diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000000000000000000000000000000000000..dca7b3804930d5b672599ee6339c08b664a760a1 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,1725 @@ +# Doxyfile 1.7.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = XIOS + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Xml I/O Server" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = French + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.cpp \ + *.hpp \ + *.conf + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# If the HTML_TIMESTAMP tag is set to YES then the generated HTML +# documentation will contain the timesstamp. + +HTML_TIMESTAMP = YES + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 224 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 63 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 152 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/Licence.txt b/Licence.txt new file mode 100644 index 0000000000000000000000000000000000000000..36b9a110bad136a99c5642da37d7fddf18136bb8 --- /dev/null +++ b/Licence.txt @@ -0,0 +1,1428 @@ + + + ------------------ XIOS Licence --------------- + + + +XIOS is under CeCILL_V2 licence. See "Licence_CeCILL_V2-en.txt" file for an english +version of the licence and "Licence_CeCILL_V2-fr.txt" for a french version. + +All files in the src directory are submitted to the Cecill Licence. + + + +XIOS use internally some other packages that are submitted to other free licence : + + +- boost C++ library : http://www.boost.org + ---> Boost software licence : http://www.boost.org/users/license.html + + +- blitz++ : http://blitz.sourceforge.net/ + ---> GNU LESSER GENERAL PUBLIC LICENSE V3 : https://www.gnu.org/licenses/lgpl.html + + +- RapidXML : http://rapidxml.sourceforge.net/ + ---> Boost software licence : http://www.boost.org/users/license.html + + + - FCM : http://www.metoffice.gov.uk/research/collaboration/fcm + ---> GNU GENERAL PUBLIC LICENSE V3 : https://www.gnu.org/licenses/lgpl.html + + + +--------------------------------------------------------------------------- + + Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +---------------------------------------------------------------------------- + + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + 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 that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU 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 as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + + + + + +------------------------------------------------------------------------ + + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + + +----------------------------------------------------------------------------- + + + + +CeCILL FREE SOFTWARE LICENSE AGREEMENT + + + Notice + +This Agreement is a Free Software license agreement that is the result +of discussions between its authors in order to ensure compliance with +the two main principles guiding its drafting: + + * firstly, compliance with the principles governing the distribution + of Free Software: access to source code, broad rights granted to + users, + * secondly, the election of a governing law, French law, with which + it is conformant, both as regards the law of torts and + intellectual property law, and the protection that it offers to + both authors and holders of the economic rights over software. + +The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) +license are: + +Commissariat l'Energie Atomique - CEA, a public scientific, technical +and industrial research establishment, having its principal place of +business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. + +Centre National de la Recherche Scientifique - CNRS, a public scientific +and technological establishment, having its principal place of business +at 3 rue Michel-Ange, 75794 Paris cedex 16, France. + +Institut National de Recherche en Informatique et en Automatique - +INRIA, a public scientific and technological establishment, having its +principal place of business at Domaine de Voluceau, Rocquencourt, BP +105, 78153 Le Chesnay cedex, France. + + + Preamble + +The purpose of this Free Software license agreement is to grant users +the right to modify and redistribute the software governed by this +license within the framework of an open source distribution model. + +The exercising of these rights is conditional upon certain obligations +for users so as to preserve this status for all subsequent redistributions. + +In consideration of access to the source code and the rights to copy, +modify and redistribute granted by the license, users are provided only +with a limited warranty and the software's author, the holder of the +economic rights, and the successive licensors only have limited liability. + +In this respect, the risks associated with loading, using, modifying +and/or developing or reproducing the software by the user are brought to +the user's attention, given its Free Software status, which may make it +complicated to use, with the result that its use is reserved for +developers and experienced professionals having in-depth computer +knowledge. Users are therefore encouraged to load and test the +suitability of the software as regards their requirements in conditions +enabling the security of their systems and/or data to be ensured and, +more generally, to use and operate it in the same conditions of +security. This Agreement may be freely reproduced and published, +provided it is not altered, and that no provisions are either added or +removed herefrom. + +This Agreement may apply to any or all software for which the holder of +the economic rights decides to submit the use thereof to its provisions. + + + Article 1 - DEFINITIONS + +For the purpose of this Agreement, when the following expressions +commence with a capital letter, they shall have the following meaning: + +Agreement: means this license agreement, and its possible subsequent +versions and annexes. + +Software: means the software in its Object Code and/or Source Code form +and, where applicable, its documentation, "as is" when the Licensee +accepts the Agreement. + +Initial Software: means the Software in its Source Code and possibly its +Object Code form and, where applicable, its documentation, "as is" when +it is first distributed under the terms and conditions of the Agreement. + +Modified Software: means the Software modified by at least one +Contribution. + +Source Code: means all the Software's instructions and program lines to +which access is required so as to modify the Software. + +Object Code: means the binary files originating from the compilation of +the Source Code. + +Holder: means the holder(s) of the economic rights over the Initial +Software. + +Licensee: means the Software user(s) having accepted the Agreement. + +Contributor: means a Licensee having made at least one Contribution. + +Licensor: means the Holder, or any other individual or legal entity, who +distributes the Software under the Agreement. + +Contribution: means any or all modifications, corrections, translations, +adaptations and/or new functions integrated into the Software by any or +all Contributors, as well as any or all Internal Modules. + +Module: means a set of sources files including their documentation that +enables supplementary functions or services in addition to those offered +by the Software. + +External Module: means any or all Modules, not derived from the +Software, so that this Module and the Software run in separate address +spaces, with one calling the other when they are run. + +Internal Module: means any or all Module, connected to the Software so +that they both execute in the same address space. + +GNU GPL: means the GNU General Public License version 2 or any +subsequent version, as published by the Free Software Foundation Inc. + +Parties: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + + + Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the +Licensee of a non-exclusive, transferable and worldwide license for the +Software as set forth in Article 5 hereinafter for the whole term of the +protection granted by the rights over said Software. + + + Article 3 - ACCEPTANCE + +3.1 The Licensee shall be deemed as having accepted the terms and +conditions of this Agreement upon the occurrence of the first of the +following events: + + * (i) loading the Software by any or all means, notably, by + downloading from a remote server, or by loading from a physical + medium; + * (ii) the first time the Licensee exercises any of the rights + granted hereunder. + +3.2 One copy of the Agreement, containing a notice relating to the +characteristics of the Software, to the limited warranty, and to the +fact that its use is restricted to experienced users has been provided +to the Licensee prior to its acceptance as set forth in Article 3.1 +hereinabove, and the Licensee hereby acknowledges that it has read and +understood it. + + + Article 4 - EFFECTIVE DATE AND TERM + + + 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by +the Licensee as set forth in Article 3.1. + + + 4.2 TERM + +The Agreement shall remain in force for the entire legal term of +protection of the economic rights over the Software. + + + Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following +rights over the Software for any or all use, and for the term of the +Agreement, on the basis of the terms and conditions set forth hereinafter. + +Besides, if the Licensor owns or comes to own one or more patents +protecting all or part of the functions of the Software or of its +components, the Licensor undertakes not to enforce the rights granted by +these patents against successive Licensees using, exploiting or +modifying the Software. If these patents are transferred, the Licensor +undertakes to have the transferees subscribe to the obligations set +forth in this paragraph. + + + 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation +as to its fields of application, with it being hereinafter specified +that this comprises: + + 1. permanent or temporary reproduction of all or part of the Software + by any or all means and in any or all form. + + 2. loading, displaying, running, or storing the Software on any or + all medium. + + 3. entitlement to observe, study or test its operation so as to + determine the ideas and principles behind any or all constituent + elements of said Software. This shall apply when the Licensee + carries out any or all loading, displaying, running, transmission + or storage operation as regards the Software, that it is entitled + to carry out hereunder. + + + 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS + +The right to make Contributions includes the right to translate, adapt, +arrange, or make any or all modifications to the Software, and the right +to reproduce the resulting software. + +The Licensee is authorized to make any or all Contributions to the +Software provided that it includes an explicit notice that it is the +author of said Contribution and indicates the date of the creation thereof. + + + 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, +transmit and communicate the Software to the general public on any or +all medium, and by any or all means, and the right to market, either in +consideration of a fee, or free of charge, one or more copies of the +Software by any means. + +The Licensee is further authorized to distribute copies of the modified +or unmodified Software to third parties according to the terms and +conditions set forth hereinafter. + + + 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is authorized to distribute true copies of the Software in +Source Code or Object Code form, provided that said distribution +complies with all the provisions of the Agreement and is accompanied by: + + 1. a copy of the Agreement, + + 2. a notice relating to the limitation of both the Licensor's + warranty and liability as set forth in Articles 8 and 9, + +and that, in the event that only the Object Code of the Software is +redistributed, the Licensee allows future Licensees unhindered access to +the full Source Code of the Software by indicating how to access it, it +being understood that the additional cost of acquiring the Source Code +shall not exceed the cost of transferring the data. + + + 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee makes a Contribution to the Software, the terms and +conditions for the distribution of the resulting Modified Software +become subject to all the provisions of this Agreement. + +The Licensee is authorized to distribute the Modified Software, in +source code or object code form, provided that said distribution +complies with all the provisions of the Agreement and is accompanied by: + + 1. a copy of the Agreement, + + 2. a notice relating to the limitation of both the Licensor's + warranty and liability as set forth in Articles 8 and 9, + +and that, in the event that only the object code of the Modified +Software is redistributed, the Licensee allows future Licensees +unhindered access to the full source code of the Modified Software by +indicating how to access it, it being understood that the additional +cost of acquiring the source code shall not exceed the cost of +transferring the data. + + + 5.3.3 DISTRIBUTION OF EXTERNAL MODULES + +When the Licensee has developed an External Module, the terms and +conditions of this Agreement do not apply to said External Module, that +may be distributed under a separate license agreement. + + + 5.3.4 COMPATIBILITY WITH THE GNU GPL + +The Licensee can include a code that is subject to the provisions of one +of the versions of the GNU GPL in the Modified or unmodified Software, +and distribute that entire code under the terms of the same version of +the GNU GPL. + +The Licensee can include the Modified or unmodified Software in a code +that is subject to the provisions of one of the versions of the GNU GPL, +and distribute that entire code under the terms of the same version of +the GNU GPL. + + + Article 6 - INTELLECTUAL PROPERTY + + + 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the economic rights over the Initial Software. Any or +all use of the Initial Software is subject to compliance with the terms +and conditions under which the Holder has elected to distribute its work +and no one shall be entitled to modify the terms and conditions for the +distribution of said Initial Software. + +The Holder undertakes that the Initial Software will remain ruled at +least by this Agreement, for the duration set forth in Article 4.2. + + + 6.2 OVER THE CONTRIBUTIONS + +The Licensee who develops a Contribution is the owner of the +intellectual property rights over this Contribution as defined by +applicable law. + + + 6.3 OVER THE EXTERNAL MODULES + +The Licensee who develops an External Module is the owner of the +intellectual property rights over this External Module as defined by +applicable law and is free to choose the type of agreement that shall +govern its distribution. + + + 6.4 JOINT PROVISIONS + +The Licensee expressly undertakes: + + 1. not to remove, or modify, in any manner, the intellectual property + notices attached to the Software; + + 2. to reproduce said notices, in an identical manner, in the copies + of the Software modified or not. + +The Licensee undertakes not to directly or indirectly infringe the +intellectual property rights of the Holder and/or Contributors on the +Software and to take, where applicable, vis--vis its staff, any and all +measures required to ensure respect of said intellectual property rights +of the Holder and/or Contributors. + + + Article 7 - RELATED SERVICES + +7.1 Under no circumstances shall the Agreement oblige the Licensor to +provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The +terms and conditions of such technical assistance, and/or such +maintenance, shall be set forth in a separate instrument. Only the +Licensor offering said maintenance and/or technical assistance services +shall incur liability therefor. + +7.2 Similarly, any Licensor is entitled to offer to its licensees, under +its sole responsibility, a warranty, that shall only be binding upon +itself, for the redistribution of the Software and/or the Modified +Software, under terms and conditions that it is free to decide. Said +warranty, and the financial terms and conditions of its application, +shall be subject of a separate instrument executed between the Licensor +and the Licensee. + + + Article 8 - LIABILITY + +8.1 Subject to the provisions of Article 8.2, the Licensee shall be +entitled to claim compensation for any direct loss it may have suffered +from the Software as a result of a fault on the part of the relevant +Licensor, subject to providing evidence thereof. + +8.2 The Licensor's liability is limited to the commitments made under +this Agreement and shall not be incurred as a result of in particular: +(i) loss due the Licensee's total or partial failure to fulfill its +obligations, (ii) direct or consequential loss that is suffered by the +Licensee due to the use or performance of the Software, and (iii) more +generally, any consequential loss. In particular the Parties expressly +agree that any or all pecuniary or business loss (i.e. loss of data, +loss of profits, operating loss, loss of customers or orders, +opportunity cost, any disturbance to business activities) or any or all +legal proceedings instituted against the Licensee by a third party, +shall constitute consequential loss and shall not provide entitlement to +any or all compensation from the Licensor. + + + Article 9 - WARRANTY + +9.1 The Licensee acknowledges that the scientific and technical +state-of-the-art when the Software was distributed did not enable all +possible uses to be tested and verified, nor for the presence of +possible defects to be detected. In this respect, the Licensee's +attention has been drawn to the risks associated with loading, using, +modifying and/or developing and reproducing the Software which are +reserved for experienced users. + +The Licensee shall be responsible for verifying, by any or all means, +the suitability of the product for its requirements, its good working +order, and for ensuring that it shall not cause damage to either persons +or properties. + +9.2 The Licensor hereby represents, in good faith, that it is entitled +to grant all the rights over the Software (including in particular the +rights set forth in Article 5). + +9.3 The Licensee acknowledges that the Software is supplied "as is" by +the Licensor without any other express or tacit warranty, other than +that provided for in Article 9.2 and, in particular, without any warranty +as to its commercial value, its secured, safe, innovative or relevant +nature. + +Specifically, the Licensor does not warrant that the Software is free +from any error, that it will operate without interruption, that it will +be compatible with the Licensee's own equipment and software +configuration, nor that it will meet the Licensee's requirements. + +9.4 The Licensor does not either expressly or tacitly warrant that the +Software does not infringe any third party intellectual property right +relating to a patent, software or any other property right. Therefore, +the Licensor disclaims any and all liability towards the Licensee +arising out of any or all proceedings for infringement that may be +instituted in respect of the use, modification and redistribution of the +Software. Nevertheless, should such proceedings be instituted against +the Licensee, the Licensor shall provide it with technical and legal +assistance for its defense. Such technical and legal assistance shall be +decided on a case-by-case basis between the relevant Licensor and the +Licensee pursuant to a memorandum of understanding. The Licensor +disclaims any and all liability as regards the Licensee's use of the +name of the Software. No warranty is given as regards the existence of +prior rights over the name of the Software or as regards the existence +of a trademark. + + + Article 10 - TERMINATION + +10.1 In the event of a breach by the Licensee of its obligations +hereunder, the Licensor may automatically terminate this Agreement +thirty (30) days after notice has been sent to the Licensee and has +remained ineffective. + +10.2 A Licensee whose Agreement is terminated shall no longer be +authorized to use, modify or distribute the Software. However, any +licenses that it may have granted prior to termination of the Agreement +shall remain valid subject to their having been granted in compliance +with the terms and conditions hereof. + + + Article 11 - MISCELLANEOUS + + + 11.1 EXCUSABLE EVENTS + +Neither Party shall be liable for any or all delay, or failure to +perform the Agreement, that may be attributable to an event of force +majeure, an act of God or an outside cause, such as defective +functioning or interruptions of the electricity or telecommunications +networks, network paralysis following a virus attack, intervention by +government authorities, natural disasters, water damage, earthquakes, +fire, explosions, strikes and labor unrest, war, etc. + +11.2 Any failure by either Party, on one or more occasions, to invoke +one or more of the provisions hereof, shall under no circumstances be +interpreted as being a waiver by the interested Party of its right to +invoke said provision(s) subsequently. + +11.3 The Agreement cancels and replaces any or all previous agreements, +whether written or oral, between the Parties and having the same +purpose, and constitutes the entirety of the agreement between said +Parties concerning said purpose. No supplement or modification to the +terms and conditions hereof shall be effective as between the Parties +unless it is made in writing and signed by their duly authorized +representatives. + +11.4 In the event that one or more of the provisions hereof were to +conflict with a current or future applicable act or legislative text, +said act or legislative text shall prevail, and the Parties shall make +the necessary amendments so as to comply with said act or legislative +text. All other provisions shall remain effective. Similarly, invalidity +of a provision of the Agreement, for any reason whatsoever, shall not +cause the Agreement as a whole to be invalid. + + + 11.5 LANGUAGE + +The Agreement is drafted in both French and English and both versions +are deemed authentic. + + + Article 12 - NEW VERSIONS OF THE AGREEMENT + +12.1 Any person is authorized to duplicate and distribute copies of this +Agreement. + +12.2 So as to ensure coherence, the wording of this Agreement is +protected and may only be modified by the authors of the License, who +reserve the right to periodically publish updates or new versions of the +Agreement, each with a separate number. These subsequent versions may +address new issues encountered by Free Software. + +12.3 Any Software distributed under a given version of the Agreement may +only be subsequently distributed under the same version of the Agreement +or a subsequent version, subject to the provisions of Article 5.3.4. + + + Article 13 - GOVERNING LAW AND JURISDICTION + +13.1 The Agreement is governed by French law. The Parties agree to +endeavor to seek an amicable solution to any disagreements or disputes +that may arise during the performance of the Agreement. + +13.2 Failing an amicable solution within two (2) months as from their +occurrence, and unless emergency proceedings are necessary, the +disagreements or disputes shall be referred to the Paris Courts having +jurisdiction, by the more diligent Party. + + +Version 2.0 dated 2006-09-05. + + + + + diff --git a/Licence_CeCILL_V2-en.txt b/Licence_CeCILL_V2-en.txt new file mode 100644 index 0000000000000000000000000000000000000000..fcc8df26b07f09b1d12fc9c8e8b161423ae45bdf --- /dev/null +++ b/Licence_CeCILL_V2-en.txt @@ -0,0 +1,506 @@ + +CeCILL FREE SOFTWARE LICENSE AGREEMENT + + + Notice + +This Agreement is a Free Software license agreement that is the result +of discussions between its authors in order to ensure compliance with +the two main principles guiding its drafting: + + * firstly, compliance with the principles governing the distribution + of Free Software: access to source code, broad rights granted to + users, + * secondly, the election of a governing law, French law, with which + it is conformant, both as regards the law of torts and + intellectual property law, and the protection that it offers to + both authors and holders of the economic rights over software. + +The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) +license are: + +Commissariat l'Energie Atomique - CEA, a public scientific, technical +and industrial research establishment, having its principal place of +business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. + +Centre National de la Recherche Scientifique - CNRS, a public scientific +and technological establishment, having its principal place of business +at 3 rue Michel-Ange, 75794 Paris cedex 16, France. + +Institut National de Recherche en Informatique et en Automatique - +INRIA, a public scientific and technological establishment, having its +principal place of business at Domaine de Voluceau, Rocquencourt, BP +105, 78153 Le Chesnay cedex, France. + + + Preamble + +The purpose of this Free Software license agreement is to grant users +the right to modify and redistribute the software governed by this +license within the framework of an open source distribution model. + +The exercising of these rights is conditional upon certain obligations +for users so as to preserve this status for all subsequent redistributions. + +In consideration of access to the source code and the rights to copy, +modify and redistribute granted by the license, users are provided only +with a limited warranty and the software's author, the holder of the +economic rights, and the successive licensors only have limited liability. + +In this respect, the risks associated with loading, using, modifying +and/or developing or reproducing the software by the user are brought to +the user's attention, given its Free Software status, which may make it +complicated to use, with the result that its use is reserved for +developers and experienced professionals having in-depth computer +knowledge. Users are therefore encouraged to load and test the +suitability of the software as regards their requirements in conditions +enabling the security of their systems and/or data to be ensured and, +more generally, to use and operate it in the same conditions of +security. This Agreement may be freely reproduced and published, +provided it is not altered, and that no provisions are either added or +removed herefrom. + +This Agreement may apply to any or all software for which the holder of +the economic rights decides to submit the use thereof to its provisions. + + + Article 1 - DEFINITIONS + +For the purpose of this Agreement, when the following expressions +commence with a capital letter, they shall have the following meaning: + +Agreement: means this license agreement, and its possible subsequent +versions and annexes. + +Software: means the software in its Object Code and/or Source Code form +and, where applicable, its documentation, "as is" when the Licensee +accepts the Agreement. + +Initial Software: means the Software in its Source Code and possibly its +Object Code form and, where applicable, its documentation, "as is" when +it is first distributed under the terms and conditions of the Agreement. + +Modified Software: means the Software modified by at least one +Contribution. + +Source Code: means all the Software's instructions and program lines to +which access is required so as to modify the Software. + +Object Code: means the binary files originating from the compilation of +the Source Code. + +Holder: means the holder(s) of the economic rights over the Initial +Software. + +Licensee: means the Software user(s) having accepted the Agreement. + +Contributor: means a Licensee having made at least one Contribution. + +Licensor: means the Holder, or any other individual or legal entity, who +distributes the Software under the Agreement. + +Contribution: means any or all modifications, corrections, translations, +adaptations and/or new functions integrated into the Software by any or +all Contributors, as well as any or all Internal Modules. + +Module: means a set of sources files including their documentation that +enables supplementary functions or services in addition to those offered +by the Software. + +External Module: means any or all Modules, not derived from the +Software, so that this Module and the Software run in separate address +spaces, with one calling the other when they are run. + +Internal Module: means any or all Module, connected to the Software so +that they both execute in the same address space. + +GNU GPL: means the GNU General Public License version 2 or any +subsequent version, as published by the Free Software Foundation Inc. + +Parties: mean both the Licensee and the Licensor. + +These expressions may be used both in singular and plural form. + + + Article 2 - PURPOSE + +The purpose of the Agreement is the grant by the Licensor to the +Licensee of a non-exclusive, transferable and worldwide license for the +Software as set forth in Article 5 hereinafter for the whole term of the +protection granted by the rights over said Software. + + + Article 3 - ACCEPTANCE + +3.1 The Licensee shall be deemed as having accepted the terms and +conditions of this Agreement upon the occurrence of the first of the +following events: + + * (i) loading the Software by any or all means, notably, by + downloading from a remote server, or by loading from a physical + medium; + * (ii) the first time the Licensee exercises any of the rights + granted hereunder. + +3.2 One copy of the Agreement, containing a notice relating to the +characteristics of the Software, to the limited warranty, and to the +fact that its use is restricted to experienced users has been provided +to the Licensee prior to its acceptance as set forth in Article 3.1 +hereinabove, and the Licensee hereby acknowledges that it has read and +understood it. + + + Article 4 - EFFECTIVE DATE AND TERM + + + 4.1 EFFECTIVE DATE + +The Agreement shall become effective on the date when it is accepted by +the Licensee as set forth in Article 3.1. + + + 4.2 TERM + +The Agreement shall remain in force for the entire legal term of +protection of the economic rights over the Software. + + + Article 5 - SCOPE OF RIGHTS GRANTED + +The Licensor hereby grants to the Licensee, who accepts, the following +rights over the Software for any or all use, and for the term of the +Agreement, on the basis of the terms and conditions set forth hereinafter. + +Besides, if the Licensor owns or comes to own one or more patents +protecting all or part of the functions of the Software or of its +components, the Licensor undertakes not to enforce the rights granted by +these patents against successive Licensees using, exploiting or +modifying the Software. If these patents are transferred, the Licensor +undertakes to have the transferees subscribe to the obligations set +forth in this paragraph. + + + 5.1 RIGHT OF USE + +The Licensee is authorized to use the Software, without any limitation +as to its fields of application, with it being hereinafter specified +that this comprises: + + 1. permanent or temporary reproduction of all or part of the Software + by any or all means and in any or all form. + + 2. loading, displaying, running, or storing the Software on any or + all medium. + + 3. entitlement to observe, study or test its operation so as to + determine the ideas and principles behind any or all constituent + elements of said Software. This shall apply when the Licensee + carries out any or all loading, displaying, running, transmission + or storage operation as regards the Software, that it is entitled + to carry out hereunder. + + + 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS + +The right to make Contributions includes the right to translate, adapt, +arrange, or make any or all modifications to the Software, and the right +to reproduce the resulting software. + +The Licensee is authorized to make any or all Contributions to the +Software provided that it includes an explicit notice that it is the +author of said Contribution and indicates the date of the creation thereof. + + + 5.3 RIGHT OF DISTRIBUTION + +In particular, the right of distribution includes the right to publish, +transmit and communicate the Software to the general public on any or +all medium, and by any or all means, and the right to market, either in +consideration of a fee, or free of charge, one or more copies of the +Software by any means. + +The Licensee is further authorized to distribute copies of the modified +or unmodified Software to third parties according to the terms and +conditions set forth hereinafter. + + + 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION + +The Licensee is authorized to distribute true copies of the Software in +Source Code or Object Code form, provided that said distribution +complies with all the provisions of the Agreement and is accompanied by: + + 1. a copy of the Agreement, + + 2. a notice relating to the limitation of both the Licensor's + warranty and liability as set forth in Articles 8 and 9, + +and that, in the event that only the Object Code of the Software is +redistributed, the Licensee allows future Licensees unhindered access to +the full Source Code of the Software by indicating how to access it, it +being understood that the additional cost of acquiring the Source Code +shall not exceed the cost of transferring the data. + + + 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE + +When the Licensee makes a Contribution to the Software, the terms and +conditions for the distribution of the resulting Modified Software +become subject to all the provisions of this Agreement. + +The Licensee is authorized to distribute the Modified Software, in +source code or object code form, provided that said distribution +complies with all the provisions of the Agreement and is accompanied by: + + 1. a copy of the Agreement, + + 2. a notice relating to the limitation of both the Licensor's + warranty and liability as set forth in Articles 8 and 9, + +and that, in the event that only the object code of the Modified +Software is redistributed, the Licensee allows future Licensees +unhindered access to the full source code of the Modified Software by +indicating how to access it, it being understood that the additional +cost of acquiring the source code shall not exceed the cost of +transferring the data. + + + 5.3.3 DISTRIBUTION OF EXTERNAL MODULES + +When the Licensee has developed an External Module, the terms and +conditions of this Agreement do not apply to said External Module, that +may be distributed under a separate license agreement. + + + 5.3.4 COMPATIBILITY WITH THE GNU GPL + +The Licensee can include a code that is subject to the provisions of one +of the versions of the GNU GPL in the Modified or unmodified Software, +and distribute that entire code under the terms of the same version of +the GNU GPL. + +The Licensee can include the Modified or unmodified Software in a code +that is subject to the provisions of one of the versions of the GNU GPL, +and distribute that entire code under the terms of the same version of +the GNU GPL. + + + Article 6 - INTELLECTUAL PROPERTY + + + 6.1 OVER THE INITIAL SOFTWARE + +The Holder owns the economic rights over the Initial Software. Any or +all use of the Initial Software is subject to compliance with the terms +and conditions under which the Holder has elected to distribute its work +and no one shall be entitled to modify the terms and conditions for the +distribution of said Initial Software. + +The Holder undertakes that the Initial Software will remain ruled at +least by this Agreement, for the duration set forth in Article 4.2. + + + 6.2 OVER THE CONTRIBUTIONS + +The Licensee who develops a Contribution is the owner of the +intellectual property rights over this Contribution as defined by +applicable law. + + + 6.3 OVER THE EXTERNAL MODULES + +The Licensee who develops an External Module is the owner of the +intellectual property rights over this External Module as defined by +applicable law and is free to choose the type of agreement that shall +govern its distribution. + + + 6.4 JOINT PROVISIONS + +The Licensee expressly undertakes: + + 1. not to remove, or modify, in any manner, the intellectual property + notices attached to the Software; + + 2. to reproduce said notices, in an identical manner, in the copies + of the Software modified or not. + +The Licensee undertakes not to directly or indirectly infringe the +intellectual property rights of the Holder and/or Contributors on the +Software and to take, where applicable, vis--vis its staff, any and all +measures required to ensure respect of said intellectual property rights +of the Holder and/or Contributors. + + + Article 7 - RELATED SERVICES + +7.1 Under no circumstances shall the Agreement oblige the Licensor to +provide technical assistance or maintenance services for the Software. + +However, the Licensor is entitled to offer this type of services. The +terms and conditions of such technical assistance, and/or such +maintenance, shall be set forth in a separate instrument. Only the +Licensor offering said maintenance and/or technical assistance services +shall incur liability therefor. + +7.2 Similarly, any Licensor is entitled to offer to its licensees, under +its sole responsibility, a warranty, that shall only be binding upon +itself, for the redistribution of the Software and/or the Modified +Software, under terms and conditions that it is free to decide. Said +warranty, and the financial terms and conditions of its application, +shall be subject of a separate instrument executed between the Licensor +and the Licensee. + + + Article 8 - LIABILITY + +8.1 Subject to the provisions of Article 8.2, the Licensee shall be +entitled to claim compensation for any direct loss it may have suffered +from the Software as a result of a fault on the part of the relevant +Licensor, subject to providing evidence thereof. + +8.2 The Licensor's liability is limited to the commitments made under +this Agreement and shall not be incurred as a result of in particular: +(i) loss due the Licensee's total or partial failure to fulfill its +obligations, (ii) direct or consequential loss that is suffered by the +Licensee due to the use or performance of the Software, and (iii) more +generally, any consequential loss. In particular the Parties expressly +agree that any or all pecuniary or business loss (i.e. loss of data, +loss of profits, operating loss, loss of customers or orders, +opportunity cost, any disturbance to business activities) or any or all +legal proceedings instituted against the Licensee by a third party, +shall constitute consequential loss and shall not provide entitlement to +any or all compensation from the Licensor. + + + Article 9 - WARRANTY + +9.1 The Licensee acknowledges that the scientific and technical +state-of-the-art when the Software was distributed did not enable all +possible uses to be tested and verified, nor for the presence of +possible defects to be detected. In this respect, the Licensee's +attention has been drawn to the risks associated with loading, using, +modifying and/or developing and reproducing the Software which are +reserved for experienced users. + +The Licensee shall be responsible for verifying, by any or all means, +the suitability of the product for its requirements, its good working +order, and for ensuring that it shall not cause damage to either persons +or properties. + +9.2 The Licensor hereby represents, in good faith, that it is entitled +to grant all the rights over the Software (including in particular the +rights set forth in Article 5). + +9.3 The Licensee acknowledges that the Software is supplied "as is" by +the Licensor without any other express or tacit warranty, other than +that provided for in Article 9.2 and, in particular, without any warranty +as to its commercial value, its secured, safe, innovative or relevant +nature. + +Specifically, the Licensor does not warrant that the Software is free +from any error, that it will operate without interruption, that it will +be compatible with the Licensee's own equipment and software +configuration, nor that it will meet the Licensee's requirements. + +9.4 The Licensor does not either expressly or tacitly warrant that the +Software does not infringe any third party intellectual property right +relating to a patent, software or any other property right. Therefore, +the Licensor disclaims any and all liability towards the Licensee +arising out of any or all proceedings for infringement that may be +instituted in respect of the use, modification and redistribution of the +Software. Nevertheless, should such proceedings be instituted against +the Licensee, the Licensor shall provide it with technical and legal +assistance for its defense. Such technical and legal assistance shall be +decided on a case-by-case basis between the relevant Licensor and the +Licensee pursuant to a memorandum of understanding. The Licensor +disclaims any and all liability as regards the Licensee's use of the +name of the Software. No warranty is given as regards the existence of +prior rights over the name of the Software or as regards the existence +of a trademark. + + + Article 10 - TERMINATION + +10.1 In the event of a breach by the Licensee of its obligations +hereunder, the Licensor may automatically terminate this Agreement +thirty (30) days after notice has been sent to the Licensee and has +remained ineffective. + +10.2 A Licensee whose Agreement is terminated shall no longer be +authorized to use, modify or distribute the Software. However, any +licenses that it may have granted prior to termination of the Agreement +shall remain valid subject to their having been granted in compliance +with the terms and conditions hereof. + + + Article 11 - MISCELLANEOUS + + + 11.1 EXCUSABLE EVENTS + +Neither Party shall be liable for any or all delay, or failure to +perform the Agreement, that may be attributable to an event of force +majeure, an act of God or an outside cause, such as defective +functioning or interruptions of the electricity or telecommunications +networks, network paralysis following a virus attack, intervention by +government authorities, natural disasters, water damage, earthquakes, +fire, explosions, strikes and labor unrest, war, etc. + +11.2 Any failure by either Party, on one or more occasions, to invoke +one or more of the provisions hereof, shall under no circumstances be +interpreted as being a waiver by the interested Party of its right to +invoke said provision(s) subsequently. + +11.3 The Agreement cancels and replaces any or all previous agreements, +whether written or oral, between the Parties and having the same +purpose, and constitutes the entirety of the agreement between said +Parties concerning said purpose. No supplement or modification to the +terms and conditions hereof shall be effective as between the Parties +unless it is made in writing and signed by their duly authorized +representatives. + +11.4 In the event that one or more of the provisions hereof were to +conflict with a current or future applicable act or legislative text, +said act or legislative text shall prevail, and the Parties shall make +the necessary amendments so as to comply with said act or legislative +text. All other provisions shall remain effective. Similarly, invalidity +of a provision of the Agreement, for any reason whatsoever, shall not +cause the Agreement as a whole to be invalid. + + + 11.5 LANGUAGE + +The Agreement is drafted in both French and English and both versions +are deemed authentic. + + + Article 12 - NEW VERSIONS OF THE AGREEMENT + +12.1 Any person is authorized to duplicate and distribute copies of this +Agreement. + +12.2 So as to ensure coherence, the wording of this Agreement is +protected and may only be modified by the authors of the License, who +reserve the right to periodically publish updates or new versions of the +Agreement, each with a separate number. These subsequent versions may +address new issues encountered by Free Software. + +12.3 Any Software distributed under a given version of the Agreement may +only be subsequently distributed under the same version of the Agreement +or a subsequent version, subject to the provisions of Article 5.3.4. + + + Article 13 - GOVERNING LAW AND JURISDICTION + +13.1 The Agreement is governed by French law. The Parties agree to +endeavor to seek an amicable solution to any disagreements or disputes +that may arise during the performance of the Agreement. + +13.2 Failing an amicable solution within two (2) months as from their +occurrence, and unless emergency proceedings are necessary, the +disagreements or disputes shall be referred to the Paris Courts having +jurisdiction, by the more diligent Party. + + +Version 2.0 dated 2006-09-05. diff --git a/Licence_CeCILL_V2-fr.txt b/Licence_CeCILL_V2-fr.txt new file mode 100644 index 0000000000000000000000000000000000000000..1613fca5b606496691e6b5b6520afdf1772866de --- /dev/null +++ b/Licence_CeCILL_V2-fr.txt @@ -0,0 +1,512 @@ + +CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL + + + Avertissement + +Ce contrat est une licence de logiciel libre issue d'une concertation +entre ses auteurs afin que le respect de deux grands principes prside +sa rdaction: + + * d'une part, le respect des principes de diffusion des logiciels + libres: accs au code source, droits tendus confrs aux + utilisateurs, + * d'autre part, la dsignation d'un droit applicable, le droit + franais, auquel elle est conforme, tant au regard du droit de la + responsabilit civile que du droit de la proprit intellectuelle + et de la protection qu'il offre aux auteurs et titulaires des + droits patrimoniaux sur un logiciel. + +Les auteurs de la licence CeCILL (pour Ce[a] C[nrs] I[nria] L[ogiciel] +L[ibre]) sont: + +Commissariat l'Energie Atomique - CEA, tablissement public de +recherche caractre scientifique, technique et industriel, dont le +sige est situ 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris. + +Centre National de la Recherche Scientifique - CNRS, tablissement +public caractre scientifique et technologique, dont le sige est +situ 3 rue Michel-Ange, 75794 Paris cedex 16. + +Institut National de Recherche en Informatique et en Automatique - +INRIA, tablissement public caractre scientifique et technologique, +dont le sige est situ Domaine de Voluceau, Rocquencourt, BP 105, 78153 +Le Chesnay cedex. + + + Prambule + +Ce contrat est une licence de logiciel libre dont l'objectif est de +confrer aux utilisateurs la libert de modification et de +redistribution du logiciel rgi par cette licence dans le cadre d'un +modle de diffusion en logiciel libre. + +L'exercice de ces liberts est assorti de certains devoirs la charge +des utilisateurs afin de prserver ce statut au cours des +redistributions ultrieures. + +L'accessibilit au code source et les droits de copie, de modification +et de redistribution qui en dcoulent ont pour contrepartie de n'offrir +aux utilisateurs qu'une garantie limite et de ne faire peser sur +l'auteur du logiciel, le titulaire des droits patrimoniaux et les +concdants successifs qu'une responsabilit restreinte. + +A cet gard l'attention de l'utilisateur est attire sur les risques +associs au chargement, l'utilisation, la modification et/ou au +dveloppement et la reproduction du logiciel par l'utilisateur tant +donn sa spcificit de logiciel libre, qui peut le rendre complexe +manipuler et qui le rserve donc des dveloppeurs ou des +professionnels avertis possdant des connaissances informatiques +approfondies. Les utilisateurs sont donc invits charger et tester +l'adquation du logiciel leurs besoins dans des conditions permettant +d'assurer la scurit de leurs systmes et/ou de leurs donnes et, plus +gnralement, l'utiliser et l'exploiter dans les mmes conditions de +scurit. Ce contrat peut tre reproduit et diffus librement, sous +rserve de le conserver en l'tat, sans ajout ni suppression de clauses. + +Ce contrat est susceptible de s'appliquer tout logiciel dont le +titulaire des droits patrimoniaux dcide de soumettre l'exploitation aux +dispositions qu'il contient. + + + Article 1 - DEFINITIONS + +Dans ce contrat, les termes suivants, lorsqu'ils seront crits avec une +lettre capitale, auront la signification suivante: + +Contrat: dsigne le prsent contrat de licence, ses ventuelles versions +postrieures et annexes. + +Logiciel: dsigne le logiciel sous sa forme de Code Objet et/ou de Code +Source et le cas chant sa documentation, dans leur tat au moment de +l'acceptation du Contrat par le Licenci. + +Logiciel Initial: dsigne le Logiciel sous sa forme de Code Source et +ventuellement de Code Objet et le cas chant sa documentation, dans +leur tat au moment de leur premire diffusion sous les termes du Contrat. + +Logiciel Modifi: dsigne le Logiciel modifi par au moins une +Contribution. + +Code Source: dsigne l'ensemble des instructions et des lignes de +programme du Logiciel et auquel l'accs est ncessaire en vue de +modifier le Logiciel. + +Code Objet: dsigne les fichiers binaires issus de la compilation du +Code Source. + +Titulaire: dsigne le ou les dtenteurs des droits patrimoniaux d'auteur +sur le Logiciel Initial. + +Licenci: dsigne le ou les utilisateurs du Logiciel ayant accept le +Contrat. + +Contributeur: dsigne le Licenci auteur d'au moins une Contribution. + +Concdant: dsigne le Titulaire ou toute personne physique ou morale +distribuant le Logiciel sous le Contrat. + +Contribution: dsigne l'ensemble des modifications, corrections, +traductions, adaptations et/ou nouvelles fonctionnalits intgres dans +le Logiciel par tout Contributeur, ainsi que tout Module Interne. + +Module: dsigne un ensemble de fichiers sources y compris leur +documentation qui permet de raliser des fonctionnalits ou services +supplmentaires ceux fournis par le Logiciel. + +Module Externe: dsigne tout Module, non driv du Logiciel, tel que ce +Module et le Logiciel s'excutent dans des espaces d'adressage +diffrents, l'un appelant l'autre au moment de leur excution. + +Module Interne: dsigne tout Module li au Logiciel de telle sorte +qu'ils s'excutent dans le mme espace d'adressage. + +GNU GPL: dsigne la GNU General Public License dans sa version 2 ou +toute version ultrieure, telle que publie par Free Software Foundation +Inc. + +Parties: dsigne collectivement le Licenci et le Concdant. + +Ces termes s'entendent au singulier comme au pluriel. + + + Article 2 - OBJET + +Le Contrat a pour objet la concession par le Concdant au Licenci d'une +licence non exclusive, cessible et mondiale du Logiciel telle que +dfinie ci-aprs l'article 5 pour toute la dure de protection des droits +portant sur ce Logiciel. + + + Article 3 - ACCEPTATION + +3.1 L'acceptation par le Licenci des termes du Contrat est rpute +acquise du fait du premier des faits suivants: + + * (i) le chargement du Logiciel par tout moyen notamment par + tlchargement partir d'un serveur distant ou par chargement + partir d'un support physique; + * (ii) le premier exercice par le Licenci de l'un quelconque des + droits concds par le Contrat. + +3.2 Un exemplaire du Contrat, contenant notamment un avertissement +relatif aux spcificits du Logiciel, la restriction de garantie et +la limitation un usage par des utilisateurs expriments a t mis +disposition du Licenci pralablement son acceptation telle que +dfinie l'article 3.1 ci dessus et le Licenci reconnat en avoir pris +connaissance. + + + Article 4 - ENTREE EN VIGUEUR ET DUREE + + + 4.1 ENTREE EN VIGUEUR + +Le Contrat entre en vigueur la date de son acceptation par le Licenci +telle que dfinie en 3.1. + + + 4.2 DUREE + +Le Contrat produira ses effets pendant toute la dure lgale de +protection des droits patrimoniaux portant sur le Logiciel. + + + Article 5 - ETENDUE DES DROITS CONCEDES + +Le Concdant concde au Licenci, qui accepte, les droits suivants sur +le Logiciel pour toutes destinations et pour la dure du Contrat dans +les conditions ci-aprs dtailles. + +Par ailleurs, si le Concdant dtient ou venait dtenir un ou +plusieurs brevets d'invention protgeant tout ou partie des +fonctionnalits du Logiciel ou de ses composants, il s'engage ne pas +opposer les ventuels droits confrs par ces brevets aux Licencis +successifs qui utiliseraient, exploiteraient ou modifieraient le +Logiciel. En cas de cession de ces brevets, le Concdant s'engage +faire reprendre les obligations du prsent alina aux cessionnaires. + + + 5.1 DROIT D'UTILISATION + +Le Licenci est autoris utiliser le Logiciel, sans restriction quant +aux domaines d'application, tant ci-aprs prcis que cela comporte: + + 1. la reproduction permanente ou provisoire du Logiciel en tout ou + partie par tout moyen et sous toute forme. + + 2. le chargement, l'affichage, l'excution, ou le stockage du + Logiciel sur tout support. + + 3. la possibilit d'en observer, d'en tudier, ou d'en tester le + fonctionnement afin de dterminer les ides et principes qui sont + la base de n'importe quel lment de ce Logiciel; et ceci, + lorsque le Licenci effectue toute opration de chargement, + d'affichage, d'excution, de transmission ou de stockage du + Logiciel qu'il est en droit d'effectuer en vertu du Contrat. + + + 5.2 DROIT D'APPORTER DES CONTRIBUTIONS + +Le droit d'apporter des Contributions comporte le droit de traduire, +d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel +et le droit de reproduire le logiciel en rsultant. + +Le Licenci est autoris apporter toute Contribution au Logiciel sous +rserve de mentionner, de faon explicite, son nom en tant qu'auteur de +cette Contribution et la date de cration de celle-ci. + + + 5.3 DROIT DE DISTRIBUTION + +Le droit de distribution comporte notamment le droit de diffuser, de +transmettre et de communiquer le Logiciel au public sur tout support et +par tout moyen ainsi que le droit de mettre sur le march titre +onreux ou gratuit, un ou des exemplaires du Logiciel par tout procd. + +Le Licenci est autoris distribuer des copies du Logiciel, modifi ou +non, des tiers dans les conditions ci-aprs dtailles. + + + 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION + +Le Licenci est autoris distribuer des copies conformes du Logiciel, +sous forme de Code Source ou de Code Objet, condition que cette +distribution respecte les dispositions du Contrat dans leur totalit et +soit accompagne: + + 1. d'un exemplaire du Contrat, + + 2. d'un avertissement relatif la restriction de garantie et de + responsabilit du Concdant telle que prvue aux articles 8 + et 9, + +et que, dans le cas o seul le Code Objet du Logiciel est redistribu, +le Licenci permette aux futurs Licencis d'accder facilement au Code +Source complet du Logiciel en indiquant les modalits d'accs, tant +entendu que le cot additionnel d'acquisition du Code Source ne devra +pas excder le simple cot de transfert des donnes. + + + 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE + +Lorsque le Licenci apporte une Contribution au Logiciel, les conditions +de distribution du Logiciel Modifi en rsultant sont alors soumises +l'intgralit des dispositions du Contrat. + +Le Licenci est autoris distribuer le Logiciel Modifi, sous forme de +code source ou de code objet, condition que cette distribution +respecte les dispositions du Contrat dans leur totalit et soit +accompagne: + + 1. d'un exemplaire du Contrat, + + 2. d'un avertissement relatif la restriction de garantie et de + responsabilit du Concdant telle que prvue aux articles 8 + et 9, + +et que, dans le cas o seul le code objet du Logiciel Modifi est +redistribu, le Licenci permette aux futurs Licencis d'accder +facilement au code source complet du Logiciel Modifi en indiquant les +modalits d'accs, tant entendu que le cot additionnel d'acquisition +du code source ne devra pas excder le simple cot de transfert des donnes. + + + 5.3.3 DISTRIBUTION DES MODULES EXTERNES + +Lorsque le Licenci a dvelopp un Module Externe les conditions du +Contrat ne s'appliquent pas ce Module Externe, qui peut tre distribu +sous un contrat de licence diffrent. + + + 5.3.4 COMPATIBILITE AVEC LA LICENCE GNU GPL + +Le Licenci peut inclure un code soumis aux dispositions d'une des +versions de la licence GNU GPL dans le Logiciel modifi ou non et +distribuer l'ensemble sous les conditions de la mme version de la +licence GNU GPL. + +Le Licenci peut inclure le Logiciel modifi ou non dans un code soumis +aux dispositions d'une des versions de la licence GNU GPL et distribuer +l'ensemble sous les conditions de la mme version de la licence GNU GPL. + + + Article 6 - PROPRIETE INTELLECTUELLE + + + 6.1 SUR LE LOGICIEL INITIAL + +Le Titulaire est dtenteur des droits patrimoniaux sur le Logiciel +Initial. Toute utilisation du Logiciel Initial est soumise au respect +des conditions dans lesquelles le Titulaire a choisi de diffuser son +oeuvre et nul autre n'a la facult de modifier les conditions de +diffusion de ce Logiciel Initial. + +Le Titulaire s'engage ce que le Logiciel Initial reste au moins rgi +par le Contrat et ce, pour la dure vise l'article 4.2. + + + 6.2 SUR LES CONTRIBUTIONS + +Le Licenci qui a dvelopp une Contribution est titulaire sur celle-ci +des droits de proprit intellectuelle dans les conditions dfinies par +la lgislation applicable. + + + 6.3 SUR LES MODULES EXTERNES + +Le Licenci qui a dvelopp un Module Externe est titulaire sur celui-ci +des droits de proprit intellectuelle dans les conditions dfinies par +la lgislation applicable et reste libre du choix du contrat rgissant +sa diffusion. + + + 6.4 DISPOSITIONS COMMUNES + +Le Licenci s'engage expressment: + + 1. ne pas supprimer ou modifier de quelque manire que ce soit les + mentions de proprit intellectuelle apposes sur le Logiciel; + + 2. reproduire l'identique lesdites mentions de proprit + intellectuelle sur les copies du Logiciel modifi ou non. + +Le Licenci s'engage ne pas porter atteinte, directement ou +indirectement, aux droits de proprit intellectuelle du Titulaire et/ou +des Contributeurs sur le Logiciel et prendre, le cas chant, +l'gard de son personnel toutes les mesures ncessaires pour assurer le +respect des dits droits de proprit intellectuelle du Titulaire et/ou +des Contributeurs. + + + Article 7 - SERVICES ASSOCIES + +7.1 Le Contrat n'oblige en aucun cas le Concdant la ralisation de +prestations d'assistance technique ou de maintenance du Logiciel. + +Cependant le Concdant reste libre de proposer ce type de services. Les +termes et conditions d'une telle assistance technique et/ou d'une telle +maintenance seront alors dtermins dans un acte spar. Ces actes de +maintenance et/ou assistance technique n'engageront que la seule +responsabilit du Concdant qui les propose. + +7.2 De mme, tout Concdant est libre de proposer, sous sa seule +responsabilit, ses licencis une garantie, qui n'engagera que lui, +lors de la redistribution du Logiciel et/ou du Logiciel Modifi et ce, +dans les conditions qu'il souhaite. Cette garantie et les modalits +financires de son application feront l'objet d'un acte spar entre le +Concdant et le Licenci. + + + Article 8 - RESPONSABILITE + +8.1 Sous rserve des dispositions de l'article 8.2, le Licenci a la +facult, sous rserve de prouver la faute du Concdant concern, de +solliciter la rparation du prjudice direct qu'il subirait du fait du +Logiciel et dont il apportera la preuve. + +8.2 La responsabilit du Concdant est limite aux engagements pris en +application du Contrat et ne saurait tre engage en raison notamment: +(i) des dommages dus l'inexcution, totale ou partielle, de ses +obligations par le Licenci, (ii) des dommages directs ou indirects +dcoulant de l'utilisation ou des performances du Logiciel subis par le +Licenci et (iii) plus gnralement d'un quelconque dommage indirect. En +particulier, les Parties conviennent expressment que tout prjudice +financier ou commercial (par exemple perte de donnes, perte de +bnfices, perte d'exploitation, perte de clientle ou de commandes, +manque gagner, trouble commercial quelconque) ou toute action dirige +contre le Licenci par un tiers, constitue un dommage indirect et +n'ouvre pas droit rparation par le Concdant. + + + Article 9 - GARANTIE + +9.1 Le Licenci reconnat que l'tat actuel des connaissances +scientifiques et techniques au moment de la mise en circulation du +Logiciel ne permet pas d'en tester et d'en vrifier toutes les +utilisations ni de dtecter l'existence d'ventuels dfauts. L'attention +du Licenci a t attire sur ce point sur les risques associs au +chargement, l'utilisation, la modification et/ou au dveloppement et +la reproduction du Logiciel qui sont rservs des utilisateurs avertis. + +Il relve de la responsabilit du Licenci de contrler, par tous +moyens, l'adquation du produit ses besoins, son bon fonctionnement et +de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens. + +9.2 Le Concdant dclare de bonne foi tre en droit de concder +l'ensemble des droits attachs au Logiciel (comprenant notamment les +droits viss l'article 5). + +9.3 Le Licenci reconnat que le Logiciel est fourni "en l'tat" par le +Concdant sans autre garantie, expresse ou tacite, que celle prvue +l'article 9.2 et notamment sans aucune garantie sur sa valeur commerciale, +son caractre scuris, innovant ou pertinent. + +En particulier, le Concdant ne garantit pas que le Logiciel est exempt +d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible +avec l'quipement du Licenci et sa configuration logicielle ni qu'il +remplira les besoins du Licenci. + +9.4 Le Concdant ne garantit pas, de manire expresse ou tacite, que le +Logiciel ne porte pas atteinte un quelconque droit de proprit +intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout +autre droit de proprit. Ainsi, le Concdant exclut toute garantie au +profit du Licenci contre les actions en contrefaon qui pourraient tre +diligentes au titre de l'utilisation, de la modification, et de la +redistribution du Logiciel. Nanmoins, si de telles actions sont +exerces contre le Licenci, le Concdant lui apportera son aide +technique et juridique pour sa dfense. Cette aide technique et +juridique est dtermine au cas par cas entre le Concdant concern et +le Licenci dans le cadre d'un protocole d'accord. Le Concdant dgage +toute responsabilit quant l'utilisation de la dnomination du +Logiciel par le Licenci. Aucune garantie n'est apporte quant +l'existence de droits antrieurs sur le nom du Logiciel et sur +l'existence d'une marque. + + + Article 10 - RESILIATION + +10.1 En cas de manquement par le Licenci aux obligations mises sa +charge par le Contrat, le Concdant pourra rsilier de plein droit le +Contrat trente (30) jours aprs notification adresse au Licenci et +reste sans effet. + +10.2 Le Licenci dont le Contrat est rsili n'est plus autoris +utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les +licences qu'il aura concdes antrieurement la rsiliation du Contrat +resteront valides sous rserve qu'elles aient t effectues en +conformit avec le Contrat. + + + Article 11 - DISPOSITIONS DIVERSES + + + 11.1 CAUSE EXTERIEURE + +Aucune des Parties ne sera responsable d'un retard ou d'une dfaillance +d'excution du Contrat qui serait d un cas de force majeure, un cas +fortuit ou une cause extrieure, telle que, notamment, le mauvais +fonctionnement ou les interruptions du rseau lectrique ou de +tlcommunication, la paralysie du rseau lie une attaque +informatique, l'intervention des autorits gouvernementales, les +catastrophes naturelles, les dgts des eaux, les tremblements de terre, +le feu, les explosions, les grves et les conflits sociaux, l'tat de +guerre... + +11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou +plusieurs occasions de se prvaloir d'une ou plusieurs dispositions du +Contrat, ne pourra en aucun cas impliquer renonciation par la Partie +intresse s'en prvaloir ultrieurement. + +11.3 Le Contrat annule et remplace toute convention antrieure, crite +ou orale, entre les Parties sur le mme objet et constitue l'accord +entier entre les Parties sur cet objet. Aucune addition ou modification +aux termes du Contrat n'aura d'effet l'gard des Parties moins +d'tre faite par crit et signe par leurs reprsentants dment habilits. + +11.4 Dans l'hypothse o une ou plusieurs des dispositions du Contrat +s'avrerait contraire une loi ou un texte applicable, existants ou +futurs, cette loi ou ce texte prvaudrait, et les Parties feraient les +amendements ncessaires pour se conformer cette loi ou ce texte. +Toutes les autres dispositions resteront en vigueur. De mme, la +nullit, pour quelque raison que ce soit, d'une des dispositions du +Contrat ne saurait entraner la nullit de l'ensemble du Contrat. + + + 11.5 LANGUE + +Le Contrat est rdig en langue franaise et en langue anglaise, ces +deux versions faisant galement foi. + + + Article 12 - NOUVELLES VERSIONS DU CONTRAT + +12.1 Toute personne est autorise copier et distribuer des copies de +ce Contrat. + +12.2 Afin d'en prserver la cohrence, le texte du Contrat est protg +et ne peut tre modifi que par les auteurs de la licence, lesquels se +rservent le droit de publier priodiquement des mises jour ou de +nouvelles versions du Contrat, qui possderont chacune un numro +distinct. Ces versions ultrieures seront susceptibles de prendre en +compte de nouvelles problmatiques rencontres par les logiciels libres. + +12.3 Tout Logiciel diffus sous une version donne du Contrat ne pourra +faire l'objet d'une diffusion ultrieure que sous la mme version du +Contrat ou une version postrieure, sous rserve des dispositions de +l'article 5.3.4. + + + Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE + +13.1 Le Contrat est rgi par la loi franaise. Les Parties conviennent +de tenter de rgler l'amiable les diffrends ou litiges qui +viendraient se produire par suite ou l'occasion du Contrat. + +13.2 A dfaut d'accord amiable dans un dlai de deux (2) mois compter +de leur survenance et sauf situation relevant d'une procdure d'urgence, +les diffrends ou litiges seront ports par la Partie la plus diligente +devant les Tribunaux comptents de Paris. + + +Version 2.0 du 2006-09-05. diff --git a/arch/arch-BG_FERMI.env b/arch/arch-BG_FERMI.env new file mode 100644 index 0000000000000000000000000000000000000000..8d5c78498963a7add7f3056bfe64996e8a4e9354 --- /dev/null +++ b/arch/arch-BG_FERMI.env @@ -0,0 +1,8 @@ +module purge +module load profile/advanced +module load bgq-xl/1.0 +module load netcdf/4.1.3_par--bgq-xl--1.0 +module load hdf5/1.8.9_par--bgq-xl--1.0 +module load szip/2.1--bgq-xl--1.0 +module load zlib/1.2.7--bgq-gnu--4.4.6 +module load mass diff --git a/arch/arch-BG_FERMI.fcm b/arch/arch-BG_FERMI.fcm new file mode 100644 index 0000000000000000000000000000000000000000..e055a4c58bab1a13bfd04b638e725fb2b0b77d6c --- /dev/null +++ b/arch/arch-BG_FERMI.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpixlc_r +%FCOMPILER mpixlf90_r +%LINKER mpixlf90_r + +%BASE_CFLAGS +%PROD_CFLAGS -O3 -qarch=qp -qtune=qp +%DEV_CFLAGS +%DEBUG_CFLAGS + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 -qarch=qp -qtune=qp +%DEV_FFLAGS +%DEBUG_FFLAGS + +%BASE_INC -D__NONE__ +%BASE_LD -L/opt/ibmcmp/vacpp/bg/12.1/bglib64 -libmc++ + +%CPP mpixlc -EP +%FPP cpp -P +%MAKE make diff --git a/arch/arch-BG_FERMI.path b/arch/arch-BG_FERMI.path new file mode 100644 index 0000000000000000000000000000000000000000..97f9f8370d8b3b21db83000c0456e7bacd338a27 --- /dev/null +++ b/arch/arch-BG_FERMI.path @@ -0,0 +1,19 @@ +NETCDF_INCDIR="-I $NETCDF_INC" +NETCDF_LIBDIR="-L $NETCDF_LIB" +NETCDF_LIB="-lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="-I$HDF5_INC" +HDF5_LIBDIR="-L$HDF5_LIB -L$SZIP_LIB -L$ZLIB_LIB" +HDF5_LIB="-lhdf5_hl -lhdf5 -lsz -lz" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" + +#only for MEMTRACK debuging : developper only +ADDR2LINE_LIBDIR="-L${WORKDIR}/ADDR2LINE_LIB" +ADDR2LINE_LIB="-laddr2line" diff --git a/arch/arch-BG_TURING.env b/arch/arch-BG_TURING.env new file mode 100644 index 0000000000000000000000000000000000000000..cbf37e844524229e005496ca4948b4f98d32b395 --- /dev/null +++ b/arch/arch-BG_TURING.env @@ -0,0 +1,10 @@ +module load compilerwrappers/no +module load netcdf/mpi/4.2.1 +module load hdf5/mpi/1.8.9 + +export NETCDF_INC=/bglocal/cn/pub/NetCDF/4.2.1/mpi/include +export NETCDF_LIB=/bglocal/cn/pub/NetCDF/4.2.1/mpi/lib + +export HDF5_INC=/bglocal/cn/pub/HDF5/1.8.9/par/include +export HDF5_LIB=/bglocal/cn/pub/HDF5/1.8.9/par/lib +export ZLIB=/bglocal/cn/pub/zlib/1.2.8/lib diff --git a/arch/arch-BG_TURING.fcm b/arch/arch-BG_TURING.fcm new file mode 100644 index 0000000000000000000000000000000000000000..e055a4c58bab1a13bfd04b638e725fb2b0b77d6c --- /dev/null +++ b/arch/arch-BG_TURING.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpixlc_r +%FCOMPILER mpixlf90_r +%LINKER mpixlf90_r + +%BASE_CFLAGS +%PROD_CFLAGS -O3 -qarch=qp -qtune=qp +%DEV_CFLAGS +%DEBUG_CFLAGS + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 -qarch=qp -qtune=qp +%DEV_FFLAGS +%DEBUG_FFLAGS + +%BASE_INC -D__NONE__ +%BASE_LD -L/opt/ibmcmp/vacpp/bg/12.1/bglib64 -libmc++ + +%CPP mpixlc -EP +%FPP cpp -P +%MAKE make diff --git a/arch/arch-BG_TURING.path b/arch/arch-BG_TURING.path new file mode 100644 index 0000000000000000000000000000000000000000..21535e21bbdaa9e364711c839f205267cf570f36 --- /dev/null +++ b/arch/arch-BG_TURING.path @@ -0,0 +1,19 @@ +NETCDF_INCDIR="-I $NETCDF_INC" +NETCDF_LIBDIR="-L $NETCDF_LIB" +NETCDF_LIB="-lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="-I$HDF5_INC" +HDF5_LIBDIR="-L$HDF5_LIB -L$ZLIB" +HDF5_LIB="-lhdf5_hl -lhdf5 -lz" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" + +#only for MEMTRACK debuging : developper only +ADDR2LINE_LIBDIR="-L${WORKDIR}/ADDR2LINE_LIB" +ADDR2LINE_LIB="-laddr2line" diff --git a/arch/arch-GCC_LINUX.env b/arch/arch-GCC_LINUX.env new file mode 100644 index 0000000000000000000000000000000000000000..a065dbf6bd2d0f42a8543f1e66646eb31a7b57e8 --- /dev/null +++ b/arch/arch-GCC_LINUX.env @@ -0,0 +1,6 @@ +export HDF5_INC_DIR=$HOME/hdf5/include +export HDF5_LIB_DIR=$HOME/hdf5/lib + +export NETCDF_INC_DIR=$HOME/netcdf4/include +export NETCDF_LIB_DIR=$HOME/netcdf4/lib + diff --git a/arch/arch-GCC_LINUX.fcm b/arch/arch-GCC_LINUX.fcm new file mode 100644 index 0000000000000000000000000000000000000000..0a4316d2276a3627880d06d29034cdf28c6be1e2 --- /dev/null +++ b/arch/arch-GCC_LINUX.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpicc +%FCOMPILER mpif90 +%LINKER mpif90 + +%BASE_CFLAGS -ansi -w +%PROD_CFLAGS -O3 -DBOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -O2 +%DEBUG_CFLAGS -g + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 +%DEBUG_FFLAGS -g + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-GCC_LINUX.path b/arch/arch-GCC_LINUX.path new file mode 100644 index 0000000000000000000000000000000000000000..65c11769c3e0a3cf65a95e93d68d013c8022c118 --- /dev/null +++ b/arch/arch-GCC_LINUX.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INC_DIR" +NETCDF_LIBDIR="-L $NETCDF_LIB_DIR" +NETCDF_LIB="-lnetcdff -lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="-I $HDF5_INC_DIR" +HDF5_LIBDIR="-L $HDF5_LIB_DIR" +HDF5_LIB="-lhdf5_hl -lhdf5 -lhdf5 -lz" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-GCC_MACOSX.env b/arch/arch-GCC_MACOSX.env new file mode 100644 index 0000000000000000000000000000000000000000..a5aba075bd02e14b672a5f566a0bd0d36a98a82b --- /dev/null +++ b/arch/arch-GCC_MACOSX.env @@ -0,0 +1,14 @@ +# Environment to compile XIOS on Mac OS X +# +# Tested successfully with : +# Mac OS X 10.7.4 +# Prerequisite softwares installed with MacPorts : +# gfortran : 4.6.0 +# openmpi : 1.6.3_0 variant +gcc45 +# netcdf : 4.2.1 variant : +dap+netcdf4+openmpi (includes hdf5) +# +# Olivier Marti - olivier.marti(ad)lsce.ipsl.fr +# +export NETCDF_DIR=/opt/local +export NETCDF_INC_DIR=${NETCDF_DIR}/include +export NETCDF_LIB_DIR=${NETCDF_DIR}/lib diff --git a/arch/arch-GCC_MACOSX.fcm b/arch/arch-GCC_MACOSX.fcm new file mode 100644 index 0000000000000000000000000000000000000000..8e061a69fb39740fb3cc2f91fe09435415cf4fdc --- /dev/null +++ b/arch/arch-GCC_MACOSX.fcm @@ -0,0 +1,25 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpiCC +%FCOMPILER mpif90 +%LINKER mpif90 + +%BASE_CFLAGS -w +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g +%DEBUG_CFLAGS -g -O2 + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 +%DEBUG_FFLAGS -g + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ + +%CPP /opt/local/bin/cpp-mp-4.5 +%FPP /opt/local/bin/cpp-mp-4.5 -P +%MAKE gmake + diff --git a/arch/arch-GCC_MACOSX.path b/arch/arch-GCC_MACOSX.path new file mode 100644 index 0000000000000000000000000000000000000000..c873de8fabdaaa8c5bb300bfeadb0b751ba612b3 --- /dev/null +++ b/arch/arch-GCC_MACOSX.path @@ -0,0 +1,11 @@ +NETCDF_INCDIR="-I${NETCDF_INC_DIR}" +NETCDF_LIBDIR="-L${NETCDF_LIB_DIR}" +NETCDF_LIB="-lnetcdff -lnetcdf" + +HDF5_INCDIR="" +HDF5_LIBDIR="" +HDF5_LIB="" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-PW6_VARGAS.env b/arch/arch-PW6_VARGAS.env new file mode 100644 index 0000000000000000000000000000000000000000..513f1dbf186a7dc614b3b5a267783fb4d1a75a2b --- /dev/null +++ b/arch/arch-PW6_VARGAS.env @@ -0,0 +1,7 @@ +module unload netcdf +module unload hdf5 +module unload phdf5 +module load phdf5/1.8.7 +module load netcdf/4.1.3-par +module unload c++ +module load c++/12.1.0.0 diff --git a/arch/arch-PW6_VARGAS.fcm b/arch/arch-PW6_VARGAS.fcm new file mode 100644 index 0000000000000000000000000000000000000000..71c17b519ad9d4f12deb9d4a303e6ddc5faa116d --- /dev/null +++ b/arch/arch-PW6_VARGAS.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpCC_r +%FCOMPILER mpxlf2003_r +%LINKER mpCC_r + +%BASE_CFLAGS -qmkshrobj -qrtti +%PROD_CFLAGS -O3 -DBOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g +%DEBUG_CFLAGS -g -O0 -qfullpath + +%BASE_FFLAGS -qmkshrobj +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g +%DEBUG_FFLAGS -g -O0 -qfullpath + +%BASE_INC -D__NONE__ +%BASE_LD -lxlf90 + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-PW6_VARGAS.path b/arch/arch-PW6_VARGAS.path new file mode 100644 index 0000000000000000000000000000000000000000..45676423cf3654da8c92604e827114fc44e6331f --- /dev/null +++ b/arch/arch-PW6_VARGAS.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="" +NETCDF_LIBDIR="" +NETCDF_LIB="" + +HDF5_INCDIR="" +HDF5_LIBDIR="" +HDF5_LIB="" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-X64_ADA.env b/arch/arch-X64_ADA.env new file mode 100644 index 0000000000000000000000000000000000000000..e2a31cf7ebafd653f773d4cee33f6630b1da00bf --- /dev/null +++ b/arch/arch-X64_ADA.env @@ -0,0 +1,4 @@ +module unload netcdf +module unload hdf5 +#module load netcdf/mpi/4.1.3 +#module load hdf5/mpi/1.8.9 diff --git a/arch/arch-X64_ADA.fcm b/arch/arch-X64_ADA.fcm new file mode 100644 index 0000000000000000000000000000000000000000..5eacae8c4abf94a6954ba161b7b4e97bcd0cb73b --- /dev/null +++ b/arch/arch-X64_ADA.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpiicc +%FCOMPILER mpiifort +%LINKER mpiifort -nofor-main + +%BASE_CFLAGS -diag-disable 1125 -diag-disable 279 +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -traceback +%DEBUG_CFLAGS -DBZ_DEBUG -g -traceback -fno-inline + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 -traceback +%DEBUG_FFLAGS -g -traceback + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ -Wl,-rpath=/smplocal/pub/NetCDF/4.1.3/mpi/lib:/smplocal/pub/HDF5/1.8.9/par/lib + +%CPP mpiicc -EP +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_ADA.path b/arch/arch-X64_ADA.path new file mode 100644 index 0000000000000000000000000000000000000000..0a5ce51cefda3eeafcbe7f137a664fea2433d809 --- /dev/null +++ b/arch/arch-X64_ADA.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I/smplocal/pub/NetCDF/4.1.3/mpi/include" +NETCDF_LIBDIR="-L/smplocal/pub/NetCDF/4.1.3/mpi/lib" +NETCDF_LIB="-lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="-I/smplocal/pub/HDF5/1.8.9/par/include" +HDF5_LIBDIR="-L/smplocal/pub/HDF5/1.8.9/par/lib" +HDF5_LIB="-lhdf5_hl -lhdf5 -lhdf5 -lz" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-X64_ATHENA.env b/arch/arch-X64_ATHENA.env new file mode 100644 index 0000000000000000000000000000000000000000..0fe35c7c171ec290dd651ec84229e448ae032dfa --- /dev/null +++ b/arch/arch-X64_ATHENA.env @@ -0,0 +1,15 @@ +# Environment to compile XIOS on Athena +# +# Prerequisite softwares installed with +# +module load INTEL/intel_xe_2013 +module load HDF5/hdf5-1.8.11_parallel +module load NETCDF/netcdf-4.3_parallel +module load NETCDF/parallel-netcdf-1.3.1 + +#export NETCDF_DIR=${NETCDF} +#export PNETCDF_DIR=${PNETCDF} +export NETCDF_DIR=/users/home/opt/netcdf/netcdf-4.3_parallel +export PNETCDF_DIR=/users/home/opt/netcdf/parallel-netcdf-1.3.1 +export HDF5_DIR=/users/home/opt/hdf5/hdf5-1.8.11_parallel + diff --git a/arch/arch-X64_ATHENA.fcm b/arch/arch-X64_ATHENA.fcm new file mode 100644 index 0000000000000000000000000000000000000000..9839041c53832adfe60c078dc379bc5c51fbb0e7 --- /dev/null +++ b/arch/arch-X64_ATHENA.fcm @@ -0,0 +1,26 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpiicc +%FCOMPILER mpiifort +%LINKER mpiifort -nofor-main + +%BASE_CFLAGS -diag-disable 1125 -diag-disable 279 +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -traceback +%DEBUG_CFLAGS -DBZ_DEBUG -g -traceback -fno-inline + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 -traceback +%DEBUG_FFLAGS -g -traceback + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ -lz -lcurl -Wl -lgpfs + +%CPP mpiicc -EP +%FPP cpp -P +%MAKE gmake + + diff --git a/arch/arch-X64_ATHENA.path b/arch/arch-X64_ATHENA.path new file mode 100644 index 0000000000000000000000000000000000000000..e5816d93ec25b87105047cfdcc0fa059d1a969f1 --- /dev/null +++ b/arch/arch-X64_ATHENA.path @@ -0,0 +1,12 @@ +NETCDF_INCDIR="-I${NETCDF_DIR}/include -I${PNETCDF_DIR}/include" +NETCDF_LIBDIR="-L${NETCDF_DIR}/lib -L${PNETCDF_DIR}/lib" +NETCDF_LIB="-L${NETCDF_DIR}/lib -lnetcdff -L${NETCDF_DIR}/lib -lnetcdf -L${PNETCDF_DIR}/lib -lpnetcdf" + +HDF5_INCDIR="-I${HDF5_DIR}/include" +HDF5_LIBDIR="-L${HDF5_DIR}/lib" +HDF5_LIB="-L${HDF5_DIR}/lib -lhdf5_hl -L${HDF5_DIR}/lib -lhdf5" + +OASIS_INCDIR="" +OASIS_LIBDIR="" +OASIS_LIB="" + diff --git a/arch/arch-X64_CURIE.env b/arch/arch-X64_CURIE.env new file mode 100644 index 0000000000000000000000000000000000000000..3a47f6620adaf039caccd95e1cadef6f27cbba7b --- /dev/null +++ b/arch/arch-X64_CURIE.env @@ -0,0 +1,4 @@ +module unload netcdf +module unload hdf5 +module load hdf5/1.8.9_parallel +module load netcdf/4.2_hdf5_parallel diff --git a/arch/arch-X64_CURIE.fcm b/arch/arch-X64_CURIE.fcm new file mode 100644 index 0000000000000000000000000000000000000000..2b40e6195df3fe51f893aba75c201499a0abf01d --- /dev/null +++ b/arch/arch-X64_CURIE.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpicc +%FCOMPILER mpif90 +%LINKER mpif90 -nofor-main + +%BASE_CFLAGS -diag-disable 1125 -diag-disable 279 +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -traceback +%DEBUG_CFLAGS -DBZ_DEBUG -g -traceback -fno-inline + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 -traceback +%DEBUG_FFLAGS -g -traceback + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ + +%CPP mpicc -EP +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_CURIE.path b/arch/arch-X64_CURIE.path new file mode 100644 index 0000000000000000000000000000000000000000..8b35daad024f04d841d2ae55abbd1e348662ee76 --- /dev/null +++ b/arch/arch-X64_CURIE.path @@ -0,0 +1,19 @@ +NETCDF_INCDIR="-I $NETCDF_INCDIR" +NETCDF_LIBDIR="-L $NETCDF_LIBDIR" +NETCDF_LIB="-lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="-I$HDF5_INC_DIR" +HDF5_LIBDIR="-L$HDF5_LIB_DIR" +HDF5_LIB="-lhdf5_hl -lhdf5 -lhdf5 -lz -lcurl" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" + +#only for MEMTRACK debuging : developper only +ADDR2LINE_LIBDIR="-L${WORKDIR}/ADDR2LINE_LIB" +ADDR2LINE_LIB="-laddr2line" diff --git a/arch/arch-X64_CURIE_GCC.env b/arch/arch-X64_CURIE_GCC.env new file mode 100644 index 0000000000000000000000000000000000000000..764b701c64274ed0dd8ddbff893161235b13195d --- /dev/null +++ b/arch/arch-X64_CURIE_GCC.env @@ -0,0 +1,8 @@ +module unload netcdf +module unload hdf5 +module load netcdf/4.3.3.1_hdf5_parallel +module load gnu/4.9.1 +export OMPI_CC=gcc +export OMPI_CXX=g++ +export OMPI_F77=gfortran +export OMPI_FC=gfortran diff --git a/arch/arch-X64_CURIE_GCC.fcm b/arch/arch-X64_CURIE_GCC.fcm new file mode 100644 index 0000000000000000000000000000000000000000..d047ac5dfe30c54baa51f60d4c5ad907a830563b --- /dev/null +++ b/arch/arch-X64_CURIE_GCC.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpicc +%FCOMPILER mpif90 +%LINKER mpif90 + +%BASE_CFLAGS -w +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -O2 +%DEBUG_CFLAGS -g + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 +%DEBUG_FFLAGS -g + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_CURIE_GCC.path b/arch/arch-X64_CURIE_GCC.path new file mode 100644 index 0000000000000000000000000000000000000000..6032f7c0dd16cdb5fa52b19a3d3d0a2ed9741713 --- /dev/null +++ b/arch/arch-X64_CURIE_GCC.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INCDIR" +NETCDF_LIBDIR="-L $NETCDF_LIBDIR" +NETCDF_LIB="-lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="" +HDF5_LIBDIR="" +HDF5_LIB="" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-X64_CURIE_PGI.env b/arch/arch-X64_CURIE_PGI.env new file mode 100644 index 0000000000000000000000000000000000000000..3d5df63e72907e2fc16706e5dcc73b4f274f61d7 --- /dev/null +++ b/arch/arch-X64_CURIE_PGI.env @@ -0,0 +1,12 @@ +module unload netcdf +module unload hdf5 +module load netcdf/4.3.3.1_hdf5_parallel +#module unload intel +module unload pgi +module unload gnu +module load pgi/14.10 + +export OMPI_CC=pgcc +export OMPI_CXX=pgcpp +export OMPI_F77=pgf77 +export OMPI_FC=pgf95 diff --git a/arch/arch-X64_CURIE_PGI.fcm b/arch/arch-X64_CURIE_PGI.fcm new file mode 100644 index 0000000000000000000000000000000000000000..8c663cd015405dcacce38f3e1be192a797858649 --- /dev/null +++ b/arch/arch-X64_CURIE_PGI.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpicxx -noswitcherror +%FCOMPILER mpif90 -noswitcherror +%LINKER mpif90 -noswitcherror + +%BASE_CFLAGS -D__NONE__ +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -O2 +%DEBUG_CFLAGS -g + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 +%DEBUG_FFLAGS -g + +%BASE_INC -D__NONE__ +%BASE_LD -pgcpplibs + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_CURIE_PGI.path b/arch/arch-X64_CURIE_PGI.path new file mode 100644 index 0000000000000000000000000000000000000000..6032f7c0dd16cdb5fa52b19a3d3d0a2ed9741713 --- /dev/null +++ b/arch/arch-X64_CURIE_PGI.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INCDIR" +NETCDF_LIBDIR="-L $NETCDF_LIBDIR" +NETCDF_LIB="-lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="" +HDF5_LIBDIR="" +HDF5_LIB="" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-X64_CURIE_VAMPIR.env b/arch/arch-X64_CURIE_VAMPIR.env new file mode 100644 index 0000000000000000000000000000000000000000..9d06affa8bc8955aa6786a684df5bfee81e97284 --- /dev/null +++ b/arch/arch-X64_CURIE_VAMPIR.env @@ -0,0 +1,5 @@ +module unload netcdf +module unload hdf5 +module unload vampir +module load vampir/8.2.1 +module load netcdf/4.3.3.1_hdf5_parallel diff --git a/arch/arch-X64_CURIE_VAMPIR.fcm b/arch/arch-X64_CURIE_VAMPIR.fcm new file mode 100644 index 0000000000000000000000000000000000000000..e40091ceefb417272357e731b6f3bfe683010f7f --- /dev/null +++ b/arch/arch-X64_CURIE_VAMPIR.fcm @@ -0,0 +1,23 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER vtcc -vt:cc mpicc -vt:inst manual -DVTRACE +%FCOMPILER vtf90 -vt:f90 mpif90 -vt:inst manual -DVTRACE +%LINKER vtf90 -vt:f90 mpif90 -vt:inst manual -nofor-main -DVTRACE +%BASE_CFLAGS -diag-disable 1125 -diag-disable 279 +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -traceback +%DEBUG_CFLAGS -DBZ_DEBUG -g -traceback -fno-inline + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 -traceback +%DEBUG_FFLAGS -g -traceback + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_CURIE_VAMPIR.path b/arch/arch-X64_CURIE_VAMPIR.path new file mode 100644 index 0000000000000000000000000000000000000000..3b3f6914c0158e99c1fac02575b7343758bd1e91 --- /dev/null +++ b/arch/arch-X64_CURIE_VAMPIR.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INCDIR" +NETCDF_LIBDIR="-L$NETCDF_LIBDIR" +NETCDF_LIB="-lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="" +HDF5_LIBDIR="" +HDF5_LIB="-lhdf5_hl -lhdf5 -lz -lcurl" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-X64_HORUS.env b/arch/arch-X64_HORUS.env new file mode 100644 index 0000000000000000000000000000000000000000..a065dbf6bd2d0f42a8543f1e66646eb31a7b57e8 --- /dev/null +++ b/arch/arch-X64_HORUS.env @@ -0,0 +1,6 @@ +export HDF5_INC_DIR=$HOME/hdf5/include +export HDF5_LIB_DIR=$HOME/hdf5/lib + +export NETCDF_INC_DIR=$HOME/netcdf4/include +export NETCDF_LIB_DIR=$HOME/netcdf4/lib + diff --git a/arch/arch-X64_HORUS.fcm b/arch/arch-X64_HORUS.fcm new file mode 100644 index 0000000000000000000000000000000000000000..cbfbc97123b3f7625624af12f1b7c5fd153e02bf --- /dev/null +++ b/arch/arch-X64_HORUS.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpicc +%FCOMPILER mpif90 +%LINKER mpif90 + +%BASE_CFLAGS -w +%PROD_CFLAGS -O3 -DBOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -O2 +%DEBUG_CFLAGS -g + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 +%DEBUG_FFLAGS -g + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_HORUS.path b/arch/arch-X64_HORUS.path new file mode 100644 index 0000000000000000000000000000000000000000..65c11769c3e0a3cf65a95e93d68d013c8022c118 --- /dev/null +++ b/arch/arch-X64_HORUS.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INC_DIR" +NETCDF_LIBDIR="-L $NETCDF_LIB_DIR" +NETCDF_LIB="-lnetcdff -lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="-I $HDF5_INC_DIR" +HDF5_LIBDIR="-L $HDF5_LIB_DIR" +HDF5_LIB="-lhdf5_hl -lhdf5 -lhdf5 -lz" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-X64_JADE.env b/arch/arch-X64_JADE.env new file mode 100644 index 0000000000000000000000000000000000000000..06c9557ac6c8841c61b95d360fe19e14ffa92151 --- /dev/null +++ b/arch/arch-X64_JADE.env @@ -0,0 +1,12 @@ +module unload hdf5 +module unload zlib +module unload pnetcdf +module unload netcdf + +module load hdf5/1.8.9 +module load pnetcdf/1.3.0 +module load zlib/1.2.5 +module load netcdf_C/4.2.1.1 + +export NETCDF_INC_DIR="/opt/software/SGI/netcdf/C/4.2.1.1/include" +export NETCDF_LIB_DIR="/opt/software/SGI/netcdf/C/4.2.1.1/lib" diff --git a/arch/arch-X64_JADE.fcm b/arch/arch-X64_JADE.fcm new file mode 100644 index 0000000000000000000000000000000000000000..00927ad2a619ecf7d1da8807a6fdff2a5ccfc99a --- /dev/null +++ b/arch/arch-X64_JADE.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER icc +%FCOMPILER ifort +%LINKER ifort + +%BASE_CFLAGS -diag-disable 1125 -diag-disable 279 +%PROD_CFLAGS -O3 -DBOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -O2 -traceback +%DEBUG_CFLAGS -DBZ_DEBUG -g -traceback -fno-inline + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 -traceback +%DEBUG_FFLAGS -g -traceback + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ -lifcore -lintlc -lmpi + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_JADE.path b/arch/arch-X64_JADE.path new file mode 100644 index 0000000000000000000000000000000000000000..26ec954f126570590259749d7b430cadbc143508 --- /dev/null +++ b/arch/arch-X64_JADE.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INC_DIR" +NETCDF_LIBDIR="" +NETCDF_LIB="-lnetcdf -lpnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="" +HDF5_LIBDIR="" +HDF5_LIB="-lhdf5_hl -lhdf5 -lhdf5 -lz" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-X64_TITANE.env b/arch/arch-X64_TITANE.env new file mode 100644 index 0000000000000000000000000000000000000000..260ce7ee5e5412e5f85f0dd3425769b9565dc152 --- /dev/null +++ b/arch/arch-X64_TITANE.env @@ -0,0 +1,4 @@ +module unload netcdf +module unload hdf5 +module load netcdf/4.2 +module load hdf5/1.8.8 diff --git a/arch/arch-X64_TITANE.fcm b/arch/arch-X64_TITANE.fcm new file mode 100644 index 0000000000000000000000000000000000000000..97038f70e44bb934a61edbaff4870e7c51b50936 --- /dev/null +++ b/arch/arch-X64_TITANE.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER mpicc +%FCOMPILER mpif90 +%LINKER mpif90 -nofor-main + +%BASE_CFLAGS -diag-disable 1125 -diag-disable 279 +%PROD_CFLAGS -O3 -DBOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -O2 -traceback +%DEBUG_CFLAGS -DBZ_DEBUG -g -traceback -fno-inline + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 -traceback +%DEBUG_FFLAGS -g -traceback + +%BASE_INC -D __NONE__ +%BASE_LD -lstdc++ + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_TITANE.path b/arch/arch-X64_TITANE.path new file mode 100644 index 0000000000000000000000000000000000000000..fc522ecd64f0d47b08210b4c0ff1962f1896a24b --- /dev/null +++ b/arch/arch-X64_TITANE.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INC_DIR" +NETCDF_LIBDIR="-L $NETCDF_LIB_DIR" +NETCDF_LIB="-lnetcdff -lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="-I $HDF5_INC_DIR" +HDF5_LIBDIR="-L $HDF5_LIB_DIR" +HDF5_LIB="-lhdf5_hl -lhdf5 -lhdf5 -lz -lcurl" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-X64_TITANE_VAMPIR.env b/arch/arch-X64_TITANE_VAMPIR.env new file mode 100644 index 0000000000000000000000000000000000000000..260ce7ee5e5412e5f85f0dd3425769b9565dc152 --- /dev/null +++ b/arch/arch-X64_TITANE_VAMPIR.env @@ -0,0 +1,4 @@ +module unload netcdf +module unload hdf5 +module load netcdf/4.2 +module load hdf5/1.8.8 diff --git a/arch/arch-X64_TITANE_VAMPIR.fcm b/arch/arch-X64_TITANE_VAMPIR.fcm new file mode 100644 index 0000000000000000000000000000000000000000..abfe1ddcf21ca4a0f56ae71bd3ffbef4af7cf2cf --- /dev/null +++ b/arch/arch-X64_TITANE_VAMPIR.fcm @@ -0,0 +1,23 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER vtcc -vt:cc mpicc -vt:inst manual -DVTRACE +%FCOMPILER vtf90 -vt:f90 mpif90 -vt:inst manual -DVTRACE +%LINKER vtf90 -vt:f90 mpif90 -vt:inst manual -nofor-main -DVTRACE +%BASE_CFLAGS -diag-disable 1125 -diag-disable 279 +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -traceback +%DEBUG_CFLAGS -DBZ_DEBUG -g -traceback -fno-inline + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 -traceback +%DEBUG_FFLAGS -g -traceback + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-X64_TITANE_VAMPIR.path b/arch/arch-X64_TITANE_VAMPIR.path new file mode 100644 index 0000000000000000000000000000000000000000..fc522ecd64f0d47b08210b4c0ff1962f1896a24b --- /dev/null +++ b/arch/arch-X64_TITANE_VAMPIR.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INC_DIR" +NETCDF_LIBDIR="-L $NETCDF_LIB_DIR" +NETCDF_LIB="-lnetcdff -lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="-I $HDF5_INC_DIR" +HDF5_LIBDIR="-L $HDF5_LIB_DIR" +HDF5_LIB="-lhdf5_hl -lhdf5 -lhdf5 -lz -lcurl" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-XC30_Cray.env b/arch/arch-XC30_Cray.env new file mode 100644 index 0000000000000000000000000000000000000000..63e629da3399b2b280bc34a3d8c6b5d7bb8a6f77 --- /dev/null +++ b/arch/arch-XC30_Cray.env @@ -0,0 +1,5 @@ +export HDF5_INC_DIR="" +export HDF5_LIB_DIR="" + +export NETCDF_INC_DIR="" +export NETCDF_LIB_DIR="" diff --git a/arch/arch-XC30_Cray.fcm b/arch/arch-XC30_Cray.fcm new file mode 100644 index 0000000000000000000000000000000000000000..df6bf5a322fd4f4150989ce1c05ea9784cdb1b37 --- /dev/null +++ b/arch/arch-XC30_Cray.fcm @@ -0,0 +1,42 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +# Cray XC build instructions for XIOS/xios-1.0 +# These files have been tested on +# Archer (XC30), ECMWF (XC30), and the Met Office (XC40) using the Cray PrgEnv. +# One must also: +# module load cray-netcdf-hdf5parallel/4.3.2 +# There is a bug in the CC compiler prior to cce/8.3.7 using -O3 or -O2 +# The workarounds are not ideal: +# Use -Gfast and put up with VERY large executables +# Use -O1 and possibly suffer a significant performance loss. +# +# Mike Rezny Met Office 23/03/2015 + +%CCOMPILER CC +%FCOMPILER ftn +%LINKER CC + +%BASE_CFLAGS -DMPICH_SKIP_MPICXX -h msglevel_4 -h zero -h gnu + +## Only use -O3 if you can load module cce/8.3.7 or later +#%PROD_CFLAGS -O3 -DBOOST_DISABLE_ASSERTS + +## Otherwise take your pick of these, refer to information above. +%PROD_CFLAGS -O1 -DBOOST_DISABLE_ASSERTS +## %PROD_CFLAGS -Gfast -DBOOST_DISABLE_ASSERTS +%DEV_CFLAGS -O2 +%DEBUG_CFLAGS -g + +%BASE_FFLAGS -em -m 4 -e0 -eZ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -G2 +%DEBUG_FFLAGS -g + +%BASE_INC -D__NONE__ +%BASE_LD -D__NONE__ + +%CPP cpp +%FPP cpp -P -CC +%MAKE gmake diff --git a/arch/arch-XC30_Cray.path b/arch/arch-XC30_Cray.path new file mode 100644 index 0000000000000000000000000000000000000000..8b97af306088becefcf60cd65a455e43868beda4 --- /dev/null +++ b/arch/arch-XC30_Cray.path @@ -0,0 +1,18 @@ +NETCDF_INCDIR="" +NETCDF_LIBDIR="" +NETCDF_LIB="" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +HDF5_INCDIR="" +HDF5_LIBDIR="" +HDF5_LIB="" + +OASIS_INCDIR="" +OASIS_LIBDIR="" +OASIS_LIB="" +#OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +#OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +#OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-XE6_LYNX.env b/arch/arch-XE6_LYNX.env new file mode 100644 index 0000000000000000000000000000000000000000..8790aeb80bff6911d98e937eb3d6e8697135ad81 --- /dev/null +++ b/arch/arch-XE6_LYNX.env @@ -0,0 +1,4 @@ +export HDF5_INC_DIR=$WORKDIR/hdf5/include +export HDF5_LIB_DIR=${CRAY_HDF5_DIR}/hdf5-parallel-cce/lib +export NETCDF_INC_DIR=${CRAY_NETCDF_DIR}/netcdf-hdf5parallel-cce/include +export NETCDF_LIB_DIR=${CRAY_NETCDF_DIR}/netcdf-hdf5parallel-cce/lib diff --git a/arch/arch-XE6_LYNX.fcm b/arch/arch-XE6_LYNX.fcm new file mode 100644 index 0000000000000000000000000000000000000000..b1094c7e4d518b071f9bc01ab5729960240b9193 --- /dev/null +++ b/arch/arch-XE6_LYNX.fcm @@ -0,0 +1,24 @@ +################################################################################ +################### Projet xios - xmlioserver ##################### +################################################################################ + +%CCOMPILER CC +%FCOMPILER ftn +%LINKER CC + +%BASE_CFLAGS -DMPICH_SKIP_MPICXX -h msglevel_4 +%PROD_CFLAGS -O3 -DBOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -O2 +%DEBUG_CFLAGS -g + +%BASE_FFLAGS -em -m 4 +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 +%DEBUG_FFLAGS -g + +%BASE_INC -D__NONE__ +%BASE_LD -D__NONE__ + +%CPP cpp +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-XE6_LYNX.path b/arch/arch-XE6_LYNX.path new file mode 100644 index 0000000000000000000000000000000000000000..fa5642cc7a24f04dd740b310a814b17cb217b6cb --- /dev/null +++ b/arch/arch-XE6_LYNX.path @@ -0,0 +1,15 @@ +NETCDF_INCDIR="-I $NETCDF_INC_DIR" +NETCDF_LIBDIR="-L $NETCDF_LIB_DIR" +NETCDF_LIB="-lnetcdf" + +MPI_INCDIR="" +MPI_LIBDIR="" +MPI_LIB="" + +#HDF5_INCDIR="-I $HDF5_INC_DIR" +HDF5_LIBDIR="-L $HDF5_LIB_DIR" +HDF5_LIB="-lhdf5_hl -lhdf5 -lz -lcurl" + +OASIS_INCDIR="-I$PWD/../../oasis3-mct/BLD/build/lib/psmile.MPI1" +OASIS_LIBDIR="-L$PWD/../../oasis3-mct/BLD/lib" +OASIS_LIB="-lpsmile.MPI1 -lscrip -lmct -lmpeu" diff --git a/arch/arch-ifort_LSCE.fcm b/arch/arch-ifort_LSCE.fcm new file mode 100644 index 0000000000000000000000000000000000000000..d146074e4b3ba875cf06ad8414b5452f2e742bdf --- /dev/null +++ b/arch/arch-ifort_LSCE.fcm @@ -0,0 +1,20 @@ +%CCOMPILER mpicc +%FCOMPILER mpif90 +%LINKER mpif90 -nofor-main + +%BASE_CFLAGS +%PROD_CFLAGS -O3 -D BOOST_DISABLE_ASSERTS +%DEV_CFLAGS -g -traceback +%DEBUG_CFLAGS -DBZ_DEBUG -g -traceback -fno-inline + +%BASE_FFLAGS -D__NONE__ +%PROD_FFLAGS -O3 +%DEV_FFLAGS -g -O2 -traceback +%DEBUG_FFLAGS -g -traceback + +%BASE_INC -D__NONE__ +%BASE_LD -lstdc++ + +%CPP mpicc -EP +%FPP cpp -P +%MAKE gmake diff --git a/arch/arch-ifort_LSCE.path b/arch/arch-ifort_LSCE.path new file mode 100644 index 0000000000000000000000000000000000000000..6357d4061d68d35188ca06be0c9954c2e2a6b60c --- /dev/null +++ b/arch/arch-ifort_LSCE.path @@ -0,0 +1,6 @@ +NETCDF_INCDIR="-I /usr/local/install/netcdf-4.3.2p/include" +NETCDF_LIBDIR="-L/usr/local/install/netcdf-4.3.2p/lib" +NETCDF_LIB="-lnetcdf" +HDF5_INCDIR="-I /usr/local/install/hdf5-1.8.9p/include" +HDF5_LIBDIR="-L/usr/local/install/hdf5-1.8.9p/lib" +HDF5_LIB="-lhdf5_hl -lhdf5 -lhdf5 -lz -lcurl" diff --git a/bld.cfg b/bld.cfg new file mode 100644 index 0000000000000000000000000000000000000000..bbe9373257cae834b6907b43c84b0d3e05f4d43b --- /dev/null +++ b/bld.cfg @@ -0,0 +1,58 @@ +# ----------------------- FCM extract configuration file ----------------------- +cfg::type bld +cfg::version 1.0 + + +# ------------------------------------------------------------------------------ +# Build information +# ------------------------------------------------------------------------------ + +inc arch.fcm +inc config.fcm + +%CFLAGS %BASE_CFLAGS %COMPIL_CFLAGS +%FFLAGS %BASE_FFLAGS %COMPIL_FFLAGS +%LD_FLAGS %ARCH_LD %BASE_LD + + +dest::root $PWD + +bld::infile_ext::cpp C::SOURCE +bld::infile_ext::conf CPP::INCLUDE +bld::infile_ext::hpp CPP::INCLUDE + + +search_src true +src::zzz . +src::date $PWD/extern/boost/src/date_time +src::blitz $PWD/extern/blitz/src +src::netcdf $PWD/extern/netcdf4 +bld::lib xios +bld::target libxios.a +#bld::target generate_fortran_interface.exe +bld::target xios_server.exe test_client.exe parse_xml.exe test_complete.exe test_xios_interface.exe +bld::exe_dep + +bld::tool::cc %CCOMPILER +bld::tool::fc %FCOMPILER +bld::tool::fpp %FPP +bld::tool::cpp %CPP +bld::tool::cppflags %CBASE_INC -I${PWD}/extern/src_netcdf -I${PWD}/extern/boost/include -I${PWD}/extern/rapidxml/include -I${PWD}/extern/blitz/include +bld::tool::fppflags %BASE_INC -I${PWD}/extern/boost/include -I${PWD}/extern/rapidxml/include +bld::tool::ld %LINKER +bld::tool::ldflags %LD_FLAGS +bld::tool::cflags %CFLAGS %CBASE_INC -I${PWD}/extern/src_netcdf -I${PWD}/extern/boost/include -I${PWD}/extern/rapidxml/include -I${PWD}/extern/blitz/include +bld::tool::fflags %FFLAGS %FBASE_INC +bld::tool::cppkeys %CPP_KEY +bld::tool::fppkeys %CPP_KEY +bld::tool::make %MAKE + +# Pre-process code before analysing dependencies +bld::pp false +bld::pp::interface/fortran true +bld::pp::interface/fortran_attr true +bld::excl_dep use::mod_prism_get_comm +bld::excl_dep use::mod_prism_get_localcomm_proto +bld::excl_dep use::mod_prism_proto +bld::excl_dep use::mod_prism +bld::excl_dep inc::mpif.h diff --git a/doc/XIOS_reference_guide.pdf b/doc/XIOS_reference_guide.pdf new file mode 100755 index 0000000000000000000000000000000000000000..a06dd9cc45e6653e980555f9278664290fcca7cf Binary files /dev/null and b/doc/XIOS_reference_guide.pdf differ diff --git a/doc/reference_xml.pdf b/doc/reference_xml.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1f5bee63f8a58b4fcba43a33249f03db9190971c Binary files /dev/null and b/doc/reference_xml.pdf differ diff --git a/extern/src_netcdf4/attr.c b/extern/src_netcdf4/attr.c new file mode 100644 index 0000000000000000000000000000000000000000..10bd63d35e0fc120fb76fc423ad4b5dc154fa820 --- /dev/null +++ b/extern/src_netcdf4/attr.c @@ -0,0 +1,1164 @@ +/* Do not edit this file. It is produced from the corresponding .m4 source */ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: attr.m4,v 2.39 2010/05/26 18:11:08 dmh Exp $ */ + +#include "nc.h" +#include "ncdispatch.h" +#include "nc3dispatch.h" +#include +#include +#include +#include "ncx.h" +#include "fbits.h" +#include "rnd.h" +#include "utf8proc.h" + + +/* + * Free attr + * Formerly +NC_free_attr() + */ +void +free_NC_attr(NC_attr *attrp) +{ + + if(attrp == NULL) + return; + free_NC_string(attrp->name); + free(attrp); +} + + +/* + * How much space will 'nelems' of 'type' take in + * external representation (as the values of an attribute)? + */ +static size_t +ncx_len_NC_attrV(nc_type type, size_t nelems) +{ + switch(type) { + case NC_BYTE: + case NC_CHAR: + return ncx_len_char(nelems); + case NC_SHORT: + return ncx_len_short(nelems); + case NC_INT: + return ncx_len_int(nelems); + case NC_FLOAT: + return ncx_len_float(nelems); + case NC_DOUBLE: + return ncx_len_double(nelems); + default: + assert("ncx_len_NC_attr bad type" == 0); + } + return 0; +} + + +NC_attr * +new_x_NC_attr( + NC_string *strp, + nc_type type, + size_t nelems) +{ + NC_attr *attrp; + const size_t xsz = ncx_len_NC_attrV(type, nelems); + size_t sz = M_RNDUP(sizeof(NC_attr)); + + assert(!(xsz == 0 && nelems != 0)); + + sz += xsz; + + attrp = (NC_attr *) malloc(sz); + if(attrp == NULL ) + return NULL; + + attrp->xsz = xsz; + + attrp->name = strp; + attrp->type = type; + attrp->nelems = nelems; + if(xsz != 0) + attrp->xvalue = (char *)attrp + M_RNDUP(sizeof(NC_attr)); + else + attrp->xvalue = NULL; + + return(attrp); +} + + +/* + * Formerly +NC_new_attr(name,type,count,value) + */ +static NC_attr * +new_NC_attr( + const char *uname, + nc_type type, + size_t nelems) +{ + NC_string *strp; + NC_attr *attrp; + + char *name = (char *)utf8proc_NFC((const unsigned char *)uname); + if(name == NULL) + return NULL; + assert(name != NULL && *name != 0); + + strp = new_NC_string(strlen(name), name); + free(name); + if(strp == NULL) + return NULL; + + attrp = new_x_NC_attr(strp, type, nelems); + if(attrp == NULL) + { + free_NC_string(strp); + return NULL; + } + + return(attrp); +} + + +static NC_attr * +dup_NC_attr(const NC_attr *rattrp) +{ + NC_attr *attrp = new_NC_attr(rattrp->name->cp, + rattrp->type, rattrp->nelems); + if(attrp == NULL) + return NULL; + (void) memcpy(attrp->xvalue, rattrp->xvalue, rattrp->xsz); + return attrp; +} + +/* attrarray */ + +/* + * Free the stuff "in" (referred to by) an NC_attrarray. + * Leaves the array itself allocated. + */ +void +free_NC_attrarrayV0(NC_attrarray *ncap) +{ + assert(ncap != NULL); + + if(ncap->nelems == 0) + return; + + assert(ncap->value != NULL); + + { + NC_attr **app = ncap->value; + NC_attr *const *const end = &app[ncap->nelems]; + for( /*NADA*/; app < end; app++) + { + free_NC_attr(*app); + *app = NULL; + } + } + ncap->nelems = 0; +} + + +/* + * Free NC_attrarray values. + * formerly +NC_free_array() + */ +void +free_NC_attrarrayV(NC_attrarray *ncap) +{ + assert(ncap != NULL); + + if(ncap->nalloc == 0) + return; + + assert(ncap->value != NULL); + + free_NC_attrarrayV0(ncap); + + free(ncap->value); + ncap->value = NULL; + ncap->nalloc = 0; +} + + +int +dup_NC_attrarrayV(NC_attrarray *ncap, const NC_attrarray *ref) +{ + int status = NC_NOERR; + + assert(ref != NULL); + assert(ncap != NULL); + + if(ref->nelems != 0) + { + const size_t sz = ref->nelems * sizeof(NC_attr *); + ncap->value = (NC_attr **) malloc(sz); + if(ncap->value == NULL) + return NC_ENOMEM; + + (void) memset(ncap->value, 0, sz); + ncap->nalloc = ref->nelems; + } + + ncap->nelems = 0; + { + NC_attr **app = ncap->value; + const NC_attr **drpp = (const NC_attr **)ref->value; + NC_attr *const *const end = &app[ref->nelems]; + for( /*NADA*/; app < end; drpp++, app++, ncap->nelems++) + { + *app = dup_NC_attr(*drpp); + if(*app == NULL) + { + status = NC_ENOMEM; + break; + } + } + } + + if(status != NC_NOERR) + { + free_NC_attrarrayV(ncap); + return status; + } + + assert(ncap->nelems == ref->nelems); + + return NC_NOERR; +} + + +/* + * Add a new handle on the end of an array of handles + * Formerly +NC_incr_array(array, tail) + */ +static int +incr_NC_attrarray(NC_attrarray *ncap, NC_attr *newelemp) +{ + NC_attr **vp; + + assert(ncap != NULL); + + if(ncap->nalloc == 0) + { + assert(ncap->nelems == 0); + vp = (NC_attr **) malloc(NC_ARRAY_GROWBY * sizeof(NC_attr *)); + if(vp == NULL) + return NC_ENOMEM; + + ncap->value = vp; + ncap->nalloc = NC_ARRAY_GROWBY; + } + else if(ncap->nelems +1 > ncap->nalloc) + { + vp = (NC_attr **) realloc(ncap->value, + (ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_attr *)); + if(vp == NULL) + return NC_ENOMEM; + + ncap->value = vp; + ncap->nalloc += NC_ARRAY_GROWBY; + } + + if(newelemp != NULL) + { + ncap->value[ncap->nelems] = newelemp; + ncap->nelems++; + } + return NC_NOERR; +} + + +NC_attr * +elem_NC_attrarray(const NC_attrarray *ncap, size_t elem) +{ + assert(ncap != NULL); + /* cast needed for braindead systems with signed size_t */ + if(ncap->nelems == 0 || (unsigned long) elem >= ncap->nelems) + return NULL; + + assert(ncap->value != NULL); + + return ncap->value[elem]; +} + +/* End attarray per se */ + +/* + * Given ncp and varid, return ptr to array of attributes + * else NULL on error + */ +static NC_attrarray * +NC_attrarray0( NC *ncp, int varid) +{ + NC_attrarray *ap; + + if(varid == NC_GLOBAL) /* Global attribute, attach to cdf */ + { + ap = &ncp->attrs; + } + else if(varid >= 0 && (size_t) varid < ncp->vars.nelems) + { + NC_var **vpp; + vpp = (NC_var **)ncp->vars.value; + vpp += varid; + ap = &(*vpp)->attrs; + } else { + ap = NULL; + } + return(ap); +} + + +/* + * Step thru NC_ATTRIBUTE array, seeking match on name. + * return match or NULL if Not Found or out of memory. + */ +NC_attr ** +NC_findattr(const NC_attrarray *ncap, const char *uname) +{ + NC_attr **attrpp; + size_t attrid; + size_t slen; + char *name; + + assert(ncap != NULL); + + if(ncap->nelems == 0) + return NULL; + + attrpp = (NC_attr **) ncap->value; + + /* normalized version of uname */ + name = (char *)utf8proc_NFC((const unsigned char *)uname); + if(name == NULL) + return NULL; /* TODO: need better way to indicate no memory */ + slen = strlen(name); + + for(attrid = 0; attrid < ncap->nelems; attrid++, attrpp++) + { + if(strlen((*attrpp)->name->cp) == slen && + strncmp((*attrpp)->name->cp, name, slen) == 0) + { + free(name); + return(attrpp); /* Normal return */ + } + } + free(name); + return(NULL); +} + + +/* + * Look up by ncid, varid and name, return NULL if not found + */ +static int +NC_lookupattr(int ncid, + int varid, + const char *name, /* attribute name */ + NC_attr **attrpp) /* modified on return */ +{ + int status; + NC *ncp; + NC_attrarray *ncap; + NC_attr **tmp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + ncap = NC_attrarray0(ncp, varid); + if(ncap == NULL) + return NC_ENOTVAR; + + tmp = NC_findattr(ncap, name); + if(tmp == NULL) + return NC_ENOTATT; + + if(attrpp != NULL) + *attrpp = *tmp; + + return ENOERR; +} + +/* Public */ + +int +NC3_inq_attname(int ncid, int varid, int attnum, char *name) +{ + int status; + NC *ncp; + NC_attrarray *ncap; + NC_attr *attrp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + ncap = NC_attrarray0(ncp, varid); + if(ncap == NULL) + return NC_ENOTVAR; + + attrp = elem_NC_attrarray(ncap, (size_t)attnum); + if(attrp == NULL) + return NC_ENOTATT; + + (void) strncpy(name, attrp->name->cp, attrp->name->nchars); + name[attrp->name->nchars] = 0; + + return NC_NOERR; +} + + +int +NC3_inq_attid(int ncid, int varid, const char *name, int *attnump) +{ + int status; + NC *ncp; + NC_attrarray *ncap; + NC_attr **attrpp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + ncap = NC_attrarray0(ncp, varid); + if(ncap == NULL) + return NC_ENOTVAR; + + + attrpp = NC_findattr(ncap, name); + if(attrpp == NULL) + return NC_ENOTATT; + + if(attnump != NULL) + *attnump = (int)(attrpp - ncap->value); + + return NC_NOERR; +} + +int +NC3_inq_att(int ncid, + int varid, + const char *name, /* input, attribute name */ + nc_type *datatypep, + size_t *lenp) +{ + int status; + NC_attr *attrp; + + status = NC_lookupattr(ncid, varid, name, &attrp); + if(status != NC_NOERR) + return status; + + if(datatypep != NULL) + *datatypep = attrp->type; + if(lenp != NULL) + *lenp = attrp->nelems; + + return NC_NOERR; +} + + +int +NC3_rename_att( int ncid, int varid, const char *name, const char *unewname) +{ + int status; + NC *ncp; + NC_attrarray *ncap; + NC_attr **tmp; + NC_attr *attrp; + NC_string *newStr, *old; + char *newname; /* normalized version */ + + /* sortof inline clone of NC_lookupattr() */ + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_readonly(ncp)) + return NC_EPERM; + + ncap = NC_attrarray0(ncp, varid); + if(ncap == NULL) + return NC_ENOTVAR; + + status = NC_check_name(unewname); + if(status != NC_NOERR) + return status; + + tmp = NC_findattr(ncap, name); + if(tmp == NULL) + return NC_ENOTATT; + attrp = *tmp; + /* end inline clone NC_lookupattr() */ + + if(NC_findattr(ncap, unewname) != NULL) + { + /* name in use */ + return NC_ENAMEINUSE; + } + + old = attrp->name; + newname = (char *)utf8proc_NFC((const unsigned char *)unewname); + if(newname == NULL) + return NC_EBADNAME; + if(NC_indef(ncp)) + { + newStr = new_NC_string(strlen(newname), newname); + free(newname); + if( newStr == NULL) + return NC_ENOMEM; + attrp->name = newStr; + free_NC_string(old); + return NC_NOERR; + } + /* else */ + status = set_NC_string(old, newname); + free(newname); + if( status != NC_NOERR) + return status; + + set_NC_hdirty(ncp); + + if(NC_doHsync(ncp)) + { + status = NC_sync(ncp); + if(status != NC_NOERR) + return status; + } + + return NC_NOERR; +} + +int +NC3_del_att(int ncid, int varid, const char *uname) +{ + int status; + NC *ncp; + NC_attrarray *ncap; + NC_attr **attrpp; + NC_attr *old = NULL; + int attrid; + size_t slen; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(!NC_indef(ncp)) + return NC_ENOTINDEFINE; + + ncap = NC_attrarray0(ncp, varid); + if(ncap == NULL) + return NC_ENOTVAR; + + { + char *name = (char *)utf8proc_NFC((const unsigned char *)uname); + if(name == NULL) + return NC_ENOMEM; + + /* sortof inline NC_findattr() */ + slen = strlen(name); + + attrpp = (NC_attr **) ncap->value; + for(attrid = 0; (size_t) attrid < ncap->nelems; attrid++, attrpp++) + { + if( slen == (*attrpp)->name->nchars && + strncmp(name, (*attrpp)->name->cp, slen) == 0) + { + old = *attrpp; + break; + } + } + free(name); + } + if( (size_t) attrid == ncap->nelems ) + return NC_ENOTATT; + /* end inline NC_findattr() */ + + /* shuffle down */ + for(attrid++; (size_t) attrid < ncap->nelems; attrid++) + { + *attrpp = *(attrpp + 1); + attrpp++; + } + *attrpp = NULL; + /* decrement count */ + ncap->nelems--; + + free_NC_attr(old); + + return NC_NOERR; +} + + +static int +ncx_pad_putn_Iuchar(void **xpp, size_t nelems, const uchar *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_putn_schar_uchar(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_putn_short_uchar(xpp, nelems, tp); + case NC_INT: + return ncx_putn_int_uchar(xpp, nelems, tp); + case NC_FLOAT: + return ncx_putn_float_uchar(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_putn_double_uchar(xpp, nelems, tp); + default: + assert("ncx_pad_putn_Iuchar invalid type" == 0); + } + return NC_EBADTYPE; +} + +static int +ncx_pad_getn_Iuchar(const void **xpp, size_t nelems, uchar *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_getn_schar_uchar(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_getn_short_uchar(xpp, nelems, tp); + case NC_INT: + return ncx_getn_int_uchar(xpp, nelems, tp); + case NC_FLOAT: + return ncx_getn_float_uchar(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_getn_double_uchar(xpp, nelems, tp); + default: + assert("ncx_pad_getn_Iuchar invalid type" == 0); + } + return NC_EBADTYPE; +} + + +static int +ncx_pad_putn_Ischar(void **xpp, size_t nelems, const schar *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_putn_schar_schar(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_putn_short_schar(xpp, nelems, tp); + case NC_INT: + return ncx_putn_int_schar(xpp, nelems, tp); + case NC_FLOAT: + return ncx_putn_float_schar(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_putn_double_schar(xpp, nelems, tp); + default: + assert("ncx_pad_putn_Ischar invalid type" == 0); + } + return NC_EBADTYPE; +} + +static int +ncx_pad_getn_Ischar(const void **xpp, size_t nelems, schar *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_getn_schar_schar(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_getn_short_schar(xpp, nelems, tp); + case NC_INT: + return ncx_getn_int_schar(xpp, nelems, tp); + case NC_FLOAT: + return ncx_getn_float_schar(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_getn_double_schar(xpp, nelems, tp); + default: + assert("ncx_pad_getn_Ischar invalid type" == 0); + } + return NC_EBADTYPE; +} + + +static int +ncx_pad_putn_Ishort(void **xpp, size_t nelems, const short *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_putn_schar_short(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_putn_short_short(xpp, nelems, tp); + case NC_INT: + return ncx_putn_int_short(xpp, nelems, tp); + case NC_FLOAT: + return ncx_putn_float_short(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_putn_double_short(xpp, nelems, tp); + default: + assert("ncx_pad_putn_Ishort invalid type" == 0); + } + return NC_EBADTYPE; +} + +static int +ncx_pad_getn_Ishort(const void **xpp, size_t nelems, short *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_getn_schar_short(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_getn_short_short(xpp, nelems, tp); + case NC_INT: + return ncx_getn_int_short(xpp, nelems, tp); + case NC_FLOAT: + return ncx_getn_float_short(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_getn_double_short(xpp, nelems, tp); + default: + assert("ncx_pad_getn_Ishort invalid type" == 0); + } + return NC_EBADTYPE; +} + + +static int +ncx_pad_putn_Iint(void **xpp, size_t nelems, const int *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_putn_schar_int(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_putn_short_int(xpp, nelems, tp); + case NC_INT: + return ncx_putn_int_int(xpp, nelems, tp); + case NC_FLOAT: + return ncx_putn_float_int(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_putn_double_int(xpp, nelems, tp); + default: + assert("ncx_pad_putn_Iint invalid type" == 0); + } + return NC_EBADTYPE; +} + +static int +ncx_pad_getn_Iint(const void **xpp, size_t nelems, int *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_getn_schar_int(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_getn_short_int(xpp, nelems, tp); + case NC_INT: + return ncx_getn_int_int(xpp, nelems, tp); + case NC_FLOAT: + return ncx_getn_float_int(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_getn_double_int(xpp, nelems, tp); + default: + assert("ncx_pad_getn_Iint invalid type" == 0); + } + return NC_EBADTYPE; +} + + +static int +ncx_pad_putn_Ifloat(void **xpp, size_t nelems, const float *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_putn_schar_float(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_putn_short_float(xpp, nelems, tp); + case NC_INT: + return ncx_putn_int_float(xpp, nelems, tp); + case NC_FLOAT: + return ncx_putn_float_float(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_putn_double_float(xpp, nelems, tp); + default: + assert("ncx_pad_putn_Ifloat invalid type" == 0); + } + return NC_EBADTYPE; +} + +static int +ncx_pad_getn_Ifloat(const void **xpp, size_t nelems, float *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_getn_schar_float(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_getn_short_float(xpp, nelems, tp); + case NC_INT: + return ncx_getn_int_float(xpp, nelems, tp); + case NC_FLOAT: + return ncx_getn_float_float(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_getn_double_float(xpp, nelems, tp); + default: + assert("ncx_pad_getn_Ifloat invalid type" == 0); + } + return NC_EBADTYPE; +} + + +static int +ncx_pad_putn_Idouble(void **xpp, size_t nelems, const double *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_putn_schar_double(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_putn_short_double(xpp, nelems, tp); + case NC_INT: + return ncx_putn_int_double(xpp, nelems, tp); + case NC_FLOAT: + return ncx_putn_float_double(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_putn_double_double(xpp, nelems, tp); + default: + assert("ncx_pad_putn_Idouble invalid type" == 0); + } + return NC_EBADTYPE; +} + +static int +ncx_pad_getn_Idouble(const void **xpp, size_t nelems, double *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_getn_schar_double(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_getn_short_double(xpp, nelems, tp); + case NC_INT: + return ncx_getn_int_double(xpp, nelems, tp); + case NC_FLOAT: + return ncx_getn_float_double(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_getn_double_double(xpp, nelems, tp); + default: + assert("ncx_pad_getn_Idouble invalid type" == 0); + } + return NC_EBADTYPE; +} + + +#ifdef IGNORE +static int +ncx_pad_putn_Ilong(void **xpp, size_t nelems, const long *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_putn_schar_long(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_putn_short_long(xpp, nelems, tp); + case NC_INT: + return ncx_putn_int_long(xpp, nelems, tp); + case NC_FLOAT: + return ncx_putn_float_long(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_putn_double_long(xpp, nelems, tp); + default: + assert("ncx_pad_putn_Ilong invalid type" == 0); + } + return NC_EBADTYPE; +} + +static int +ncx_pad_getn_Ilong(const void **xpp, size_t nelems, long *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_getn_schar_long(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_getn_short_long(xpp, nelems, tp); + case NC_INT: + return ncx_getn_int_long(xpp, nelems, tp); + case NC_FLOAT: + return ncx_getn_float_long(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_getn_double_long(xpp, nelems, tp); + default: + assert("ncx_pad_getn_Ilong invalid type" == 0); + } + return NC_EBADTYPE; +} + +#endif + +static int +ncx_pad_putn_Ilonglong(void **xpp, size_t nelems, const longlong *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_putn_schar_longlong(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_putn_short_longlong(xpp, nelems, tp); + case NC_INT: + return ncx_putn_int_longlong(xpp, nelems, tp); + case NC_FLOAT: + return ncx_putn_float_longlong(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_putn_double_longlong(xpp, nelems, tp); + default: + assert("ncx_pad_putn_Ilonglong invalid type" == 0); + } + return NC_EBADTYPE; +} + +static int +ncx_pad_getn_Ilonglong(const void **xpp, size_t nelems, longlong *tp, nc_type type) +{ + switch(type) { + case NC_CHAR: + return NC_ECHAR; + case NC_BYTE: + return ncx_pad_getn_schar_longlong(xpp, nelems, tp); + case NC_SHORT: + return ncx_pad_getn_short_longlong(xpp, nelems, tp); + case NC_INT: + return ncx_getn_int_longlong(xpp, nelems, tp); + case NC_FLOAT: + return ncx_getn_float_longlong(xpp, nelems, tp); + case NC_DOUBLE: + return ncx_getn_double_longlong(xpp, nelems, tp); + default: + assert("ncx_pad_getn_Ilonglong invalid type" == 0); + } + return NC_EBADTYPE; +} + + + +/* Common dispatcher for put cases */ +static int +dispatchput(void **xpp, size_t nelems, const void* tp, + nc_type atype, nc_type memtype) +{ + switch (memtype) { + case NC_CHAR: + return ncx_pad_putn_text(xpp,nelems, (char *)tp); + case NC_BYTE: + return ncx_pad_putn_Ischar(xpp, nelems, (schar*)tp, atype); + case NC_SHORT: + return ncx_pad_putn_Ishort(xpp, nelems, (short*)tp, atype); + case NC_INT: + return ncx_pad_putn_Iint(xpp, nelems, (int*)tp, atype); + case NC_FLOAT: + return ncx_pad_putn_Ifloat(xpp, nelems, (float*)tp, atype); + case NC_DOUBLE: + return ncx_pad_putn_Idouble(xpp, nelems, (double*)tp, atype); + case NC_UBYTE: /*Synthetic*/ + return ncx_pad_putn_Iuchar(xpp,nelems, (uchar *)tp, atype); + case NC_INT64: + return ncx_pad_putn_Ilonglong(xpp, nelems, (longlong*)tp, atype); + case NC_NAT: + return NC_EBADTYPE; + default: + break; + } + return NC_EBADTYPE; +} + +int +NC3_put_att( + int ncid, + int varid, + const char *name, + nc_type type, + size_t nelems, + const void *value, + nc_type memtype) +{ + int status; + NC *ncp; + NC_attrarray *ncap; + NC_attr **attrpp; + NC_attr *old = NULL; + NC_attr *attrp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_readonly(ncp)) + return NC_EPERM; + + ncap = NC_attrarray0(ncp, varid); + if(ncap == NULL) + return NC_ENOTVAR; + + status = nc_cktype(type); + if(status != NC_NOERR) + return status; + + if(memtype == NC_NAT) memtype = type; + + if(memtype != NC_CHAR && type == NC_CHAR) + return NC_ECHAR; + if(memtype == NC_CHAR && type != NC_CHAR) + return NC_ECHAR; + + /* cast needed for braindead systems with signed size_t */ + if((unsigned long) nelems > X_INT_MAX) /* backward compat */ + return NC_EINVAL; /* Invalid nelems */ + + if(nelems != 0 && value == NULL) + return NC_EINVAL; /* Null arg */ + + attrpp = NC_findattr(ncap, name); + + /* 4 cases: exists X indef */ + + if(attrpp != NULL) { /* name in use */ + if(!NC_indef(ncp)) { + const size_t xsz = ncx_len_NC_attrV(type, nelems); + attrp = *attrpp; /* convenience */ + + if(xsz > attrp->xsz) return NC_ENOTINDEFINE; + /* else, we can reuse existing without redef */ + + attrp->xsz = xsz; + attrp->type = type; + attrp->nelems = nelems; + + if(nelems != 0) { + void *xp = attrp->xvalue; + status = dispatchput(&xp, nelems, (const void*)value, type, memtype); + } + + set_NC_hdirty(ncp); + + if(NC_doHsync(ncp)) { + const int lstatus = NC_sync(ncp); + /* + * N.B.: potentially overrides NC_ERANGE + * set by ncx_pad_putn_I$1 + */ + if(lstatus != ENOERR) return lstatus; + } + + return status; + } + /* else, redefine using existing array slot */ + old = *attrpp; + } else { + if(!NC_indef(ncp)) return NC_ENOTINDEFINE; + + if(ncap->nelems >= NC_MAX_ATTRS) return NC_EMAXATTS; + } + + status = NC_check_name(name); + if(status != NC_NOERR) return status; + + attrp = new_NC_attr(name, type, nelems); + if(attrp == NULL) return NC_ENOMEM; + + if(nelems != 0) { + void *xp = attrp->xvalue; + status = dispatchput(&xp, nelems, (const void*)value, type, memtype); + } + + if(attrpp != NULL) { + assert(old != NULL); + *attrpp = attrp; + free_NC_attr(old); + } else { + const int lstatus = incr_NC_attrarray(ncap, attrp); + /* + * N.B.: potentially overrides NC_ERANGE + * set by ncx_pad_putn_I$1 + */ + if(lstatus != NC_NOERR) { + free_NC_attr(attrp); + return lstatus; + } + } + return status; +} + +int +NC3_get_att( + int ncid, + int varid, + const char *name, + void *value, + nc_type memtype) +{ + int status; + NC_attr *attrp; + const void *xp; + + status = NC_lookupattr(ncid, varid, name, &attrp); + if(status != NC_NOERR) return status; + + if(attrp->nelems == 0) return NC_NOERR; + + if(memtype == NC_NAT) memtype = attrp->type; + + if(memtype != NC_CHAR && attrp->type == NC_CHAR) + return NC_ECHAR; + if(memtype == NC_CHAR && attrp->type != NC_CHAR) + return NC_ECHAR; + + xp = attrp->xvalue; + switch (memtype) { + case NC_CHAR: + return ncx_pad_getn_text(&xp, attrp->nelems , (char *)value); + case NC_BYTE: + return ncx_pad_getn_Ischar(&xp,attrp->nelems,(schar*)value,attrp->type); + case NC_SHORT: + return ncx_pad_getn_Ishort(&xp,attrp->nelems,(short*)value,attrp->type); + case NC_INT: + return ncx_pad_getn_Iint(&xp,attrp->nelems,(int*)value,attrp->type); + case NC_FLOAT: + return ncx_pad_getn_Ifloat(&xp,attrp->nelems,(float*)value,attrp->type); + case NC_DOUBLE: + return ncx_pad_getn_Idouble(&xp,attrp->nelems,(double*)value,attrp->type); + case NC_INT64: + return ncx_pad_getn_Ilonglong(&xp,attrp->nelems,(longlong*)value,attrp->type); + case NC_UBYTE: /* Synthetic */ + return ncx_pad_getn_Iuchar(&xp, attrp->nelems , (uchar *)value, attrp->type); + case NC_NAT: + return NC_EBADTYPE; + default: + break; + } + status = NC_EBADTYPE; + return status; +} + diff --git a/extern/src_netcdf4/cache.c b/extern/src_netcdf4/cache.c new file mode 100644 index 0000000000000000000000000000000000000000..8fca3c320489e063de8aafe878161814a62a1628 --- /dev/null +++ b/extern/src_netcdf4/cache.c @@ -0,0 +1,369 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header$ + *********************************************************************/ +#include "ncdap3.h" +#include "dapodom.h" +#include "dapdump.h" + +static int iscacheableconstraint(DCEconstraint* con); + +/* Return 1 if we can reuse cached data to address + the current get_vara request; return 0 otherwise. + Target is in the constrained tree space. + Currently, if the target matches a cache that is not + a whole variable, then match is false. +*/ +int +iscached(NCDAPCOMMON* nccomm, CDFnode* target, NCcachenode** cachenodep) +{ + int i,j,found,index; + NCcache* cache; + NCcachenode* cachenode; + + found = 0; + if(target == NULL) goto done; + + /* Match the target variable against the prefetch, if any */ + /* Note that prefetches are always whole variable */ + cache = nccomm->cdf.cache; + cachenode = cache->prefetch; + if(cachenode!= NULL) { + for(found=0,i=0;ivars);i++) { + CDFnode* var = (CDFnode*)nclistget(cachenode->vars,i); + if(var == target) { + if(cachenodep) *cachenodep = cachenode; + found=1; + goto done; + } + } + } + + /*search other cache nodes starting at latest first */ + index = 0; + for(i=nclistlength(cache->nodes)-1;i>=0;i--) { + cachenode = (NCcachenode*)nclistget(cache->nodes,i); + /* We currently do not try to match constraints; + If the cachenode is constrained by more than + simple wholevariable projections, then skip it. + */ + if(!cachenode->wholevariable) continue; + for(found=0,j=0;jvars);j++) { + CDFnode* var = (CDFnode*)nclistget(cachenode->vars,j); + if(var == target) {found=1;index=i;break;} + } + if(found) break; + } + + if(found) { + ASSERT((cachenode != NULL)); + if(nclistlength(cache->nodes) > 1) { + /* Manage the cache nodes as LRU */ + nclistremove(cache->nodes,index); + nclistpush(cache->nodes,(ncelem)cachenode); + } + if(cachenodep) *cachenodep = cachenode; + } + +done: +#ifdef DEBUG +fprintf(stderr,"iscached: search: %s\n",makecdfpathstring3(target,".")); +if(found) + fprintf(stderr,"iscached: found: %s\n",dumpcachenode(cachenode)); +else + fprintf(stderr,"iscached: notfound\n"); +#endif + return found; +} + +/* Compute the set of prefetched data. + Notes: + 1. Even if caching is off, we will + still prefetch the small variables. + 2. All prefetches are whole variable fetches. + 3. If the data set is unconstrainable, we + will prefetch the whole thing +*/ +NCerror +prefetchdata3(NCDAPCOMMON* nccomm) +{ + int i,j; + NCerror ncstat = NC_NOERR; + NClist* allvars = nccomm->cdf.varnodes; + DCEconstraint* urlconstraint = nccomm->oc.dapconstraint; + NClist* vars = nclistnew(); + NCcachenode* cache = NULL; + DCEconstraint* newconstraint = NULL; + int isnc4 = FLAGSET(nccomm->controls,NCF_NC4); + + + if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) { + /* If we cannot constrain and caching is enabled, + then pull in everything */ + if(FLAGSET(nccomm->controls,NCF_CACHE)) { + for(i=0;icdf.cache->prefetch = NULL; + goto done; + } + } else { /* can do constraints */ + /* pull in those variables of sufficiently small size */ + for(i=0;inctype == NC_Sequence || dapinsequence(var)) continue; + } + + /* Compute the # of elements in the variable */ + for(j=0;jarray.dimset0);j++) { + CDFnode* dim = (CDFnode*)nclistget(var->array.dimset0,j); + nelems *= dim->dim.declsize; + } +if(SHOWFETCH) { +nclog(NCLOGDBG,"prefetch: %s=%lu",var->ncfullname,(unsigned long)nelems); +} + if(nelems <= nccomm->cdf.smallsizelimit) { + nclistpush(vars,(ncelem)var); +if(SHOWFETCH) { +nclog(NCLOGDBG,"prefetch: %s",var->ncfullname); +} + } + } + } + + /* If there are no vars, then do nothing */ + if(nclistlength(vars) == 0) { + nccomm->cdf.cache->prefetch = NULL; + goto done; + } + + /* Create a single constraint consisting of the projections for the variables; + each projection is whole variable. The selections are passed on as is. + */ + + newconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); + newconstraint->projections = nclistnew(); + newconstraint->selections = dceclonelist(urlconstraint->selections); + + for(i=0;iprojections,(ncelem)varprojection); + } +if(SHOWFETCH) { +char* s = dumpprojections(newconstraint->projections); +LOG1(NCLOGNOTE,"prefetch.final: %s",s); +nullfree(s); +} + ncstat = buildcachenode34(nccomm,newconstraint,vars,&cache,!isnc4); + newconstraint = NULL; /* buildcachenode34 takes control of newconstraint */ + if(ncstat) goto done; + cache->wholevariable = 1; /* All prefetches are whole variable */ + /* Make cache node be the prefetch node */ + nccomm->cdf.cache->prefetch = cache; +if(SHOWFETCH) { +LOG0(NCLOGNOTE,"prefetch.complete"); +} + +if(SHOWFETCH) { +char* s = NULL; +/* Log the set of prefetch variables */ +NCbytes* buf = ncbytesnew(); +ncbytescat(buf,"prefetch.vars: "); +for(i=0;ioc.conn; + OCobject ocroot = OCNULL; + CDFnode* dxdroot = NULL; + NCcachenode* cachenode = NULL; + char* ce = NULL; + + ce = buildconstraintstring3(constraint); + + ocstat = dap_fetch(nccomm,conn,ce,OCDATADDS,&ocroot); + nullfree(ce); + if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;} + + ncstat = buildcdftree34(nccomm,ocroot,OCDATA,&dxdroot); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* regrid */ + if(!FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) { + ncstat = regrid3(dxdroot,nccomm->cdf.ddsroot,constraint->projections); + if(ncstat) {THROWCHK(ncstat); goto done;} + } + + /* create the cache node */ + cachenode = createnccachenode(); + cachenode->prefetch = isprefetch; + cachenode->vars = nclistclone(varlist); + cachenode->datadds = dxdroot; + /* Give the constraint over to the cachenode */ + cachenode->constraint = constraint; + constraint = NULL; + cachenode->wholevariable = iscacheableconstraint(cachenode->constraint); + + /* save the root content*/ + cachenode->ocroot = ocroot; + cachenode->content = oc_data_new(conn); + ocstat = oc_data_root(conn,ocroot,cachenode->content); + if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;} + + /* capture the packet size */ + ocstat = oc_raw_xdrsize(conn,ocroot,&cachenode->xdrsize); + if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;} + +#ifdef DEBUG +fprintf(stderr,"buildcachenode: new cache node: %s\n", + dumpcachenode(cachenode)); +#endif + /* Insert into the cache. If not caching, then + remove any previous cache node + */ + if(!isprefetch) { + NCcache* cache = nccomm->cdf.cache; + if(cache->nodes == NULL) cache->nodes = nclistnew(); + /* remove cache nodes to get below the max cache size */ + while(cache->cachesize + cachenode->xdrsize > cache->cachelimit + && nclistlength(cache->nodes) > 0) { + NCcachenode* node = (NCcachenode*)nclistremove(cache->nodes,0); +#ifdef DEBUG +fprintf(stderr,"buildcachenode: purge cache node: %s\n", + dumpcachenode(cachenode)); +#endif + cache->cachesize -= node->xdrsize; + freenccachenode(nccomm,node); + } + /* Remove cache nodes to get below the max cache count */ + /* If not caching, then cachecount should be 0 */ + while(nclistlength(cache->nodes) > cache->cachecount) { + NCcachenode* node = (NCcachenode*)nclistremove(cache->nodes,0); +#ifdef DEBUG +fprintf(stderr,"buildcachenode: count purge cache node: %s\n", + dumpcachenode(node)); +#endif + cache->cachesize -= node->xdrsize; + freenccachenode(nccomm,node); + } + nclistpush(nccomm->cdf.cache->nodes,(ncelem)cachenode); + cache->cachesize += cachenode->xdrsize; + } + +#ifdef DEBUG +fprintf(stderr,"buildcachenode: %s\n",dumpcachenode(cachenode)); +#endif + +done: + if(constraint != NULL) dcefree((DCEnode*)constraint); + if(cachep) *cachep = cachenode; + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); + if(ncstat) { + freecdfroot34(dxdroot); + freenccachenode(nccomm,cachenode); + } + return THROW(ncstat); +} + +NCcachenode* +createnccachenode(void) +{ + NCcachenode* mem = (NCcachenode*)calloc(1,sizeof(NCcachenode)); + return mem; +} + +void +freenccachenode(NCDAPCOMMON* nccomm, NCcachenode* node) +{ + if(node == NULL) return; + oc_data_free(nccomm->oc.conn,node->content); + dcefree((DCEnode*)node->constraint); + freecdfroot34(node->datadds); + nclistfree(node->vars); + nullfree(node); +} + +void +freenccache(NCDAPCOMMON* nccomm, NCcache* cache) +{ + int i; + if(cache == NULL) return; + freenccachenode(nccomm,cache->prefetch); + for(i=0;inodes);i++) { + freenccachenode(nccomm,(NCcachenode*)nclistget(cache->nodes,i)); + } + nclistfree(cache->nodes); + nullfree(cache); +} + +NCcache* +createnccache(void) +{ + NCcache* c = (NCcache*)calloc(1,sizeof(NCcache)); + c->cachelimit = DFALTCACHELIMIT; + c->cachesize = 0; + c->nodes = nclistnew(); + c->cachecount = DFALTCACHECOUNT; + return c; +} + +static int +iscacheableprojection(DCEprojection* proj) +{ + int i,cacheable; + if(proj->discrim != CES_VAR) return 0; + cacheable = 1; /* assume so */ + for(i=0;ivar->segments);i++) { + DCEsegment* segment = (DCEsegment*)nclistget(proj->var->segments,i); + if(!iswholesegment(segment)) {cacheable = 0; break;} + } + return cacheable; +} + +static int +iscacheableconstraint(DCEconstraint* con) +{ + int i; + if(con == NULL) return 1; + if(con->selections != NULL && nclistlength(con->selections) > 0) + return 0; /* cant deal with selections */ + for(i=0;iprojections);i++) { + if(!iscacheableprojection((DCEprojection*)nclistget(con->projections,i))) + return 0; + } + return 1; +} diff --git a/extern/src_netcdf4/cdf3.c b/extern/src_netcdf4/cdf3.c new file mode 100644 index 0000000000000000000000000000000000000000..acb3c8979338f95e5ba3cf7717249ed28d771bbb --- /dev/null +++ b/extern/src_netcdf4/cdf3.c @@ -0,0 +1,770 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/cdf3.c,v 1.33 2009/12/03 03:42:37 dmh Exp $ + *********************************************************************/ + +#include "ncdap3.h" +#include "daputil.h" +#include "dapdump.h" + +CDFnode* v4node = NULL; + +/* Forward*/ +static NCerror sequencecheck3r(CDFnode* node, NClist* vars, CDFnode* topseq); +static NCerror regrid3r(CDFnode*, CDFnode*, NClist*); +static NCerror testregrid3(CDFnode* node, CDFnode* template, NClist*); +static CDFnode* makenewgrid3(CDFnode* node, CDFnode* template); +static NCerror regridinsert(CDFnode* newgrid, CDFnode* node); +static NCerror regridremove(CDFnode* newgrid, CDFnode* node); +static NCerror mapnodes3r(CDFnode*, CDFnode*, int depth); +static NCerror mapfcn(CDFnode* dstnode, CDFnode* srcnode); +static NCerror definedimsetplus3(NCDAPCOMMON* nccomm, CDFnode* node); +static NCerror definedimsetall3(NCDAPCOMMON* nccomm, CDFnode* node); + +/* Accumulate useful node sets */ +NCerror +computecdfnodesets3(NCDAPCOMMON* nccomm) +{ + unsigned int i; + NClist* varnodes = nclistnew(); + NClist* allnodes = nccomm->cdf.ddsroot->tree->nodes; + + if(nccomm->cdf.seqnodes == NULL) nccomm->cdf.seqnodes = nclistnew(); + if(nccomm->cdf.gridnodes == NULL) nccomm->cdf.gridnodes = nclistnew(); + nclistclear(nccomm->cdf.seqnodes); + nclistclear(nccomm->cdf.gridnodes); + + computevarnodes3(nccomm,allnodes,varnodes); + nclistfree(nccomm->cdf.varnodes); + nccomm->cdf.varnodes = varnodes; + + /* Now compute other sets of interest */ + for(i=0;ivisible) continue; + switch (node->nctype) { + case NC_Sequence: + nclistpush(nccomm->cdf.seqnodes,(ncelem)node); + break; + case NC_Grid: + nclistpush(nccomm->cdf.gridnodes,(ncelem)node); + break; + default: break; + } + } + return NC_NOERR; +} + +NCerror +computevarnodes3(NCDAPCOMMON* nccomm, NClist* allnodes, NClist* varnodes) +{ + unsigned int i,len; + NClist* allvarnodes = nclistnew(); + for(i=0;iocname)) { + char* newname = dap_repairname(node->ocname); + nullfree(node->ocname); + node->ocname = newname; + } + if(!node->visible) continue; + if(node->nctype == NC_Primitive) + nclistpush(allvarnodes,(ncelem)node); + } + /* Further process the variable nodes to get the final set */ + /* Use toplevel vars first */ + len = nclistlength(allvarnodes); + for(i=0;icontrols,NCF_NCDAP)) + nclistpush(varnodes,(ncelem)node); + nclistset(allvarnodes,i,(ncelem)NULL); + } + } + /*... then all others */ + for(i=0;icdf.gridnodes; + + for(i=0;itree->nodes);i++) { + CDFnode* node = (CDFnode*)nclistget(root->tree->nodes,i); + node->elided = 0; + if(node->nctype == NC_Grid || node->nctype == NC_Dataset) + node->elided = 1; + } + + /* ensure all variables have an initial full name defined */ + for(i=0;incfullname); + var->ncfullname = makecdfpathstring3(var,nccomm->cdf.separator); +#ifdef DEBUG2 +fprintf(stderr,"var names: %s %s %s\n", + var->ocname,var->ncbasename,var->ncfullname); +#endif + } + + /* unify all variables with same fullname and dimensions + basevar fields says: "for duplicate grid variables"; + when does this happen? + */ + if(FLAGSET(nccomm->controls,NCF_NC3)) { + for(i=0;iarray.basevar != NULL) + continue; /* already processed */ + if(strcmp(var->ncfullname,testnode->ncfullname) != 0) + match = 0; + else if(nclistlength(testnode->array.dimsetall) + != nclistlength(var->array.dimsetall)) + match = 0; + else for(d=0;darray.dimsetall);d++) { + CDFnode* vdim = (CDFnode*)nclistget(var->array.dimsetall,d); + CDFnode* tdim = (CDFnode*)nclistget(testnode->array.dimsetall,d); + if(vdim->dim.declsize != tdim->dim.declsize) { + match = 0; + break; + } + } + if(match) { + testnode->array.basevar = var; +fprintf(stderr,"basevar invoked: %s\n",var->ncfullname); + } + } + } + } + + /* Finally, verify unique names */ + for(i=0;iarray.basevar != NULL) continue; + for(j=0;jarray.basevar != NULL) continue; + if(strcmp(var1->ncfullname,var2->ncfullname)==0) { + PANIC1("duplicate var names: %s",var1->ncfullname); + } + } + } + return NC_NOERR; +} + + +/* locate and connect usable sequences and vars. +A sequence is usable iff: +1. it has a path from one of its subnodes to a leaf and that + path does not contain a sequence. +2. No parent container has dimensions. +*/ + +NCerror +sequencecheck3(NCDAPCOMMON* nccomm) +{ + (void)sequencecheck3r(nccomm->cdf.ddsroot,nccomm->cdf.varnodes,NULL); + return NC_NOERR; +} + + +static NCerror +sequencecheck3r(CDFnode* node, NClist* vars, CDFnode* topseq) +{ + unsigned int i; + NCerror err = NC_NOERR; + int ok = 0; + if(topseq == NULL && nclistlength(node->array.dimset0) > 0) { + err = NC_EINVAL; /* This container has dimensions, so no sequence within it + can be usable */ + } else if(node->nctype == NC_Sequence) { + /* Recursively walk the path for each subnode of this sequence node + looking for a path without any sequence */ + for(i=0;isubnodes);i++) { + CDFnode* sub = (CDFnode*)nclistget(node->subnodes,i); + err = sequencecheck3r(sub,vars,node); + if(err == NC_NOERR) ok = 1; /* there is at least 1 usable var below */ + } + if(topseq == NULL && ok == 1) { + /* this sequence is usable because it has scalar container + (by construction) and has a path to a leaf without an intermediate + sequence. */ + err = NC_NOERR; + node->usesequence = 1; + } else { + /* this sequence is unusable because it has no path + to a leaf without an intermediate sequence. */ + node->usesequence = 0; + err = NC_EINVAL; + } + } else if(nclistcontains(vars,(ncelem)node)) { + /* If we reach a leaf, then topseq is usable, so save it */ + node->array.sequence = topseq; + } else { /* Some kind of non-sequence container node with no dimensions */ + /* recursively compute usability */ + for(i=0;isubnodes);i++) { + CDFnode* sub = (CDFnode*)nclistget(node->subnodes,i); + err = sequencecheck3r(sub,vars,topseq); + if(err == NC_NOERR) ok = 1; + } + err = (ok?NC_NOERR:NC_EINVAL); + } + return err; +} + +/* +OPeNDAP is in the process of changing servers so that +partial grids are converted to structures. However, not all +servers do this: some elide the grid altogether, which can +lead to ambiguities. Handle this last case by attempting to +convert the elided case to look like the newer structure +case. [for some reason, this code has been difficult to get +right; I have rewritten 6 times and it probably is still not +right.] + +Input is +(1) the root of the dds that needs to be re-gridded +(2) the full datadds tree that defines where the grids are. +(3) the projections that were used to produce (1) from (2). +*/ + +NCerror +regrid3(CDFnode* ddsroot, CDFnode* template, NClist* projections) +{ + NCerror ncstat = NC_NOERR; + NClist* newgrids = nclistnew(); + + /* The current regrid assumes that the ddsroot tree + has missing grids compared to the template. + It is also assumed that order of the nodes + in the ddsroot is the same as in the template. + */ + if(ddsroot->tree->regridded) return NC_NOERR; + +#ifdef DEBUG +fprintf(stderr,"regrid: ddsroot=%s\n",dumptree(ddsroot)); +fprintf(stderr,"regrid: template=%s\n",dumptree(template)); +#endif + + +#ifdef PROJECTED + /* turn off the projection tag for all nodes */ + unprojected3(template->tree->nodes); + /* Set the projection flag for all paths of all nodes + that are referenced in the projections that produced ddsroot. + This includes containers and subnodes. If there are no + projections then mark all nodes + */ + projectall3(template->tree->nodes); +#endif + + if(simplenodematch34(ddsroot,template)) { + ncstat = regrid3r(ddsroot,template,newgrids); + ddsroot->tree->regridded = 1; + } else + ncstat = NC_EINVAL; + nclistfree(newgrids); + return ncstat; +} + +#ifdef PROJECTED +static void +unprojected3(NClist* nodes) +{ + int i; + for(i=0;iprojected = 0; + } +} + +static void +projectall3(NClist* nodes) +{ + int i; + for(i=0;iprojected = 1; + } +} + +static void +projection3r(CDFnode* node) +{ + int i; + NClist* path = nclistnew(); + collectnodepath3(node,path,!WITHDATASET); + for(i=0;iprojected == 0) +fprintf(stderr,"projection: %s\n",makesimplepathstring3(pathnode)); +#endif + pathnode->projected = 1; + } + /* Now tag everything below me */ + for(i=0;isubnodes);i++) { + CDFnode* subnode = (CDFnode*)nclistget(node->subnodes,i); + projection3r(subnode); + } + nclistfree(path); +} +#endif /*PROJECTED*/ + +/* +Add in virtual structure nodes so that +old style constrainted DDS and DATADDS +look like the new style with structures. +*/ +static NCerror +regrid3r(CDFnode* node, CDFnode* template, NClist* gridnodes) +{ + unsigned int inode, itemp; + NCerror ncstat = NC_NOERR; + + /* Try to match node's subnodes to a subset of the + template subnodes + */ +#ifdef DEBUG +fprintf(stderr,"regrid: matched: %s -> %s\n", +node->ocname,template->ocname); +#endif + for(inode=0;inodesubnodes);inode++) { + CDFnode* subnode = (CDFnode*)nclistget(node->subnodes,inode); + int match = 0; + for(itemp=0;itempsubnodes);itemp++) { + CDFnode* subtemp = (CDFnode*)nclistget(template->subnodes,itemp); + if( +#ifdef PROJECTED + subtemp->projected && +#endif + simplenodematch34(subnode,subtemp)) { + ncstat = regrid3r(subnode,subtemp,gridnodes); + if(ncstat != NC_NOERR) return THROW(ncstat); + match = 1; +#ifdef PROJECTED + subtemp->projected = 0; /*make sure we dont reuse this node*/ +#endif + break; + } + } + if(!match) { /* subnode has no match */ + /* ok, see if we can regrid */ + for(itemp=0;itempsubnodes);itemp++) { + CDFnode* subtemp = (CDFnode*)nclistget(template->subnodes,itemp); +#ifdef DEBUG +fprintf(stderr,"regrid: inside: %s.%s :: %s.%s\n", +node->ocname,subnode->ocname, +template->ocname,subtemp->ocname); +#endif + if(subtemp->nctype != NC_Grid) + continue; +#ifdef PROJECTED + if(!subtemp->projected) continue; +#endif + ncstat = testregrid3(subnode,subtemp,gridnodes); + if(ncstat == NC_NOERR) {match=1; break;} + } + if(!match) {/* really no match */ + ncstat = THROW(NC_EDDS); /* no match */ + } + } + } + return THROW(ncstat); +} + +/* See if this node can match a subnode of the template + as a grid, and if so, then rebuild the node graph. +*/ +static NCerror +testregrid3(CDFnode* node, CDFnode* template, NClist* gridnodes) +{ + int i,match; + NCerror ncstat = NC_NOERR; + ASSERT((template->nctype == NC_Grid)); + { /* try to match inside the grid */ + for(match=0,i=0;isubnodes);i++) { + CDFnode* gridelem = (CDFnode*)nclistget(template->subnodes,i); + if(!simplenodematch34(gridelem,node)) + continue; + ncstat = regrid3r(node,gridelem,gridnodes); + if(ncstat == NC_NOERR) { + /* create new grid node if not already created */ + CDFnode* newgrid = NULL; + match = 1; + for(i=0;itemplate == template) break; + newgrid = NULL; + } + if(newgrid == NULL) { + newgrid = makenewgrid3(node,template); + if(newgrid == NULL) {ncstat = NC_ENOMEM; goto done;} + /* Insert the grid into node's parent */ + regridinsert(newgrid,node); + nclistpush(gridnodes,(ncelem)newgrid); + nclistpush(node->root->tree->nodes,(ncelem)newgrid); + } + regridremove(newgrid, node); + node->container = newgrid; + nclistpush(newgrid->subnodes,(ncelem)node); + break; /* done with node */ + } + } + } + if(!match) ncstat = NC_EDDS; +done: + return ncstat; +} + + +static CDFnode* +makenewgrid3(CDFnode* node, CDFnode* template) +{ + CDFnode* newgrid; + newgrid = (CDFnode*)calloc(1,sizeof(CDFnode)); + if(newgrid == NULL) return NULL; + memset((void*)newgrid,0,sizeof(CDFnode)); + newgrid->virtual = 1; + newgrid->ocname = nulldup(template->ocname); + newgrid->ncbasename = nulldup(template->ncbasename); + newgrid->nctype = NC_Grid; + newgrid->subnodes = nclistnew(); + newgrid->container = node->container; + newgrid->template = template; + return newgrid; +} + +static NCerror +regridinsert(CDFnode* newgrid, CDFnode* node) +{ + int i; + CDFnode* parent; + /* Locate the index of the node in its current parent */ + parent = node->container; + for(i=0;isubnodes);i++) { + CDFnode* subnode = (CDFnode*)nclistget(parent->subnodes,i); + if(subnode == node) { + /* Insert the grid right before this node */ + nclistinsert(parent->subnodes,i,(ncelem)newgrid); + return NC_NOERR; + } + } + PANIC("regridinsert failure"); + return NC_EINVAL; +} + +static NCerror +regridremove(CDFnode* newgrid, CDFnode* node) +{ + int i; + CDFnode* parent; + /* Locate the index of the node in its current parent and remove */ + parent = node->container; + for(i=0;isubnodes);i++) { + CDFnode* subnode = (CDFnode*)nclistget(parent->subnodes,i); + if(subnode == node) { + nclistremove(parent->subnodes,i); + return NC_NOERR; + } + } + PANIC("regridremove failure"); + return NC_EINVAL; +} + +/** + +Make the constrained dds nodes (root) +point to the corresponding unconstrained +dds nodes (fullroot). + */ + +NCerror +mapnodes3(CDFnode* root, CDFnode* fullroot) +{ + NCerror ncstat = NC_NOERR; + ASSERT(root != NULL && fullroot != NULL); + if(!simplenodematch34(root,fullroot)) + {THROWCHK(ncstat=NC_EINVAL); goto done;} + /* clear out old associations*/ + unmap3(root); + ncstat = mapnodes3r(root,fullroot,0); +done: + return ncstat; +} + +static NCerror +mapnodes3r(CDFnode* connode, CDFnode* fullnode, int depth) +{ + unsigned int i,j; + NCerror ncstat = NC_NOERR; + + ASSERT((simplenodematch34(connode,fullnode))); + +#ifdef DEBUG +{ +char* path1 = makecdfpathstring3(fullnode,"."); +char * path2 = makecdfpathstring3(connode,"."); +fprintf(stderr,"mapnode: %s->%s\n",path1,path2); +nullfree(path1); nullfree(path2); +} +#endif + + /* Map node */ + mapfcn(connode,fullnode); + + /* Try to match connode subnodes against fullnode subnodes */ + ASSERT(nclistlength(connode->subnodes) <= nclistlength(fullnode->subnodes)); + + for(i=0;isubnodes);i++) { + CDFnode* consubnode = (CDFnode*)nclistget(connode->subnodes,i); + /* Search full subnodes for a matching subnode from con */ + for(j=0;jsubnodes);j++) { + CDFnode* fullsubnode = (CDFnode*)nclistget(fullnode->subnodes,j); + if(simplenodematch34(fullsubnode,consubnode)) { + ncstat = mapnodes3r(consubnode,fullsubnode,depth+1); + if(ncstat) goto done; + } + } + } +done: + return THROW(ncstat); +} + + +/* The specific actions of a map are defined + by this function. +*/ +static NCerror +mapfcn(CDFnode* dstnode, CDFnode* srcnode) +{ + /* Mark node as having been mapped */ + dstnode->visible = 1; + dstnode->basenode = srcnode; + return NC_NOERR; +} + +void +unmap3(CDFnode* root) +{ + unsigned int i; + CDFtree* tree = root->tree; + for(i=0;inodes);i++) { + CDFnode* node = (CDFnode*)nclistget(tree->nodes,i); + node->basenode = NULL; + node->visible = 0; + } +} + +/* +Move dimension data from basenodes to nodes +*/ + +NCerror +dimimprint3(NCDAPCOMMON* nccomm) +{ + NCerror ncstat = NC_NOERR; + NClist* allnodes; + int i,j; + CDFnode* basenode; + + allnodes = nccomm->cdf.ddsroot->tree->nodes; + for(i=0;ibasenode; + if(basenode == NULL) continue; + noderank = nclistlength(node->array.dimset0); + baserank = nclistlength(basenode->array.dimset0); + if(noderank == 0) continue; + ASSERT(noderank == baserank); +#ifdef DEBUG +fprintf(stderr,"dimimprint %s/%d -> %s/%d\n", + makecdfpathstring3(basenode,"."), + noderank, + makecdfpathstring3(node,"."), + baserank); +#endif + for(j=0;jarray.dimset0,j); + CDFnode* basedim = (CDFnode*)nclistget(basenode->array.dimset0,j); + dim->dim.declsize0 = basedim->dim.declsize; +#ifdef DEBUG +fprintf(stderr,"dimimprint: %d: %lu -> %lu\n",i,basedim->dim.declsize,dim->dim.declsize0); +#endif + } + } + return ncstat; +} + +static CDFnode* +clonedim(NCDAPCOMMON* nccomm, CDFnode* dim, CDFnode* var) +{ + CDFnode* clone; + clone = makecdfnode34(nccomm,dim->ocname,OC_Dimension, + OCNULL,dim->container); + /* Record its existence */ + nclistpush(dim->container->root->tree->nodes,(ncelem)clone); + clone->dim = dim->dim; /* copy most everything */ + clone->dim.dimflags |= CDFDIMCLONE; + clone->dim.array = var; + return clone; +} + +static NClist* +clonedimset3(NCDAPCOMMON* nccomm, NClist* dimset, CDFnode* var) +{ + NClist* result = nclistnew(); + int i; + for(i=0;iarray.dimsetplus == NULL); + if(node->array.dimset0 == NULL) + dimset = nclistnew(); + else { /* copy the dimset0 into dimset */ + dimset = nclistclone(node->array.dimset0); + } + /* Insert the sequence or string dims */ + if(node->array.stringdim != NULL) { + clone = node->array.stringdim; + nclistpush(dimset,(ncelem)clone); + } + if(node->array.seqdim != NULL) { + clone = node->array.seqdim; + nclistpush(dimset,(ncelem)clone); + } + node->array.dimsetplus = dimset; + return ncstat; +} + +/* Define the dimsetall list for a node */ +static NCerror +definedimsetall3(NCDAPCOMMON* nccomm, CDFnode* node) +{ + int i; + int ncstat = NC_NOERR; + NClist* dimsetall; + + ASSERT(node->array.dimsetall == NULL); + if(node->container != NULL) { + if(node->container->array.dimsetall == NULL) { +#ifdef DEBUG1 +fprintf(stderr,"dimsetall: recurse %s\n",node->container->ocname); +#endif + ncstat = definedimsetall3(nccomm,node->container); + if(ncstat != NC_NOERR) return ncstat; + } + /* We need to clone the parent dimensions because we will be assigning + indices vis-a-vis this variable */ + dimsetall = clonedimset3(nccomm,node->container->array.dimsetall,node); + } else + dimsetall = nclistnew(); + /* concat parentall and dimset;*/ + for(i=0;iarray.dimsetplus);i++) { + CDFnode* clone = (CDFnode*)nclistget(node->array.dimsetplus,i); + nclistpush(dimsetall,(ncelem)clone); + } + node->array.dimsetall = dimsetall; +#ifdef DEBUG1 +fprintf(stderr,"dimsetall: |%s|=%d\n",node->ocname,nclistlength(dimsetall)); +#endif + return ncstat; +} + +/* Define the dimsetplus and dimsetall lists for + all nodes with dimensions +*/ +NCerror +definedimsets3(NCDAPCOMMON* nccomm) +{ + int i; + int ncstat = NC_NOERR; + NClist* allnodes = nccomm->cdf.ddsroot->tree->nodes; + + for(i=0;inctype == NC_Dimension) continue; /* ignore */ + ASSERT((rankednode->array.dimsetplus == NULL)); + ncstat = definedimsetplus3(nccomm,rankednode); + if(ncstat != NC_NOERR) return ncstat; + } + for(i=0;inctype == NC_Dimension) continue; /*ignore*/ + ASSERT((rankednode->array.dimsetall == NULL)); + ASSERT((rankednode->array.dimsetplus != NULL)); + ncstat = definedimsetall3(nccomm,rankednode); + if(ncstat != NC_NOERR) return ncstat; + } + return NC_NOERR; +} + diff --git a/extern/src_netcdf4/ceconstraints.h b/extern/src_netcdf4/ceconstraints.h new file mode 100644 index 0000000000000000000000000000000000000000..8ec2c0da2dd9db8275eb734ee4ba5189a8f64c90 --- /dev/null +++ b/extern/src_netcdf4/ceconstraints.h @@ -0,0 +1,31 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + *********************************************************************/ +/* $Header$ */ + +#ifndef CECONSTRAINTS_H +#define CECONSTRAINTS_H + +#ifndef NC_MAX_VAR_DIMS +#define NC_MAX_VAR_DIMS 1024 +#endif + +typedef enum CEops { +CEO_NIL=0,CEO_EQ=1,CEO_NEQ=2,CEO_GE=3,CEO_GT=4,CEO_LT=5,CEO_LE=6,CEO_RE=7 +} CEops; + +/* Must match NCCops */ +#define OPSTRINGS {"?","=","!=",">=",">","<=","<","=~"} + +typedef enum CEsort { +CES_NIL=0, +CES_STR=8,CES_INT=9,CES_FLOAT=10, +CES_VAR=11,CES_FCN=12,CES_CONST=13, +CES_SELECT=14, CES_PROJECT=15, +CES_SEGMENT=16, CES_CONSTRAINT=17, +CES_VALUE=18, CES_SLICE=19 +} CEsort; + +#endif /*CECONSTRAINTS_H*/ + diff --git a/extern/src_netcdf4/common34.c b/extern/src_netcdf4/common34.c new file mode 100644 index 0000000000000000000000000000000000000000..c7159c4c812d81695085c03a7813b6fad19d14ba --- /dev/null +++ b/extern/src_netcdf4/common34.c @@ -0,0 +1,924 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/common34.c,v 1.29 2010/05/25 13:53:02 ed Exp $ + *********************************************************************/ + +#include "ncdap3.h" + +#ifdef HAVE_GETRLIMIT +# ifdef HAVE_SYS_RESOURCE_H +# include +# endif +# ifdef HAVE_SYS_RESOURCE_H +# include +# endif +#endif +#include "dapdump.h" + +extern CDFnode* v4node; + +/* Define the set of protocols known to be constrainable */ +static char* constrainableprotocols[] = {"http", "https",NULL}; +static NCerror buildcdftree34r(NCDAPCOMMON*,OCobject,CDFnode*,CDFtree*,CDFnode**); +static void defdimensions(OCobject, CDFnode*, NCDAPCOMMON*, CDFtree*); +static NCerror attachsubset34r(CDFnode*, CDFnode*); +static void free1cdfnode34(CDFnode* node); + +/* Define Procedures that are common to both + libncdap3 and libncdap4 +*/ + +/* Ensure every node has an initial base name defined and fullname */ +/* Exceptions: anonymous dimensions. */ +static NCerror +fix1node34(NCDAPCOMMON* nccomm, CDFnode* node) +{ + if(node->nctype == NC_Dimension && node->ocname == NULL) return NC_NOERR; + ASSERT((node->ocname != NULL)); + nullfree(node->ncbasename); + node->ncbasename = cdflegalname3(node->ocname); + if(node->ncbasename == NULL) return NC_ENOMEM; + nullfree(node->ncfullname); + node->ncfullname = makecdfpathstring3(node,nccomm->cdf.separator); + if(node->ncfullname == NULL) return NC_ENOMEM; + if(node->nctype == NC_Primitive) + node->externaltype = nctypeconvert(nccomm,node->etype); + return NC_NOERR; +} + +NCerror +fixnodes34(NCDAPCOMMON* nccomm, NClist* cdfnodes) +{ + int i; + for(i=0;isubnodes); + array = (CDFnode*)nclistget(grid->subnodes,0); + if(nccomm->controls.flags & (NCF_NC3)) { + /* Rename grid Array: variable, but leave its oc base name alone */ + nullfree(array->ncbasename); + array->ncbasename = nulldup(grid->ncbasename); + if(!array->ncbasename) return NC_ENOMEM; + } + /* validate and modify the grid structure */ + if((glen-1) != nclistlength(array->array.dimset0)) goto invalid; + for(i=1;iarray.dimset0,i-1); + CDFnode* map = (CDFnode*)nclistget(grid->subnodes,i); + CDFnode* mapdim; + /* map must have 1 dimension */ + if(nclistlength(map->array.dimset0) != 1) goto invalid; + /* and the map name must match the ith array dimension */ + if(arraydim->ocname != NULL && map->ocname != NULL + && strcmp(arraydim->ocname,map->ocname) != 0) + goto invalid; + /* and the map name must match its dim name (if any) */ + mapdim = (CDFnode*)nclistget(map->array.dimset0,0); + if(mapdim->ocname != NULL && map->ocname != NULL + && strcmp(mapdim->ocname,map->ocname) != 0) + goto invalid; + /* Add appropriate names for the anonymous dimensions */ + /* Do the map name first, so the array dim may inherit */ + if(mapdim->ocname == NULL) { + nullfree(mapdim->ncbasename); + mapdim->ocname = nulldup(map->ocname); + if(!mapdim->ocname) return NC_ENOMEM; + mapdim->ncbasename = cdflegalname3(mapdim->ocname); + if(!mapdim->ncbasename) return NC_ENOMEM; + } + if(arraydim->ocname == NULL) { + nullfree(arraydim->ncbasename); + arraydim->ocname = nulldup(map->ocname); + if(!arraydim->ocname) return NC_ENOMEM; + arraydim->ncbasename = cdflegalname3(arraydim->ocname); + if(!arraydim->ncbasename) return NC_ENOMEM; + } + if(FLAGSET(nccomm->controls,(NCF_NCDAP|NCF_NC3))) { + char tmp[3*NC_MAX_NAME]; + /* Add the grid name to the basename of the map */ + snprintf(tmp,sizeof(tmp),"%s%s%s",map->container->ncbasename, + nccomm->cdf.separator, + map->ncbasename); + nullfree(map->ncbasename); + map->ncbasename = nulldup(tmp); + if(!map->ncbasename) return NC_ENOMEM; + } + } + return NC_NOERR; +invalid: + return NC_EINVAL; /* mal-formed grid */ +} + +/** + * Given an anonymous dimension, compute the + * effective 0-based index wrt to the specified var. + * The result should mimic the libnc-dap indices. + */ + +static void +computedimindexanon3(CDFnode* dim, CDFnode* var) +{ + int i; + NClist* dimset = var->array.dimsetall; + for(i=0;idim.index1=i+1; + return; + } + } +} + +/* Replace dims in a list with their corresponding basedim */ +static void +replacedims(NClist* dims) +{ + int i; + for(i=0;idim.basedim; + if(basedim == NULL) continue; + nclistset(dims,i,(ncelem)basedim); + } +} + +/** + Two dimensions are equivalent if + 1. they have the same size + 2. neither are anonymous + 3. they ave the same names. + */ +static int +equivalentdim(CDFnode* basedim, CDFnode* dupdim) +{ + if(dupdim->dim.declsize != basedim->dim.declsize) return 0; + if(basedim->ocname == NULL && dupdim->ocname == NULL) return 0; + if(basedim->ocname == NULL || dupdim->ocname == NULL) return 0; + if(strcmp(dupdim->ocname,basedim->ocname) != 0) return 0; + return 1; +} + +/* + Provide short and/or unified names for dimensions. + This must mimic lib-ncdap, which is difficult. +*/ +NCerror +computecdfdimnames34(NCDAPCOMMON* nccomm) +{ + int i,j; + char tmp[NC_MAX_NAME*2]; + NClist* conflicts = nclistnew(); + NClist* varnodes = nccomm->cdf.varnodes; + NClist* alldims; + NClist* basedims; + + /* Collect all dimension nodes from dimsetall lists */ + + alldims = getalldims34(nccomm,0); + + /* Assign an index to all anonymous dimensions + vis-a-vis its containing variable + */ + for(i=0;iarray.dimsetall);j++) { + CDFnode* dim = (CDFnode*)nclistget(var->array.dimsetall,j); + if(dim->ocname != NULL) continue; /* not anonymous */ + computedimindexanon3(dim,var); + } + } + + /* Unify dimensions by defining one dimension as the "base" + dimension, and make all "equivalent" dimensions point to the + base dimension. + 1. Equivalent means: same size and both have identical non-null names. + 2. Dims with same name but different sizes will be handled separately + */ + for(i=0;idim.basedim != NULL) continue; /* already processed*/ + for(j=i+1;jdim.basedim != NULL) continue; /* already processed */ + if(!equivalentdim(basedim,dupdim)) + continue; + dupdim->dim.basedim = basedim; /* equate */ +#ifdef DEBUG1 +fprintf(stderr,"assign: %s/%s -> %s/%s\n", +basedim->dim.array->ocname,basedim->ocname, +dupdim->dim.array->ocname,dupdim->ocname +); +#endif + } + } + + /* Next case: same name and different sizes*/ + /* => rename second dim */ + + for(i=0;idim.basedim != NULL) continue; + /* Collect all conflicting dimensions */ + nclistclear(conflicts); + for(j=i+1;jdim.basedim != NULL) continue; + if(dim->ocname == NULL && basedim->ocname == NULL) continue; + if(dim->ocname == NULL || basedim->ocname == NULL) continue; + if(strcmp(dim->ocname,basedim->ocname)!=0) continue; + if(dim->dim.declsize == basedim->dim.declsize) continue; +#ifdef DEBUG2 +fprintf(stderr,"conflict: %s[%lu] %s[%lu]\n", + basedim->ncfullname,(unsigned long)basedim->dim.declsize, + dim->ncfullname,(unsigned long)dim->dim.declsize); +#endif + nclistpush(conflicts,(ncelem)dim); + } + /* Give all the conflicting dimensions an index */ + for(j=0;jdim.index1 = j+1; + } + } + nclistfree(conflicts); + + /* Replace all non-base dimensions with their base dimension */ + for(i=0;iarray.dimsetall); + replacedims(node->array.dimsetplus); + replacedims(node->array.dimset0); + } + + /* Collect list of all basedims */ + basedims = nclistnew(); + for(i=0;idim.basedim == NULL) { + if(!nclistcontains(basedims,(ncelem)dim)) { + nclistpush(basedims,(ncelem)dim); + } + } + } + + nccomm->cdf.dimnodes = basedims; + + /* cleanup */ + nclistfree(alldims); + + /* Assign ncbasenames and ncfullnames to base dimensions */ + for(i=0;idim.array; + if(dim->dim.basedim != NULL) PANIC1("nonbase basedim: %s\n",dim->ocname); + /* stringdim names are already assigned */ + if(dim->ocname == NULL) { /* anonymous: use the index to compute the name */ + snprintf(tmp,sizeof(tmp),"%s_%d", + var->ncfullname,dim->dim.index1-1); + nullfree(dim->ncbasename); + dim->ncbasename = cdflegalname3(tmp); + nullfree(dim->ncfullname); + dim->ncfullname = nulldup(dim->ncbasename); + } else { /* !anonymous; use index1 if defined */ + char* legalname = cdflegalname3(dim->ocname); + nullfree(dim->ncbasename); + if(dim->dim.index1 > 0) {/* need to fix conflicting names (see above) */ + char sindex[64]; + snprintf(sindex,sizeof(sindex),"_%d",dim->dim.index1); + dim->ncbasename = (char*)malloc(strlen(sindex)+strlen(legalname)+1); + if(dim->ncbasename == NULL) return NC_ENOMEM; + strcpy(dim->ncbasename,legalname); + strcat(dim->ncbasename,sindex); + nullfree(legalname); + } else {/* standard case */ + dim->ncbasename = legalname; + } + nullfree(dim->ncfullname); + dim->ncfullname = nulldup(dim->ncbasename); + } + } + + /* Verify unique and defined names for dimensions*/ + for(i=0;idim.basedim != NULL) PANIC1("nonbase basedim: %s\n",dim1->ncbasename); + if(dim1->ncbasename == NULL || dim1->ncfullname == NULL) + PANIC1("missing dim names: %s",dim1->ocname); + /* search backward so we can delete duplicates */ + for(j=nclistlength(basedims)-1;j>i;j--) { + CDFnode* dim2 = (CDFnode*)nclistget(basedims,j); + if(strcmp(dim1->ncfullname,dim2->ncfullname)==0) { + /* complain and suppress one of them */ + fprintf(stderr,"duplicate dim names: %s[%lu] %s[%lu]\n", + dim1->ncfullname,(unsigned long)dim1->dim.declsize, + dim2->ncfullname,(unsigned long)dim2->dim.declsize); + nclistremove(basedims,j); + } + } + } + +#ifdef DEBUG +for(i=0;incfullname,(long)dim->dim.declsize); + } +#endif + + return NC_NOERR; +} + +NCerror +makegetvar34(NCDAPCOMMON* nccomm, CDFnode* var, void* data, nc_type dsttype, Getvara** getvarp) +{ + Getvara* getvar; + NCerror ncstat = NC_NOERR; + + getvar = (Getvara*)calloc(1,sizeof(Getvara)); + MEMCHECK(getvar,NC_ENOMEM); + if(getvarp) *getvarp = getvar; + + getvar->target = var; + getvar->memory = data; + getvar->dsttype = dsttype; + getvar->target = var; + if(ncstat) nullfree(getvar); + return ncstat; +} + +int +constrainable34(NC_URI* durl) +{ + char** protocol = constrainableprotocols; + for(;*protocol;protocol++) { + if(strcmp(durl->protocol,*protocol)==0) + return 1; + } + return 0; +} + +CDFnode* +makecdfnode34(NCDAPCOMMON* nccomm, char* name, OCtype octype, + /*optional*/ OCobject ocnode, CDFnode* container) +{ + CDFnode* node; + assert(nccomm != NULL); + node = (CDFnode*)calloc(1,sizeof(CDFnode)); + if(node == NULL) return (CDFnode*)NULL; + + node->ocname = NULL; + if(name) { + size_t len = strlen(name); + if(len >= NC_MAX_NAME) len = NC_MAX_NAME-1; + node->ocname = (char*)malloc(len+1); + if(node->ocname == NULL) return NULL; + memcpy(node->ocname,name,len); + node->ocname[len] = '\0'; + } + node->nctype = octypetonc(octype); + node->ocnode = ocnode; + node->subnodes = nclistnew(); + node->container = container; + if(ocnode != OCNULL) { + oc_inq_primtype(nccomm->oc.conn,ocnode,&octype); + node->etype = octypetonc(octype); + } + return node; +} + +/* Given an OCnode tree, mimic it as a CDFnode tree; + Add DAS attributes if DAS is available. Accumulate set + of all nodes in preorder. +*/ +NCerror +buildcdftree34(NCDAPCOMMON* nccomm, OCobject ocroot, OCdxd occlass, CDFnode** cdfrootp) +{ + CDFnode* root = NULL; + CDFtree* tree = (CDFtree*)calloc(1,sizeof(CDFtree)); + NCerror err = NC_NOERR; + tree->ocroot = ocroot; + tree->nodes = nclistnew(); + tree->occlass = occlass; + tree->owner = nccomm; + + err = buildcdftree34r(nccomm,ocroot,NULL,tree,&root); + if(!err) { + if(occlass != OCDAS) + fixnodes34(nccomm,tree->nodes); + if(cdfrootp) *cdfrootp = root; + } + return err; +} + +static NCerror +buildcdftree34r(NCDAPCOMMON* nccomm, OCobject ocnode, CDFnode* container, + CDFtree* tree, CDFnode** cdfnodep) +{ + unsigned int i,ocrank,ocnsubnodes; + OCtype octype; + char* ocname = NULL; + NCerror ncerr = NC_NOERR; + CDFnode* cdfnode; + + oc_inq_class(nccomm->oc.conn,ocnode,&octype); + oc_inq_name(nccomm->oc.conn,ocnode,&ocname); + oc_inq_rank(nccomm->oc.conn,ocnode,&ocrank); + oc_inq_nsubnodes(nccomm->oc.conn,ocnode,&ocnsubnodes); + + switch (octype) { + case OC_Dataset: + case OC_Grid: + case OC_Structure: + case OC_Sequence: + case OC_Primitive: + cdfnode = makecdfnode34(nccomm,ocname,octype,ocnode,container); + nclistpush(tree->nodes,(ncelem)cdfnode); + if(tree->root == NULL) { + tree->root = cdfnode; + cdfnode->tree = tree; + } + break; + + case OC_Dimension: + default: PANIC1("buildcdftree: unexpect OC node type: %d",(int)octype); + + } + /* cross link */ + cdfnode->root = tree->root; + + if(ocrank > 0) defdimensions(ocnode,cdfnode,nccomm,tree); + for(i=0;ioc.conn,ocnode,i,&ocsubnode); + ncerr = buildcdftree34r(nccomm,ocsubnode,cdfnode,tree,&subnode); + if(ncerr) return ncerr; + nclistpush(cdfnode->subnodes,(ncelem)subnode); + } + nullfree(ocname); + if(cdfnodep) *cdfnodep = cdfnode; + return ncerr; +} + +static void +defdimensions(OCobject ocnode, CDFnode* cdfnode, NCDAPCOMMON* nccomm, CDFtree* tree) +{ + unsigned int i,ocrank; + + oc_inq_rank(nccomm->oc.conn,ocnode,&ocrank); + assert(ocrank > 0); + for(i=0;ioc.conn,ocnode,i,&ocdim); + oc_inq_dim(nccomm->oc.conn,ocdim,&declsize,&ocname); + + cdfdim = makecdfnode34(nccomm,ocname,OC_Dimension, + ocdim,cdfnode->container); + nullfree(ocname); + nclistpush(tree->nodes,(ncelem)cdfdim); + /* Initially, constrained and unconstrained are same */ + cdfdim->dim.declsize = declsize; + cdfdim->dim.array = cdfnode; + if(cdfnode->array.dimset0 == NULL) + cdfnode->array.dimset0 = nclistnew(); + nclistpush(cdfnode->array.dimset0,(ncelem)cdfdim); + } +} + +/* Note: this routine only applies some common + client parameters, other routines may apply + specific ones. +*/ + +NCerror +applyclientparams34(NCDAPCOMMON* nccomm) +{ + int i,len; + int dfaltstrlen = DEFAULTSTRINGLENGTH; + int dfaltseqlim = DEFAULTSEQLIMIT; + const char* value; + char tmpname[NC_MAX_NAME+32]; + char* pathstr; + OCconnection conn = nccomm->oc.conn; + unsigned long limit; + + ASSERT(nccomm->oc.url != NULL); + + nccomm->cdf.cache->cachelimit = DFALTCACHELIMIT; + value = oc_clientparam_get(conn,"cachelimit"); + limit = getlimitnumber(value); + if(limit > 0) nccomm->cdf.cache->cachelimit = limit; + + nccomm->cdf.fetchlimit = DFALTFETCHLIMIT; + value = oc_clientparam_get(conn,"fetchlimit"); + limit = getlimitnumber(value); + if(limit > 0) nccomm->cdf.fetchlimit = limit; + + nccomm->cdf.smallsizelimit = DFALTSMALLLIMIT; + value = oc_clientparam_get(conn,"smallsizelimit"); + limit = getlimitnumber(value); + if(limit > 0) nccomm->cdf.smallsizelimit = limit; + + nccomm->cdf.cache->cachecount = DFALTCACHECOUNT; +#ifdef HAVE_GETRLIMIT + { struct rlimit rl; + if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) { + nccomm->cdf.cache->cachecount = (size_t)(rl.rlim_cur / 2); + } + } +#endif + value = oc_clientparam_get(conn,"cachecount"); + limit = getlimitnumber(value); + if(limit > 0) nccomm->cdf.cache->cachecount = limit; + /* Ignore limit if not caching */ + if(!FLAGSET(nccomm->controls,NCF_CACHE)) + nccomm->cdf.cache->cachecount = 0; + + if(oc_clientparam_get(conn,"nolimit") != NULL) + dfaltseqlim = 0; + value = oc_clientparam_get(conn,"limit"); + if(value != NULL && strlen(value) != 0) { + if(sscanf(value,"%d",&len) && len > 0) dfaltseqlim = len; + } + nccomm->cdf.defaultsequencelimit = dfaltseqlim; + + /* allow embedded _ */ + value = oc_clientparam_get(conn,"stringlength"); + if(value != NULL && strlen(value) != 0) { + if(sscanf(value,"%d",&len) && len > 0) dfaltstrlen = len; + } + nccomm->cdf.defaultstringlength = dfaltstrlen; + + /* String dimension limits apply to variables */ + for(i=0;icdf.varnodes);i++) { + CDFnode* var = (CDFnode*)nclistget(nccomm->cdf.varnodes,i); + /* Define the client param stringlength for this variable*/ + var->maxstringlength = 0; /* => use global dfalt */ + strcpy(tmpname,"stringlength_"); + pathstr = makeocpathstring3(conn,var->ocnode,"."); + strcat(tmpname,pathstr); + nullfree(pathstr); + value = oc_clientparam_get(conn,tmpname); + if(value != NULL && strlen(value) != 0) { + if(sscanf(value,"%d",&len) && len > 0) var->maxstringlength = len; + } + } + /* Sequence limits apply to sequences */ + for(i=0;icdf.ddsroot->tree->nodes);i++) { + CDFnode* var = (CDFnode*)nclistget(nccomm->cdf.ddsroot->tree->nodes,i); + if(var->nctype != NC_Sequence) continue; + var->sequencelimit = dfaltseqlim; + strcpy(tmpname,"nolimit_"); + pathstr = makeocpathstring3(conn,var->ocnode,"."); + strcat(tmpname,pathstr); + if(oc_clientparam_get(conn,tmpname) != NULL) + var->sequencelimit = 0; + strcpy(tmpname,"limit_"); + strcat(tmpname,pathstr); + value = oc_clientparam_get(conn,tmpname); + if(value != NULL && strlen(value) != 0) { + if(sscanf(value,"%d",&len) && len > 0) + var->sequencelimit = len; + } + nullfree(pathstr); + } + + /* test for the appropriate fetch flags */ + value = oc_clientparam_get(conn,"fetch"); + if(value != NULL && strlen(value) > 0) { + if(value[0] == 'd' || value[0] == 'D') { + SETFLAG(nccomm->controls,NCF_ONDISK); + } + } + + /* test for the force-whole-var flag */ + value = oc_clientparam_get(conn,"wholevar"); + if(value != NULL) { + SETFLAG(nccomm->controls,NCF_WHOLEVAR); + } + + return NC_NOERR; +} + +void +freecdfroot34(CDFnode* root) +{ + int i; + CDFtree* tree; + NCDAPCOMMON* nccomm; + if(root == NULL) return; + tree = root->tree; + ASSERT((tree != NULL)); + /* Explicitly FREE the ocroot */ + nccomm = tree->owner; + oc_root_free(nccomm->oc.conn,tree->ocroot); + tree->ocroot = OCNULL; + for(i=0;inodes);i++) { + CDFnode* node = (CDFnode*)nclistget(tree->nodes,i); + free1cdfnode34(node); + } + nclistfree(tree->nodes); + nullfree(tree); +} + +/* Free up a single node, but not any + nodes it points to. +*/ +static void +free1cdfnode34(CDFnode* node) +{ + unsigned int j,k; + if(node == NULL) return; + nullfree(node->ocname); + nullfree(node->ncbasename); + nullfree(node->ncfullname); + if(node->attributes != NULL) { + for(j=0;jattributes);j++) { + NCattribute* att = (NCattribute*)nclistget(node->attributes,j); + nullfree(att->name); + for(k=0;kvalues);k++) + nullfree((char*)nclistget(att->values,k)); + nclistfree(att->values); + nullfree(att); + } + } + nullfree(node->dodsspecial.dimname); + nclistfree(node->subnodes); + nclistfree(node->attributes); + nclistfree(node->array.dimsetplus); + nclistfree(node->array.dimsetall); + nclistfree(node->array.dimset0); + + /* Clean up the ncdap4 fields also */ + nullfree(node->typename); + nullfree(node->vlenname); + nullfree(node); +} + +/* Return true if node and node1 appear to refer to the same thing; + takes grid->structure changes into account. +*/ +int +nodematch34(CDFnode* node1, CDFnode* node2) +{ + return simplenodematch34(node1,node2); +} + +int +simplenodematch34(CDFnode* node1, CDFnode* node2) +{ + if(node1 == NULL) return (node2==NULL); + if(node2 == NULL) return 0; + if(node1->nctype != node2->nctype) { + /* Check for Grid->Structure match */ + if((node1->nctype == NC_Structure && node2->nctype == NC_Grid) + || (node2->nctype == NC_Structure && node1->nctype == NC_Grid)){ + if(node1->ocname == NULL || node2->ocname == NULL + || strcmp(node1->ocname,node2->ocname) !=0) return 0; + } else return 0; + } + /* Add hack to address the screwed up Columbia server */ + if(node1->nctype == NC_Dataset) return 1; + if(node1->nctype == NC_Primitive + && node1->etype != node2->etype) return 0; + if(node1->ocname != NULL && node2->ocname != NULL + && strcmp(node1->ocname,node2->ocname)!=0) return 0; + if(nclistlength(node1->array.dimset0) + != nclistlength(node2->array.dimset0)) return 0; + return 1; +} + +/* +Given DDS node, locate the node +in a DATADDS that matches the DDS node. +Return NULL if no node found +*/ + +void +unattach34(CDFnode* root) +{ + unsigned int i; + CDFtree* xtree = root->tree; + for(i=0;inodes);i++) { + CDFnode* xnode = (CDFnode*)nclistget(xtree->nodes,i); + /* break bi-directional link */ + xnode->attachment = NULL; + } +} + +static void +setattach(CDFnode* target, CDFnode* template) +{ + target->attachment = template; + template->attachment = target; + /* Transfer important information */ + target->externaltype = template->externaltype; + target->maxstringlength = template->maxstringlength; + target->sequencelimit = template->sequencelimit; + target->ncid = template->ncid; + /* also transfer libncdap4 info */ + target->typeid = template->typeid; + target->typesize = template->typesize; +} + +static NCerror +attachdims34(CDFnode* xnode, CDFnode* template) +{ + unsigned int i; + for(i=0;iarray.dimsetall);i++) { + CDFnode* xdim = (CDFnode*)nclistget(xnode->array.dimsetall,i); + CDFnode* tdim = (CDFnode*)nclistget(template->array.dimsetall,i); + setattach(xdim,tdim); +#ifdef DEBUG2 +fprintf(stderr,"attachdim: %s->%s\n",xdim->ocname,tdim->ocname); +#endif + } + return NC_NOERR; +} + +/* +Match a DATADDS node to a DDS node. +It is assumed that both trees have been regridded if necessary. +*/ + +static NCerror +attach34r(CDFnode* xnode, NClist* templatepath, int depth) +{ + unsigned int i,plen,lastnode,gridable; + NCerror ncstat = NC_NOERR; + CDFnode* templatepathnode; + CDFnode* templatepathnext; + + plen = nclistlength(templatepath); + if(depth >= plen) {THROWCHK(ncstat=NC_EINVAL); goto done;} + + lastnode = (depth == (plen-1)); + templatepathnode = (CDFnode*)nclistget(templatepath,depth); + ASSERT((simplenodematch34(xnode,templatepathnode))); + setattach(xnode,templatepathnode); +#ifdef DEBUG2 +fprintf(stderr,"attachnode: %s->%s\n",xnode->ocname,templatepathnode->ocname); +#endif + + if(lastnode) goto done; /* We have the match and are done */ + + if(nclistlength(xnode->array.dimsetall) > 0) { + attachdims34(xnode,templatepathnode); + } + + ASSERT((!lastnode)); + templatepathnext = (CDFnode*)nclistget(templatepath,depth+1); + + gridable = (templatepathnext->nctype == NC_Grid && depth+2 < plen); + + /* Try to find an xnode subnode that matches templatepathnext */ + for(i=0;isubnodes);i++) { + CDFnode* xsubnode = (CDFnode*)nclistget(xnode->subnodes,i); + if(simplenodematch34(xsubnode,templatepathnext)) { + ncstat = attach34r(xsubnode,templatepath,depth+1); + if(ncstat) goto done; + } else if(gridable && xsubnode->nctype == NC_Primitive) { + /* grids may or may not appear in the datadds; + try to match the xnode subnodes against the parts of the grid + */ + CDFnode* templatepathnext2 = (CDFnode*)nclistget(templatepath,depth+2); + if(simplenodematch34(xsubnode,templatepathnext2)) { + ncstat = attach34r(xsubnode,templatepath,depth+2); + if(ncstat) goto done; + } + } + } +done: + return THROW(ncstat); +} + +NCerror +attach34(CDFnode* xroot, CDFnode* template) +{ + NCerror ncstat = NC_NOERR; + NClist* templatepath = nclistnew(); + CDFnode* ddsroot = template->root; + + if(xroot->attachment) unattach34(xroot); + if(ddsroot != NULL && ddsroot->attachment) unattach34(ddsroot); + if(!simplenodematch34(xroot,ddsroot)) + {THROWCHK(ncstat=NC_EINVAL); goto done;} + collectnodepath3(template,templatepath,WITHDATASET); + ncstat = attach34r(xroot,templatepath,0); +done: + nclistfree(templatepath); + return ncstat; +} + +/* +Match nodes in template tree to nodes in target tree; +template tree is typically a structural superset of target tree. +WARNING: Dimensions are not attached +*/ + +NCerror +attachsubset34(CDFnode* target, CDFnode* template) +{ + NCerror ncstat = NC_NOERR; + + if(template == NULL) {THROWCHK(ncstat=NC_NOERR); goto done;} + if(!nodematch34(target,template)) {THROWCHK(ncstat=NC_EINVAL); goto done;} +#ifdef DEBUG2 +fprintf(stderr,"attachsubset: target=%s\n",dumptree(target)); +fprintf(stderr,"attachsubset: template=%s\n",dumptree(template)); +#endif + ncstat = attachsubset34r(target,template); +done: + return ncstat; +} + +static NCerror +attachsubset34r(CDFnode* target, CDFnode* template) +{ + unsigned int i; + NCerror ncstat = NC_NOERR; + int fieldindex; + +#ifdef DEBUG2 +fprintf(stderr,"attachsubsetr: attach: target=%s template=%s\n", + target->ocname,template->ocname); +#endif + + ASSERT((nodematch34(target,template))); + setattach(target,template); + + /* Try to match target subnodes against template subnodes */ + + fieldindex = 0; + for(fieldindex=0,i=0;isubnodes) && fieldindexsubnodes);i++) { + CDFnode* templatesubnode = (CDFnode*)nclistget(template->subnodes,i); + CDFnode* targetsubnode = (CDFnode*)nclistget(target->subnodes,fieldindex); + if(nodematch34(targetsubnode,templatesubnode)) { +#ifdef DEBUG2 +fprintf(stderr,"attachsubsetr: match: %s :: %s\n",targetsubnode->ocname,templatesubnode->ocname); +#endif + ncstat = attachsubset34r(targetsubnode,templatesubnode); + if(ncstat) goto done; + fieldindex++; + } + } +done: + return THROW(ncstat); +} + +static void +getalldims34a(NClist* dimset, NClist* alldims) +{ + int i; + for(i=0;incfullname,(unsigned long)dim->dim.declsize); +#endif + nclistpush(alldims,(ncelem)dim); + } + } +} + +/* Accumulate a set of all the known dimensions + vis-a-vis defined variables +*/ +NClist* +getalldims34(NCDAPCOMMON* nccomm, int visibleonly) +{ + int i; + NClist* alldims = nclistnew(); + NClist* varnodes = nccomm->cdf.varnodes; + + /* get bag of all dimensions */ + for(i=0;ivisible) { + getalldims34a(node->array.dimsetall,alldims); + } + } + return alldims; +} diff --git a/extern/src_netcdf4/config.h b/extern/src_netcdf4/config.h new file mode 100644 index 0000000000000000000000000000000000000000..83e8a4e249dff98210b8a0a26a96a595790529e7 --- /dev/null +++ b/extern/src_netcdf4/config.h @@ -0,0 +1,474 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* if true, build RPC Client and Server */ +/* #undef BUILD_RPC */ + +/* default file chunk cache nelems. */ +#define CHUNK_CACHE_NELEMS 1009 + +/* default file chunk cache preemption policy. */ +#define CHUNK_CACHE_PREEMPTION 0.75 + +/* default file chunk cache size in bytes. */ +#define CHUNK_CACHE_SIZE 4194304 + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* num chunks in default per-var chunk cache. */ +#define DEFAULT_CHUNKS_IN_CACHE 10 + +/* default chunk size in bytes */ +#define DEFAULT_CHUNK_SIZE 4194304 + +/* set this only when building a DLL under MinGW */ +/* #undef DLL_EXPORT */ + +/* set this only when building a DLL under MinGW */ +/* #undef DLL_NETCDF */ + +/* if true, build DAP Client */ +#define ENABLE_DAP 1 + +/* if true, enable DAP group names */ +#define ENABLE_DAP_GROUPS 1 + +/* if true, do remote tests */ +#define ENABLE_DAP_REMOTE_TESTS 1 + +/* if true, run extra tests which may not work yet */ +/* #undef EXTRA_TESTS */ + +/* use HDF5 1.6 API */ +#define H5_USE_16_API 1 + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_CTYPE_H 1 + +/* Is CURLOPT_KEYPASSWD defined */ +#define HAVE_CURLOPT_KEYPASSWD 1 + +/* Define to 1 if you have the declaration of `isfinite', and to 0 if you + don't. */ +#define HAVE_DECL_ISFINITE 1 + +/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. + */ +#define HAVE_DECL_ISINF 1 + +/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. + */ +#define HAVE_DECL_ISNAN 1 + +/* Define to 1 if you have the declaration of `signbit', and to 0 if you + don't. */ +#define HAVE_DECL_SIGNBIT 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +/* #undef HAVE_DOPRNT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `fsync' function. */ +#define HAVE_FSYNC 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define to 1 if you have the `getrlimit' function. */ +#define HAVE_GETRLIMIT 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `H5Pget_fapl_mpio' function. */ +#define HAVE_H5PGET_FAPL_MPIO 1 + +/* Define to 1 if you have the `H5Pget_fapl_mpiposix' function. */ +#define HAVE_H5PGET_FAPL_MPIPOSIX 1 + +/* Define to 1 if you have the `H5Pset_deflate' function. */ +#define HAVE_H5PSET_DEFLATE 1 + +/* Define to 1 if you have the `H5Z_SZIP' function. */ +/* #undef HAVE_H5Z_SZIP */ + +/* Define to 1 if you have the header file. */ +#define HAVE_HDF5_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `df' library (-ldf). */ +/* #undef HAVE_LIBDF */ + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the `mfhdf' library (-lmfhdf). */ +/* #undef HAVE_LIBMFHDF */ + +/* Define to 1 if you have the `pnetcdf' library (-lpnetcdf). */ +/* #undef HAVE_LIBPNETCDF */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if the system has the type `longlong'. */ +/* #undef HAVE_LONGLONG */ + +/* Define to 1 if the system has the type `long long int'. */ +#define HAVE_LONG_LONG_INT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MFHDF_H */ + +/* Define to 1 if you have the `mkstemp' function. */ +#define HAVE_MKSTEMP 1 + +/* Define to 1 if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define to 1 if you have the `MPI_Comm_f2c' function. */ +#define HAVE_MPI_COMM_F2C 1 + +/* Define to 1 if you have the `mremap' function. */ +#define HAVE_MREMAP 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#define HAVE_PTRDIFF_T 1 + +/* Define to 1 if you have the `rand' function. */ +#define HAVE_RAND 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if the system has the type `ssize_t'. */ +#define HAVE_SSIZE_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define to 1 if stdbool.h conforms to C99. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strcat' function. */ +#define HAVE_STRCAT 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strcpy' function. */ +#define HAVE_STRCPY 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +/* #undef HAVE_STRLCAT */ + +/* Define to 1 if you have the `strrchr' function. */ +#define HAVE_STRRCHR 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtod' function. */ +#define HAVE_STRTOD 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* Define to 1 if you have the `strtoull' function. */ +#define HAVE_STRTOULL 1 + +/* Define to 1 if `st_blksize' is member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 + +/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use + `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */ +#define HAVE_ST_BLKSIZE 1 + +/* Define to 1 if you have the `sysconf' function. */ +#define HAVE_SYSCONF 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if the system has the type `uchar'. */ +/* #undef HAVE_UCHAR */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if the system has the type `unsigned long long int'. */ +#define HAVE_UNSIGNED_LONG_LONG_INT 1 + +/* Define to 1 if you have the `vprintf' function. */ +#define HAVE_VPRINTF 1 + +/* Define to 1 if the system has the type `_Bool'. */ +#define HAVE__BOOL 1 + +/* do large file tests */ +/* #undef LARGE_FILE_TESTS */ + +/* If true, turn on logging. */ +/* #undef LOGGING */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* max size of the default per-var chunk cache. */ +#define MAX_DEFAULT_CACHE_SIZE 67108864 + +/* min blocksize for posixio. */ +#define NCIO_MINBLOCKSIZE 256 + +/* no IEEE float on this platform */ +/* #undef NO_IEEE_FLOAT */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* do not build the netCDF version 2 API */ +/* #undef NO_NETCDF_2 */ + +/* no stdlib.h */ +/* #undef NO_STDLIB_H */ + +/* no sys_types.h */ +/* #undef NO_SYS_TYPES_H */ + +/* Name of package */ +#define PACKAGE "netcdf" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "support-netcdf@unidata.ucar.edu" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "netCDF" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "netCDF 4.2.1.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "netcdf" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "4.2.1.1" + +/* The size of `double', as computed by sizeof. */ +#define SIZEOF_DOUBLE 8 + +/* The size of `float', as computed by sizeof. */ +#define SIZEOF_FLOAT 4 + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 8 + +/* The size of `long long', as computed by sizeof. */ +#define SIZEOF_LONG_LONG 8 + +/* The size of `off_t', as computed by sizeof. */ +#define SIZEOF_OFF_T 8 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 8 + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Place to put very large netCDF test files. */ +#define TEMP_LARGE "." + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* if true, build CDMREMOTE Client */ +/* #undef USE_CDMREMOTE */ + +/* if true, build DAP Client */ +#define USE_DAP 1 + +/* if true, include NC_DISKLESS code */ +#define USE_DISKLESS 1 + +/* set this to use extreme numbers in tests */ +#define USE_EXTREME_NUMBERS 1 + +/* if true, use ffio instead of posixio */ +/* #undef USE_FFIO */ + +/* if true, include experimental fsync code */ +#define USE_FSYNC 1 + +/* if true, use HDF4 too */ +/* #undef USE_HDF4 */ + +/* If true, use use wget to fetch some sample HDF4 data, and then test against + it. */ +/* #undef USE_HDF4_FILE_TESTS */ + +/* if true, use mmap for in-memory files */ +/* #undef USE_MMAP */ + +/* if true, build netCDF-4 */ +#define USE_NETCDF4 1 + +/* if true, parallel netCDF-4 is in use */ +#define USE_PARALLEL 1 + +/* if true, compile in parallel netCDF-4 based on MPI/IO */ +#define USE_PARALLEL_MPIO 1 + +/* if true, compile in parallel netCDF-4 based on MPI/POSIX */ +#define USE_PARALLEL_POSIX 1 + +/* if true, parallel netCDF is used */ +/* #undef USE_PNETCDF */ + +/* if true, compile in szip compression in netCDF-4 variables */ +/* #undef USE_SZIP */ + +/* if true, compile in zlib compression in netCDF-4 variables */ +#define USE_ZLIB 1 + +/* Version number of package */ +#define VERSION "4.2.1.1" + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to 1 if type `char' is unsigned and you are not using gcc. */ +#ifndef __CHAR_UNSIGNED__ +/* # undef __CHAR_UNSIGNED__ */ +#endif + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +#include "ncconfigure.h" diff --git a/extern/src_netcdf4/constraints3.c b/extern/src_netcdf4/constraints3.c new file mode 100644 index 0000000000000000000000000000000000000000..f1778a7e0637b79e5a68bd325ba09e99135d83d7 --- /dev/null +++ b/extern/src_netcdf4/constraints3.c @@ -0,0 +1,853 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdce3/constraints3.c,v 1.40 2010/05/27 21:34:07 dmh Exp $ + *********************************************************************/ + +#include "ncdap3.h" +#include "dapodom.h" +#include "dapdebug.h" +#include "dapdump.h" +#include "dceparselex.h" + +static void completesegments3(NClist* fullpath, NClist* segments); +static NCerror qualifyprojectionnames3(DCEprojection* proj); +static NCerror qualifyprojectionsizes3(DCEprojection* proj); +static NCerror matchpartialname3(NClist* nodes, NClist* segments, CDFnode** nodep); +static int matchsuffix3(NClist* matchpath, NClist* segments); +static int iscontainer(CDFnode* node); +static DCEprojection* projectify(CDFnode* field, DCEprojection* container); +static int slicematch(NClist* seglist1, NClist* seglist2); + +/* Parse incoming url constraints, if any, + to check for syntactic correctness */ +NCerror +parsedapconstraints(NCDAPCOMMON* dapcomm, char* constraints, + DCEconstraint* dceconstraint) +{ + NCerror ncstat = NC_NOERR; + char* errmsg; + + ASSERT(dceconstraint != NULL); + nclistclear(dceconstraint->projections); + nclistclear(dceconstraint->selections); + + ncstat = dapceparse(constraints,dceconstraint,&errmsg); + if(ncstat) { + nclog(NCLOGWARN,"DCE constraint parse failure: %s",errmsg); + nullfree(errmsg); + nclistclear(dceconstraint->projections); + nclistclear(dceconstraint->selections); + } + return ncstat; +} + +/* Map constraint paths to CDFnode paths in specified tree and fill + in the declsizes. + The difficulty is that suffix paths are legal. +*/ + +NCerror +mapconstraints3(DCEconstraint* constraint, + CDFnode* root) +{ + int i; + NCerror ncstat = NC_NOERR; + NClist* nodes = root->tree->nodes; + NClist* dceprojections = constraint->projections; +#if 0 + NClist* dceselections = constraint->selections; +#endif + + /* Convert the projection paths to leaves in the dds tree */ + for(i=0;idiscrim != CES_VAR) continue; /* ignore functions*/ + ncstat = matchpartialname3(nodes,proj->var->segments, + (CDFnode**)&proj->var->annotation); + if(ncstat) goto done; + } + +#ifdef DEBUG +fprintf(stderr,"mapconstraint.projections: %s\n", + dumpprojections(dceprojections)); +#endif + +done: + return THROW(ncstat); +} + + +/* Fill in: + 1. projection segments + 2. projection segment slices declsize + 3. selection path +*/ +NCerror +qualifyconstraints3(DCEconstraint* constraint) +{ + NCerror ncstat = NC_NOERR; + int i; +#ifdef DEBUG +fprintf(stderr,"qualifyconstraints.before: %s\n", + dumpconstraint(constraint)); +#endif + if(constraint != NULL) { + for(i=0;iprojections);i++) { + DCEprojection* p = (DCEprojection*)nclistget(constraint->projections,i); + ncstat = qualifyprojectionnames3(p); + ncstat = qualifyprojectionsizes3(p); + } + } +#ifdef DEBUG +fprintf(stderr,"qualifyconstraints.after: %s\n", + dumpconstraint(constraint)); +#endif + return ncstat; +} + +/* convert all names in projections in paths to be fully qualified + by adding prefix segment objects. +*/ +static NCerror +qualifyprojectionnames3(DCEprojection* proj) +{ + NCerror ncstat = NC_NOERR; + NClist* fullpath = nclistnew(); + + ASSERT((proj->discrim == CES_VAR + && proj->var->annotation != NULL + && ((CDFnode*)proj->var->annotation)->ocnode != OCNULL)); + collectnodepath3((CDFnode*)proj->var->annotation,fullpath,!WITHDATASET); +#ifdef DEBUG +fprintf(stderr,"qualify: %s -> ", + dumpprojection(proj)); +#endif + /* Now add path nodes to create full path */ + completesegments3(fullpath,proj->var->segments); + +#ifdef DEBUG +fprintf(stderr,"%s\n", + dumpprojection(proj)); +#endif + nclistfree(fullpath); + return ncstat; +} + +/* Make sure that the slice declsizes are all defined for this projection */ +static NCerror +qualifyprojectionsizes3(DCEprojection* proj) +{ + int i,j; + ASSERT(proj->discrim == CES_VAR); +#ifdef DEBUG +fprintf(stderr,"qualifyprojectionsizes.before: %s\n", + dumpprojection(proj)); +#endif + for(i=0;ivar->segments);i++) { + DCEsegment* seg = (DCEsegment*)nclistget(proj->var->segments,i); + NClist* dimset = NULL; + CDFnode* cdfnode = (CDFnode*)seg->annotation; + ASSERT(cdfnode != NULL); + dimset = cdfnode->array.dimsetplus; + seg->rank = nclistlength(dimset); + /* For this, we do not want any string dimensions */ + if(cdfnode->array.stringdim != NULL) seg->rank--; + for(j=0;jrank;j++) { + CDFnode* dim = (CDFnode*)nclistget(dimset,j); + if(dim->dim.basedim != NULL) dim = dim->dim.basedim; + ASSERT(dim != null); + if(seg->slicesdefined) + seg->slices[j].declsize = dim->dim.declsize; + else + dcemakewholeslice(seg->slices+j,dim->dim.declsize); + } + seg->slicesdefined = 1; + seg->slicesdeclized = 1; + } +#ifdef DEBUG +fprintf(stderr,"qualifyprojectionsizes.after: %s\n", + dumpprojection(proj)); +#endif + return NC_NOERR; +} + +static void +completesegments3(NClist* fullpath, NClist* segments) +{ + int i,delta; + /* add path nodes to segments to create full path */ + delta = (nclistlength(fullpath) - nclistlength(segments)); + ASSERT((delta >= 0)); + for(i=0;iname = nulldup(node->ocname); + seg->annotation = (void*)node; + seg->rank = nclistlength(node->array.dimset0); + nclistinsert(segments,i,(ncelem)seg); + } + /* Now modify the segments to point to the appropriate node + and fill in the slices. + */ + for(i=delta;iannotation = (void*)node; + } +} + +/* +We are given a set of segments (in path) +representing a partial path for a CDFnode variable. +Our goal is to locate all matching +variables for which the path of that +variable has a suffix matching +the given partial path. +If one node matches exactly, then use that one; +otherwise there had better be exactly one +match else ambiguous. +Additional constraints (4/12/2010): +1. if a segment is dimensioned, then use that info + to distinguish e.g a grid node from a possible + grid array within it of the same name. + Treat sequences as of rank 1. +2. if there are two matches, and one is the grid + and the other is the grid array within that grid, + then choose the grid array. +3. If there are multiple matches choose the one with the + shortest path +4. otherwise complain about ambiguity +*/ + +/** + * Given a path as segments, + * try to locate the CDFnode + * instance (from a given set) + * that corresponds to the path. + * The key difficulty is that the + * path may only be a suffix of the + * complete path. + */ + +static NCerror +matchpartialname3(NClist* nodes, NClist* segments, CDFnode** nodep) +{ + int i,nsegs; + NCerror ncstat = NC_NOERR; + DCEsegment* lastseg = NULL; + NClist* namematches = nclistnew(); + NClist* matches = nclistnew(); + NClist* matchpath = nclistnew(); + + /* Locate all nodes with the same name + as the last element in the segment path + */ + nsegs = nclistlength(segments); + lastseg = (DCEsegment*)nclistget(segments,nsegs-1); + for(i=0;iocname == null) + continue; + /* Path names come from oc space */ + if(strcmp(node->ocname,lastseg->name) != 0) + continue; + /* Only look at selected kinds of nodes */ + if(node->nctype != NC_Sequence + && node->nctype != NC_Structure + && node->nctype != NC_Grid + && node->nctype != NC_Primitive + ) + continue; + nclistpush(namematches,(ncelem)node); + } + if(nclistlength(namematches)==0) { + nclog(NCLOGERR,"No match for projection name: %s",lastseg->name); + ncstat = NC_EDDS; + goto done; + } + + /* Now, collect and compare paths of the matching nodes */ + for(i=0;incfullname,dumpsegments(segments)); +#endif + } + } + /* |matches|==0 => no match; |matches|>1 => ambiguity */ + switch (nclistlength(matches)) { + case 0: + nclog(NCLOGERR,"No match for projection name: %s",lastseg->name); + ncstat = NC_EDDS; + break; + case 1: + if(nodep) + *nodep = (CDFnode*)nclistget(matches,0); + break; + default: { + CDFnode* minnode = NULL; + int minpath = 0; + int nmin = 0; /* to catch multiple ones with same short path */ + /* ok, see if one of the matches has a path that is shorter + then all the others */ + for(i=0;i 1) { + nclog(NCLOGERR,"Ambiguous match for projection name: %s", + lastseg->name); + ncstat = NC_EDDS; + } else if(nodep) + *nodep = minnode; + } break; + } +#ifdef DEBUG +fprintf(stderr,"matchpartialname: choice: %s %s for %s\n", +(nclistlength(matches) > 1?"":"forced"), +(*nodep)->ncfullname,dumpsegments(segments)); +#endif + +done: + return THROW(ncstat); +} + +static int +matchsuffix3(NClist* matchpath, NClist* segments) +{ + int i,j; + int nsegs = nclistlength(segments); + int pathlen = nclistlength(matchpath); + ASSERT(pathlen >= nsegs); + for(i=0;irank; + /* Do the names match (in oc name space) */ + if(strcmp(seg->name,node->ocname) != 0) { + segmatch = 0;/* no match */ + } else + /* Do the ranks match (watch out for sequences) */ + if(rank == 0) /* rank == 9 matches any set of dimensions */ + segmatch = 1; + else if(node->nctype == NC_Sequence) + segmatch = (rank == 1?1:0); + else /*!NC_Sequence*/ + segmatch = (rank == nclistlength(node->array.dimset0)?1:0); + if(!segmatch) pathmatch = 0; + } + if(pathmatch) return 1; + } + return 0; +} + + +/* Convert a DCEprojection instance into a string + that can be used with the url +*/ + +char* +buildprojectionstring3(NClist* projections) +{ + char* pstring; + NCbytes* buf = ncbytesnew(); + dcelisttobuffer(projections,buf,","); + pstring = ncbytesdup(buf); + ncbytesfree(buf); + return pstring; +} + +char* +buildselectionstring3(NClist* selections) +{ + NCbytes* buf = ncbytesnew(); + char* sstring; + dcelisttobuffer(selections,buf,"&"); + sstring = ncbytesdup(buf); + ncbytesfree(buf); + return sstring; +} + +char* +buildconstraintstring3(DCEconstraint* constraints) +{ + NCbytes* buf = ncbytesnew(); + char* result = NULL; + dcetobuffer((DCEnode*)constraints,buf); + result = ncbytesdup(buf); + ncbytesfree(buf); + return result; +} + + +/* Given the arguments to vara + construct a corresponding projection + with any pseudo dimensions removed +*/ +NCerror +buildvaraprojection3(Getvara* getvar, + const size_t* startp, const size_t* countp, const ptrdiff_t* stridep, + DCEprojection** projectionp) +{ + int i,j; + NCerror ncstat = NC_NOERR; + CDFnode* var = getvar->target; + DCEprojection* projection = NULL; + NClist* path = nclistnew(); + NClist* segments = NULL; + int dimindex; + + ncstat = dapvar2projection(var,&projection); +#ifdef DEBUG +fprintf(stderr,"buildvaraprojection: %s\n",dumpprojection(projection)); +#endif + + /* We need to assign the start/count/stride info to each segment; + declsize will have been set + */ + segments = projection->var->segments; + dimindex = 0; + for(i=0;irank;j++) { + DCEslice* slice = &segment->slices[j]; + /* make each slice represent the corresponding + start/count/stride */ + slice->first = startp[dimindex+j]; + slice->stride = stridep[dimindex+j]; + slice->count = countp[dimindex+j]; + slice->length = slice->count * slice->stride; + if(slice->length > slice->declsize) + slice->length = slice->declsize; + slice->stop = (slice->first + slice->length); + if(slice->stop > slice->declsize) + slice->stop = slice->declsize; + } + dimindex += segment->rank; + } +#ifdef DEBUG +fprintf(stderr,"buildvaraprojection.final: %s\n",dumpprojection(projection)); +#endif + +#ifdef DEBUG +fprintf(stderr,"buildvaraprojection3: projection=%s\n", + dumpprojection(projection)); +#endif + + if(projectionp) *projectionp = projection; + + nclistfree(path); + if(ncstat) dcefree((DCEnode*)projection); + return ncstat; +} + +int +iswholeslice(DCEslice* slice, CDFnode* dim) +{ + if(slice->first != 0 || slice->stride != 1) return 0; + if(dim != NULL) { + if(slice->stop != dim->dim.declsize) return 0; + } else if(dim == NULL) { + if(slice->declsize == 0 + || slice->count != slice->declsize) return 0; + } + return 1; +} + +int +iswholesegment(DCEsegment* seg) +{ + int i,whole; + NClist* dimset = NULL; + unsigned int rank; + + if(seg->rank == 0) return 1; + if(!seg->slicesdefined) return 0; + if(seg->annotation == NULL) return 0; + dimset = ((CDFnode*)seg->annotation)->array.dimset0; + rank = nclistlength(dimset); + whole = 1; /* assume so */ + for(i=0;islices[i],dim)) {whole = 0; break;} + } + return whole; +} + +int +iswholeprojection(DCEprojection* proj) +{ + int i,whole; + + ASSERT((proj->discrim == CES_VAR)); + + whole = 1; /* assume so */ + for(i=0;ivar->segments);i++) { + DCEsegment* segment = (DCEsegment*)nclistget(proj->var->segments,i); + if(!iswholesegment(segment)) {whole = 0; break;} + } + return whole; +} + +int +iswholeconstraint(DCEconstraint* con) +{ + int i; + if(con == NULL) return 1; + if(con->projections != NULL) { + for(i=0;iprojections);i++) { + if(!iswholeprojection((DCEprojection*)nclistget(con->projections,i))) + return 0; + } + } + if(con->selections != NULL) + return 0; + return 1; +} + + +/* +Given a set of projections, we need to produce +an expanded, correct, and equivalent set of projections. +The term "correct" means we must fix the following cases: +1. Multiple occurrences of the same leaf variable + with differing projection slices. Fix is to complain. +2. Occurrences of container and one or more of its fields. + Fix is to suppress the container. +The term "expanded" means +1. Expand all occurrences of only a container by + replacing it with all of its fields. +*/ + +NCerror +fixprojections(NClist* list) +{ + int i,j,k; + NCerror ncstat = NC_NOERR; + NClist* tmp = nclistnew(); /* misc. uses */ + +#ifdef DEBUG +fprintf(stderr,"fixprojection: list = %s\n",dumpprojections(list)); +#endif + + if(nclistlength(list) == 0) goto done; + + /* Step 1: remove duplicates and complain about slice mismatches */ + for(i=0;idiscrim != CES_VAR) continue; /* dont try to unify functions */ + for(j=i;jdiscrim != CES_VAR) continue; + if(p1->var->annotation != p2->var->annotation) continue; + /* check for slice mismatches */ + if(!slicematch(p1->var->segments,p2->var->segments)) { + /* complain */ + nclog(NCLOGWARN,"Malformed projection: same variable with different slicing"); + } + /* remove p32 */ + nclistset(list,j,(ncelem)NULL); + dcefree((DCEnode*)p2); + } + } + + /* Step 2: remove containers when a field is also present */ + for(i=0;idiscrim != CES_VAR) continue; /* dont try to unify functions */ + if(!iscontainer((CDFnode*)p1->var->annotation)) + continue; + for(j=i;jdiscrim != CES_VAR) continue; + nclistclear(tmp); + collectnodepath3((CDFnode*)p2->var->annotation,tmp,WITHDATASET); + for(k=0;kvar->annotation) { + nclistset(list,i,(ncelem)NULL); + dcefree((DCEnode*)p1); + goto next; + } + } + } +next: continue; + } + + /* Step 3: expand all containers recursively down to the leaf nodes */ + for(;;) { + nclistclear(tmp); + for(i=0;idiscrim != CES_VAR) + continue; /* dont try to unify functions */ + leaf = (CDFnode*)target->var->annotation; + ASSERT(leaf != NULL); + if(iscontainer(leaf)) {/* capture container */ + if(!nclistcontains(tmp,(ncelem)target)) + nclistpush(tmp,(ncelem)target); + nclistset(list,i,(ncelem)NULL); + } + } + if(nclistlength(tmp) == 0) break; /*done*/ + /* Now explode the containers */ + for(i=0;ivar->annotation; + for(j=0;isubnodes);j++) { + CDFnode* field = (CDFnode*)nclistget(leaf->subnodes,j); + /* Convert field node to a proper constraint */ + DCEprojection* proj = projectify(field,container); + nclistpush(list,(ncelem)proj); + } + /* reclaim the container */ + dcefree((DCEnode*)container); + } + } /*for(;;)*/ + + /* remove all NULL elements */ + for(i=nclistlength(list)-1;i>=0;i--) { + DCEprojection* target = (DCEprojection*)nclistget(list,i); + if(target == NULL) + nclistremove(list,i); + } + +done: +#ifdef DEBUG +fprintf(stderr,"fixprojection: exploded = %s\n",dumpprojections(list)); +#endif + nclistfree(tmp); + return ncstat; +} + +static int +iscontainer(CDFnode* node) +{ + return (node->nctype == NC_Dataset + || node->nctype == NC_Sequence + || node->nctype == NC_Structure + || node->nctype == NC_Grid); +} + +static DCEprojection* +projectify(CDFnode* field, DCEprojection* container) +{ + DCEprojection* proj = (DCEprojection*)dcecreate(CES_PROJECT); + DCEvar* var = (DCEvar*)dcecreate(CES_VAR); + DCEsegment* seg = (DCEsegment*)dcecreate(CES_SEGMENT); + proj->discrim = CES_VAR; + proj->var = var; + var->annotation = (void*)field; + /* Dup the segment list */ + var->segments = dceclonelist(container->var->segments); + seg->rank = 0; + nclistpush(var->segments,(ncelem)seg); + return proj; +} + +static int +slicematch(NClist* seglist1, NClist* seglist2) +{ + int i,j; + if((seglist1 == NULL || seglist2 == NULL) && seglist1 != seglist2) + return 0; + if(nclistlength(seglist1) != nclistlength(seglist2)) + return 0; + for(i=0;irank != seg2->rank) + return 0; + for(j=0;jrank;j++) { + if(seg1->slices[j].first != seg2->slices[j].first + || seg1->slices[j].count != seg2->slices[j].count + || seg1->slices[j].stride != seg2->slices[j].stride) + return 0; + } + } + return 1; +} + +/* Convert a CDFnode var to a projection; include + pseudodimensions; always whole variable. +*/ +int +dapvar2projection(CDFnode* var, DCEprojection** projectionp) +{ + int i,j; + int ncstat = NC_NOERR; + NClist* path = nclistnew(); + NClist* segments; + DCEprojection* projection = NULL; + int dimindex; + + /* Collect the nodes needed to construct the projection segment */ + collectnodepath3(var,path,!WITHDATASET); + + segments = nclistnew(); + dimindex = 0; /* point to next subset of slices */ + nclistsetalloc(segments,nclistlength(path)); + for(i=0;iannotation = (void*)n; + segment->name = nulldup(n->ocname); + /* We need to assign whole slices to each segment */ + localrank = nclistlength(n->array.dimsetplus); + segment->rank = localrank; + dimset = n->array.dimsetplus; + for(j=0;jslices[j]; + dim = (CDFnode*)nclistget(dimset,j); + ASSERT(dim->dim.declsize0 > 0); + dcemakewholeslice(slice,dim->dim.declsize0); + } + segment->slicesdefined = 1; + segment->slicesdeclized = 1; + dimindex += localrank; + nclistpush(segments,(ncelem)segment); + } + + projection = (DCEprojection*)dcecreate(CES_PROJECT); + projection->discrim = CES_VAR; + projection->var = (DCEvar*)dcecreate(CES_VAR); + projection->var->annotation = (void*)var; + projection->var->segments = segments; + +#ifdef DEBUG1 +fprintf(stderr,"dapvar2projection: projection=%s\n", + dumpprojection(projection)); +#endif + + nclistfree(path); + if(ncstat) dcefree((DCEnode*)projection); + else if(projectionp) *projectionp = projection; + return ncstat; +} + +/* +Given a set of projections and a projection +representing a variable (from, say vara or prefetch) +construct a single projection for fetching that variable +with the proper constraints. +*/ +int +daprestrictprojection(NClist* projections, DCEprojection* var, DCEprojection** resultp) +{ + int ncstat = NC_NOERR; + int i; + DCEprojection* result = NULL; +#ifdef DEBUG1 +fprintf(stderr,"restrictprojection.before: constraints=|%s| vara=|%s|\n", + dumpprojections(projections), + dumpprojection(var)); +#endif + + ASSERT(var != NULL); + + /* the projection list will contain at most 1 match for the var by construction */ + for(result=null,i=0;idiscrim != CES_VAR) continue; + if(p1->var->annotation == var->var->annotation) { + result = p1; + break; + } + } + if(result == NULL) { + result = (DCEprojection*)dceclone((DCEnode*)var); /* use only the var projection */ + goto done; + } + result = (DCEprojection*)dceclone((DCEnode*)result); /* so we can modify */ + +#ifdef DEBUG1 +fprintf(stderr,"restrictprojection.choice: |%s|\n",dumpprojection(result)); +#endif + /* We need to merge the projection from the projection list + with the var projection + */ + ncstat = dcemergeprojections(result,var); /* result will be modified */ + +done: + if(resultp) *resultp = result; +#ifdef DEBUG +fprintf(stderr,"restrictprojection.after=|%s|\n", + dumpprojection(result)); +#endif + return ncstat; +} + +/* Shift the slice so it runs from 0..count by step 1 */ +static void +dapshiftslice(DCEslice* slice) +{ + size_t first = slice->first; + size_t stride = slice->stride; + if(first == 0 && stride == 1) return; /* no need to do anything */ + slice->first = 0; + slice->stride = 1; + slice->length = slice->count; + slice->stop = slice->count; +} + +int +dapshiftprojection(DCEprojection* projection) +{ + int ncstat = NC_NOERR; + int i,j; + NClist* segments; + +#ifdef DEBUG1 +fprintf(stderr,"dapshiftprojection.before: %s\n",dumpprojection(projection)); +#endif + + ASSERT(projection->discrim == CES_VAR); + segments = projection->var->segments; + for(i=0;irank;j++) { + DCEslice* slice = seg->slices+j; + dapshiftslice(slice); + } + } + +#ifdef DEBUG1 +fprintf(stderr,"dapshiftprojection.after: %s\n",dumpprojection(projection)); +#endif + + return ncstat; +} diff --git a/extern/src_netcdf4/constraints3.h b/extern/src_netcdf4/constraints3.h new file mode 100644 index 0000000000000000000000000000000000000000..1c5ac4bf9ca7aad9902c070b38b3a45e81f42ae7 --- /dev/null +++ b/extern/src_netcdf4/constraints3.h @@ -0,0 +1,40 @@ + /********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/constraints3.h,v 1.10 2010/04/13 03:36:30 dmh Exp $ + *********************************************************************/ +#ifndef CONSTRAINTS3_H +#define CONSTRAINTS3_H 1 + +extern NCerror parsedapconstraints(NCDAPCOMMON*, char*, DCEconstraint*); +extern NCerror mapconstraints3(DCEconstraint*,CDFnode*); +extern NCerror qualifyconstraints3(DCEconstraint* constraint); + +extern char* simplepathstring(NClist* segments, char* separator); +extern void makesegmentstring3(NClist* segments, NCbytes* buf, char* separator); + +extern int iswholeprojection(DCEprojection*); + +extern void freegetvara(struct Getvara* vara); + +extern NCerror slicemerge3(DCEslice* dst, DCEslice* src); + +extern int iswholeslice(DCEslice*, struct CDFnode* dim); +extern int iswholesegment(DCEsegment*); + +extern int iswholeconstraint(DCEconstraint* con); + +extern char* buildprojectionstring3(NClist* projections); +extern char* buildselectionstring3(NClist* selections); +extern char* buildconstraintstring3(DCEconstraint* constraints); + +extern void makewholesegment3(DCEsegment*,struct CDFnode*); +extern void makewholeslice3(DCEslice* slice, struct CDFnode* dim); + +extern NCerror fixprojections(NClist* list); + +extern int dapvar2projection(CDFnode* var, DCEprojection** projectionp); +extern int daprestrictprojection(NClist* projections, DCEprojection* var, DCEprojection** resultp); +extern int dapshiftprojection(DCEprojection*); + +#endif /*CONSTRAINTS3_H*/ diff --git a/extern/src_netcdf4/dapalign.c b/extern/src_netcdf4/dapalign.c new file mode 100644 index 0000000000000000000000000000000000000000..61efd2c30902185faa0810c3a2fc10b92978df44 --- /dev/null +++ b/extern/src_netcdf4/dapalign.c @@ -0,0 +1,332 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapalign.c,v 1.5 2009/09/23 22:26:00 dmh Exp $ + *********************************************************************/ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* +This code is a variantion of the H5detect.c code from HDF5. +Author: D. Heimbigner 10/7/2008 +*/ +#include "config.h" +#ifndef OFFSETTEST +#include "ncdap3.h" +#else +#include +#include +#include +#endif + +#include "dapnc.h" +#include "dapdebug.h" +#include "dapalign.h" + +typedef struct nccalignvlen_t { + size_t len; + void* p; +} nccalignvlen_t; + +#ifdef OFFSETTEST +typedef int nc_type; +#define NC_NAT 0 /* NAT = 'Not A Type' (c.f. NaN) */ +#define NC_BYTE 1 /* signed 1 byte integer */ +#define NC_CHAR 2 /* ISO/ASCII character */ +#define NC_SHORT 3 /* signed 2 byte integer */ +#define NC_INT 4 /* signed 4 byte integer */ +#define NC_FLOAT 5 /* single precision floating point number */ +#define NC_DOUBLE 6 /* double precision floating point number */ +#define NC_UBYTE 7 /* unsigned 1 byte int */ +#define NC_USHORT 8 /* unsigned 2-byte int */ +#define NC_UINT 9 /* unsigned 4-byte int */ +#define NC_INT64 10 /* signed 8-byte int */ +#define NC_UINT64 11 /* unsigned 8-byte int */ +#define NC_STRING 12 /* string */ +#define NC_VLEN 13 +#define NC_OPAQUE 14 +#endif + +/* +The heart of this is the following macro, +which computes the offset of a field x +when preceded by a char field. +The assumptions appear to be as follows: +1. the offset produced in this situation indicates + the alignment for x relative in such a way that it + depends only on the types that precede it in the struct. +2. the compiler does not reorder fields. +3. arrays are tightly packed. +4. nested structs are alignd according to their first member + (this actually follows from C language requirement that + a struct can legally be cast to an instance of its first member). +Given the alignments for the various common primitive types, +it is assumed that one can use them anywhere to construct +the layout of a struct of such types. +It seems to work for HDF5 for a wide variety of machines. +*/ + +#define COMP_ALIGNMENT(DST,TYPE) {\ + struct {char f1; TYPE x;} tmp; \ + DST.typename = #TYPE ; \ + DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));} + + +#define NCCTYPECOUNT (NCCTYPENCVLEN+1) + +static NCtypealignvec vec[NCCTYPECOUNT]; +static NCtypealignset set; +static int dapaligninit = 0; + +unsigned int +ncctypealignment(int nctype) +{ + NCtypealignment* align = NULL; + int index = 0; + if(!dapaligninit) compute_nccalignments(); + switch (nctype) { + case NC_BYTE: index = NCCTYPEUCHAR; break; + case NC_CHAR: index = NCCTYPECHAR; break; + case NC_SHORT: index = NCCTYPESHORT; break; + case NC_INT: index = NCCTYPEINT; break; + case NC_FLOAT: index = NCCTYPEFLOAT; break; + case NC_DOUBLE: index = NCCTYPEDOUBLE; break; + case NC_UBYTE: index = NCCTYPEUCHAR; break; + case NC_USHORT: index = NCCTYPEUSHORT; break; + case NC_UINT: index = NCCTYPEUINT; break; + case NC_INT64: index = NCCTYPELONGLONG; break; + case NC_UINT64: index = NCCTYPEULONGLONG; break; + case NC_STRING: index = NCCTYPEPTR; break; + case NC_VLEN: index = NCCTYPENCVLEN; break; + case NC_OPAQUE: index = NCCTYPEUCHAR; break; + default: +#ifndef OFFSETTEST + PANIC1("nctypealignment: bad type code: %d",nctype); +#else + return 0; +#endif + } + align = &vec[index]; + return align->alignment; +} + + +void +compute_nccalignments(void) +{ + /* Compute the alignments for all the common C data types*/ + /* First for the struct*/ + /* initialize*/ + memset((void*)&set,0,sizeof(set)); + memset((void*)vec,0,sizeof(vec)); + + COMP_ALIGNMENT(set.charalign,char); + COMP_ALIGNMENT(set.ucharalign,unsigned char); + COMP_ALIGNMENT(set.shortalign,short); + COMP_ALIGNMENT(set.ushortalign,unsigned short); + COMP_ALIGNMENT(set.intalign,int); + COMP_ALIGNMENT(set.uintalign,unsigned int); + COMP_ALIGNMENT(set.longalign,long); + COMP_ALIGNMENT(set.ulongalign,unsigned long); + COMP_ALIGNMENT(set.longlongalign,long long); + COMP_ALIGNMENT(set.ulonglongalign,unsigned long long); + COMP_ALIGNMENT(set.floatalign,float); + COMP_ALIGNMENT(set.doublealign,double); + COMP_ALIGNMENT(set.ptralign,void*); + COMP_ALIGNMENT(set.ncvlenalign,nccalignvlen_t); + + /* Then the vector*/ + COMP_ALIGNMENT(vec[NCCTYPECHAR],char); + COMP_ALIGNMENT(vec[NCCTYPEUCHAR],unsigned char); + COMP_ALIGNMENT(vec[NCCTYPESHORT],short); + COMP_ALIGNMENT(vec[NCCTYPEUSHORT],unsigned short); + COMP_ALIGNMENT(vec[NCCTYPEINT],int); + COMP_ALIGNMENT(vec[NCCTYPEUINT],unsigned int); + COMP_ALIGNMENT(vec[NCCTYPELONG],long); + COMP_ALIGNMENT(vec[NCCTYPEULONG],unsigned long); + COMP_ALIGNMENT(vec[NCCTYPELONGLONG],long long); + COMP_ALIGNMENT(vec[NCCTYPEULONGLONG],unsigned long long); + COMP_ALIGNMENT(vec[NCCTYPEFLOAT],float); + COMP_ALIGNMENT(vec[NCCTYPEDOUBLE],double); + COMP_ALIGNMENT(vec[NCCTYPEPTR],void*); + COMP_ALIGNMENT(vec[NCCTYPENCVLEN],nccalignvlen_t); + + dapaligninit = 1; +} + +/* Compute padding */ +int +nccpadding(unsigned long offset, int alignment) +{ + int pad,rem; + rem = (alignment==0?0:(offset % alignment)); + pad = (rem==0?0:(alignment - rem)); + return pad; +} + +#ifdef OFFSETTEST + +#define COMP_ALIGNMENT1(DST,TYPE1,TYPE) {\ + struct {TYPE1 f1; TYPE x;} tmp; \ + DST.typename = #TYPE ; \ + DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));} + +#define COMP_ALIGNMENT2(DST,TYPE1,TYPE2,TYPE) {\ + struct {TYPE1 f1, TYPE2 f2; TYPE x;} tmp; \ + DST.typename = #TYPE ; \ + DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));} + +#define COMP_SIZE0(DST,TYPE1,TYPE2) {\ + struct {TYPE1 c; TYPE2 x;} tmp; \ + DST = sizeof(tmp); } + +static char* +padname(char* name) +{ +#define MAX 20 + if(name == NULL) name = "null"; + int len = strlen(name); + if(len > MAX) len = MAX; + char* s = (char*)malloc(MAX+1); + memset(s,' ',MAX); + s[MAX+1] = '\0'; + strncpy(s,name,len); + return s; +} + +static void +verify(NCtypealignvec* vec) +{ + int i,j; + NCtypealignvec* vec16; + NCtypealignvec* vec32; + int* sizes8; + int* sizes16; + int* sizes32; + + vec16 = (NCtypealignvec*)malloc(sizeof(NCtypealignvec)*NCCTYPECOUNT); + vec32 = (NCtypealignvec*)malloc(sizeof(NCtypealignvec)*NCCTYPECOUNT); + sizes8 = (int*)malloc(sizeof(int)*NCCTYPECOUNT); + sizes16 = (int*)malloc(sizeof(int)*NCCTYPECOUNT); + sizes32 = (int*)malloc(sizeof(int)*NCCTYPECOUNT); + + COMP_SIZE0(sizes8[1],char,char); + COMP_SIZE0(sizes8[2],unsigned char,char); + COMP_SIZE0(sizes8[3],short,char); + COMP_SIZE0(sizes8[4],unsigned short,char); + COMP_SIZE0(sizes8[5],int,char); + COMP_SIZE0(sizes8[6],unsigned int,char); + COMP_SIZE0(sizes8[7],long,char); + COMP_SIZE0(sizes8[8],unsigned long,char); + COMP_SIZE0(sizes8[9],long long,char); + COMP_SIZE0(sizes8[10],unsigned long long,char); + COMP_SIZE0(sizes8[11],float,char); + COMP_SIZE0(sizes8[12],double,char) ; + COMP_SIZE0(sizes8[13],void*,char); + COMP_SIZE0(sizes8[14],alignvlen_t,char); + + COMP_SIZE0(sizes16[1],char,short); + COMP_SIZE0(sizes16[2],unsigned char,short); + COMP_SIZE0(sizes16[3],short,short); + COMP_SIZE0(sizes16[4],unsigned short,short); + COMP_SIZE0(sizes16[5],int,short); + COMP_SIZE0(sizes16[6],unsigned int,short); + COMP_SIZE0(sizes16[7],long,short); + COMP_SIZE0(sizes16[8],unsigned long,short); + COMP_SIZE0(sizes16[9],long long,short); + COMP_SIZE0(sizes16[10],unsigned long long,short); + COMP_SIZE0(sizes16[11],float,short); + COMP_SIZE0(sizes16[12],double,short) ; + COMP_SIZE0(sizes16[13],void*,short); + COMP_SIZE0(sizes16[14],alignvlen_t*,short); + + COMP_SIZE0(sizes32[1],char,int); + COMP_SIZE0(sizes32[2],unsigned char,int); + COMP_SIZE0(sizes32[3],short,int); + COMP_SIZE0(sizes32[4],unsigned short,int); + COMP_SIZE0(sizes32[5],int,int); + COMP_SIZE0(sizes32[6],unsigned int,int); + COMP_SIZE0(sizes32[7],long,int); + COMP_SIZE0(sizes32[8],unsigned long,int); + COMP_SIZE0(sizes32[9],long long,int); + COMP_SIZE0(sizes32[10],unsigned long long,int); + COMP_SIZE0(sizes32[11],float,int); + COMP_SIZE0(sizes32[12],double,int) ; + COMP_SIZE0(sizes32[13],void*,int); + COMP_SIZE0(sizes32[14],alignvlen_t*,int); + + COMP_ALIGNMENT1(vec16[1],char,short); + COMP_ALIGNMENT1(vec16[2],unsigned char,short); + COMP_ALIGNMENT1(vec16[3],short,short); + COMP_ALIGNMENT1(vec16[4],unsigned short,short); + COMP_ALIGNMENT1(vec16[5],int,short); + COMP_ALIGNMENT1(vec16[6],unsigned int,short); + COMP_ALIGNMENT1(vec32[7],long,short); + COMP_ALIGNMENT1(vec32[8],unsigned long,short); + COMP_ALIGNMENT1(vec32[9],long long,short); + COMP_ALIGNMENT1(vec32[10],unsigned long long,short); + COMP_ALIGNMENT1(vec16[11],float,short); + COMP_ALIGNMENT1(vec16[12],double,short); + COMP_ALIGNMENT1(vec16[13],void*,short); + COMP_ALIGNMENT1(vec16[14],alignvlen_t*,short); + + COMP_ALIGNMENT1(vec32[1],char,short); + COMP_ALIGNMENT1(vec32[2],unsigned char,short); + COMP_ALIGNMENT1(vec32[3],char,short); + COMP_ALIGNMENT1(vec32[4],unsigned short,short); + COMP_ALIGNMENT1(vec32[5],int,int); + COMP_ALIGNMENT1(vec32[6],unsigned int,int); + COMP_ALIGNMENT1(vec32[7],long,int); + COMP_ALIGNMENT1(vec32[8],unsigned long,int); + COMP_ALIGNMENT1(vec32[9],long long,int); + COMP_ALIGNMENT1(vec32[10],unsigned long long,int); + COMP_ALIGNMENT1(vec32[11],float,int); + COMP_ALIGNMENT1(vec32[12],double,int); + COMP_ALIGNMENT1(vec32[13],void*,int); + COMP_ALIGNMENT1(vec32[14],alignvlen_t*,int); + + for(i=0;i NOT-A-TYPE*/ +#define NCCTYPENAT 0 +#define NCCTYPECHAR 1 +#define NCCTYPEUCHAR 2 +#define NCCTYPESHORT 3 +#define NCCTYPEUSHORT 4 +#define NCCTYPEINT 5 +#define NCCTYPEUINT 6 +#define NCCTYPELONG 7 +#define NCCTYPEULONG 8 +#define NCCTYPELONGLONG 9 +#define NCCTYPEULONGLONG 10 +#define NCCTYPEFLOAT 11 +#define NCCTYPEDOUBLE 12 +#define NCCTYPEPTR 13 +#define NCCTYPENCVLEN 14 + +/* Capture in struct and in a vector*/ +typedef struct NCtypealignset { + NCtypealignment charalign; /* char*/ + NCtypealignment ucharalign; /* unsigned char*/ + NCtypealignment shortalign; /* short*/ + NCtypealignment ushortalign; /* unsigned short*/ + NCtypealignment intalign; /* int*/ + NCtypealignment uintalign; /* unsigned int*/ + NCtypealignment longalign; /* long*/ + NCtypealignment ulongalign; /* unsigned long*/ + NCtypealignment longlongalign; /* long long*/ + NCtypealignment ulonglongalign; /* unsigned long long*/ + NCtypealignment floatalign; /* float*/ + NCtypealignment doublealign; /* double*/ + NCtypealignment ptralign; /* void**/ + NCtypealignment ncvlenalign; /* nc_vlen_t*/ +} NCtypealignset; + +typedef NCtypealignment NCtypealignvec; + +extern void compute_nccalignments(void); +extern unsigned int ncctypealignment(int nctype); +extern int nccpadding(unsigned long offset, int alignment); + +#endif /*ALIGN_H*/ diff --git a/extern/src_netcdf4/dapattr3.c b/extern/src_netcdf4/dapattr3.c new file mode 100644 index 0000000000000000000000000000000000000000..b39a61e303aa7ffbe42dd2dee79279c2b2944376 --- /dev/null +++ b/extern/src_netcdf4/dapattr3.c @@ -0,0 +1,341 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapattr3.c,v 1.14 2009/12/03 03:42:38 dmh Exp $ + *********************************************************************/ + +#include "ncdap3.h" + +#define OCHECK(exp) if((ocstat = (exp))) goto done; + +/* Forward */ +static NCerror buildattribute(char*,nc_type,NClist*,NCattribute**); +static int mergedas1(NCDAPCOMMON*, OCconnection, CDFnode* dds, OCobject das); +static int isglobalname3(char* name); + +static NCerror +buildattribute(char* name, nc_type ptype, + NClist* values, NCattribute** attp) +{ + NCerror ncstat = NC_NOERR; + NCattribute* att; + + att = (NCattribute*)calloc(1,sizeof(NCattribute)); + MEMCHECK(att,NC_ENOMEM); + att->name = nulldup(name); + att->etype = ptype; + + att->values = values; + + if(attp) *attp = att; + + return THROW(ncstat); +} + +/* +Given a das attribute walk it to see if it +has at least 1 actual attribute (no recursion) +*/ +static int +hasattribute3(OCconnection conn, OCobject dasnode) +{ + int i; + OCerror ocstat = OC_NOERR; + int tf = 0; /* assume false */ + unsigned int nsubnodes; + OCtype ocsubtype; + OCobject* subnodes = NULL; + + OCHECK(oc_inq_class(conn,dasnode,&ocsubtype)); + if(ocsubtype == OC_Attribute) return 1; /* this is an attribute */ + ASSERT((ocsubtype == OC_Attributeset)); + + OCHECK(oc_inq_nsubnodes(conn,dasnode,&nsubnodes)); + OCHECK(oc_inq_subnodes(conn,dasnode,&subnodes)); + for(i=0;ioc.conn; + unsigned int nsubnodes, nobjects; + OCobject* dasobjects = NULL; + NClist* dasglobals = nclistnew(); + NClist* dasnodes = nclistnew(); + NClist* dodsextra = nclistnew(); + NClist* varnodes = nclistnew(); + NClist* allddsnodes = ddsroot->tree->nodes; + + if(ddsroot == NULL || dasroot == NULL) return NC_NOERR; + + nobjects = oc_inq_nobjects(conn,dasroot); + dasobjects = oc_inq_objects(conn,dasroot); + + /* 1. collect all the relevant DAS nodes; + namely those that contain at least one + attribute value. + Simultaneously look for potential ambiguities + if found; complain but continue: result are indeterminate. + also collect globals and DODS_EXTRA separately. + */ + for(i=0;inctype == NC_Primitive) nclistpush(varnodes,(ncelem)dds); + } + + /* 3. For each das node, lncate matching DDS node(s) and attach + attributes to the DDS node(s). + Match means: + 1. DAS->fullname :: DDS->fullname + 2. DAS->name :: DDS->fullname (support DAS names with embedded '.' + 3. DAS->name :: DDS->name + 4. special case for DODS. Apply 1-3 on DODS parent. + */ + for(i=0;iocname)==0) { + mergedas1(nccomm,conn,dds,das); + /* remove from dasnodes list*/ + nclistset(dasnodes,i,(ncelem)NULL); + } + nullfree(ddsfullname); + } + nullfree(ocfullname); + nullfree(ocbasename); + } + + /* 4. Assign globals */ + for(i=0;iattributes == NULL) dds->attributes = nclistnew(); + /* assign the simple attributes in the das set to this dds node*/ + OCHECK(oc_inq_nsubnodes(conn,das,&nsubnodes)); + OCHECK(oc_inq_subnodes(conn,das,&subnodes)); + for(i=0;iattributes,(ncelem)att); + } else if(octype == OC_Attributeset + && (strcmp(ocname,"DODS")==0 + || strcmp(ocname,"DODS_EXTRA")==0)) { + /* Turn the DODS special attributes into into + special attributes for dds node */ + OCHECK(oc_inq_nsubnodes(conn,attnode,&ndodsnodes)); + OCHECK(oc_inq_subnodes(conn,attnode,&dodsnodes)); + for(j=0;jinvisible = 1; + nclistpush(dds->attributes,(ncelem)att); + + /* Define extra semantics associated with DODS and DODS_EXTRA attribute */ + if(strcmp(dodsname,"strlen")==0) { + unsigned int maxstrlen = 0; + if(nclistlength(stringvalues) > 0) { + char* stringval = (char*)nclistget(stringvalues,0); + if(0==sscanf(stringval,"%u",&maxstrlen)) maxstrlen = 0; + } + dds->dodsspecial.maxstrlen = maxstrlen; +#ifdef DEBUG +fprintf(stderr,"%s.maxstrlen=%d\n",dds->ocname,(int)dds->dodsspecial.maxstrlen); +#endif + } else if(strcmp(dodsname,"dimName")==0) { + if(nclistlength(stringvalues) > 0) { + char* stringval = (char*)nclistget(stringvalues,0); + dds->dodsspecial.dimname = nulldup(stringval); +#ifdef DEBUG +fprintf(stderr,"%s.dimname=%s\n",dds->ocname,dds->dodsspecial.dimname); +#endif + } else dds->dodsspecial.dimname = NULL; + } else if(strcmp(dodsname,"Unlimited_Dimension")==0) { + if(nccomm->cdf.recorddimname != NULL) { + nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications"); + } else if(nclistlength(stringvalues) > 0) { + char* stringval = (char*)nclistget(stringvalues,0); + nccomm->cdf.recorddimname = nulldup(stringval); +#ifdef DEBUG +fprintf(stderr,"%s.Unlimited_Dimension=%s\n",dds->ocname,nccomm->cdf.recorddimname); +#endif + } + } /* else ignore */ + nullfree(dodsname); + } + nullfree(dodsnodes); + } + nullfree(ocname); + } + +done: + nullfree(subnodes); + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); + return THROW(ncstat); +} + +static int +isglobalname3(char* name) +{ + int len = strlen(name); + int glen = strlen("global"); + char* p; + if(len < glen) return 0; + p = name + (len - glen); + if(strcasecmp(p,"global") != 0) + return 0; + return 1; +} + diff --git a/extern/src_netcdf4/dapcvt.c b/extern/src_netcdf4/dapcvt.c new file mode 100644 index 0000000000000000000000000000000000000000..67041f2e1e7e3b9f834646062267798b29c69f00 --- /dev/null +++ b/extern/src_netcdf4/dapcvt.c @@ -0,0 +1,265 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapcvt.c,v 1.14 2009/11/29 00:16:26 dmh Exp $ + *********************************************************************/ +#include "config.h" +#include "ncdap3.h" +#include "dapodom.h" + +NCerror +dapconvert3(nc_type srctype, nc_type dsttype, char* memory0, char* value0, size_t count) +{ + NCerror ncstat = NC_NOERR; + size_t i; + char* memory = memory0; + char* value = value0; + + /* In order to deal with the DAP upgrade problem, + try to preserve the bit patterns + */ + + /* Provide space and pointer casts for intermediate results */ + signed char ncbyte; + signed char* ncbytep; + char ncchar; + char* nccharp; + short ncshort; + short* ncshortp; + int ncint; + int* ncintp; + float ncfloat; + float* ncfloatp; + double ncdouble; + double* ncdoublep; + unsigned char ncubyte; + unsigned char* ncubytep; + unsigned short ncushort; + unsigned short* ncushortp; + unsigned int ncuint; + unsigned int* ncuintp; + long long ncint64; + long long* ncint64p; + unsigned long long ncuint64; + unsigned long long* ncuint64p; + + +#define CASE(nc1,nc2) (nc1*256+nc2) +#define CUT8(e) ((unsigned char)((e) & 0xff)) +#define CUT16(e) ((unsigned short)((e) & 0xffff)) +#define CUT32(e) ((unsigned int)((e) & 0xffffffff)) +#define ARM(vs,ncs,ts,vd,ncd,td) \ +case CASE(ncs,ncd):\ + vs##p = (ts *)value;\ + vs = *vs##p;\ + vd##p = (td *)memory;\ + *vd##p = (td)vs;\ + break; + + for(i=0;i +#include + +#include "nclog.h" +#include "oc.h" +#include "dapdebug.h" + +int ncdap3debug = 0; + +#ifdef CATCHERROR +/* Place breakpoint here to catch errors close to where they occur*/ +int +dapbreakpoint(int err) {return err;} + +int +dapthrow(int err) +{ + if(err == 0) return err; + return dapbreakpoint(err); +} +#endif + +int +dappanic(const char* fmt, ...) +{ + va_list args; + if(fmt != NULL) { + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n" ); + va_end( args ); + } else { + fprintf(stderr, "panic" ); + } + fprintf(stderr, "\n" ); + fflush(stderr); + return 0; +} diff --git a/extern/src_netcdf4/dapdebug.h b/extern/src_netcdf4/dapdebug.h new file mode 100644 index 0000000000000000000000000000000000000000..ffd92d9ed5b037f6ed6b8d6adddaee7eeb8277e3 --- /dev/null +++ b/extern/src_netcdf4/dapdebug.h @@ -0,0 +1,73 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapdebug.h,v 1.33 2009/12/03 18:53:16 dmh Exp $ + *********************************************************************/ +#ifndef DEBUG_H +#define DEBUG_H + +#include "ocdebug.h" + +#ifdef DAPDEBUG +# define DEBUG +# if DAPDEBUG > 0 +# define DEBUG1 +# endif +# if DAPDEBUG > 1 +# define DEBUG2 +# endif +# if DAPDEBUG > 2 +# define DEBUG3 +# endif +#endif + +#undef PARSEDEBUG + +#include +#include + +/* Warning: setting CATCHERROR has significant performance impact */ +#undef CATCHERROR +#ifdef DEBUG +#undef CATCHERROR +#define CATCHERROR +#endif + +#define PANIC(msg) assert(dappanic(msg)); +#define PANIC1(msg,arg) assert(dappanic(msg,arg)); +#define PANIC2(msg,arg1,arg2) assert(dappanic(msg,arg1,arg2)); + +#define ASSERT(expr) if(!(expr)) {PANIC(#expr);} else {} + +extern int ncdap3debug; + +extern int dappanic(const char* fmt, ...); + +#define MEMCHECK(var,throw) {if((var)==NULL) return (throw);} + +#ifdef CATCHERROR +/* Place breakpoint on dapbreakpoint to catch errors close to where they occur*/ +#define THROW(e) dapthrow(e) +#define THROWCHK(e) (void)dapthrow(e) + +extern int dapbreakpoint(int err); +extern int dapthrow(int err); +#else +#define THROW(e) (e) +#define THROWCHK(e) +#endif + +#ifdef DEBUG +#define SHOWFETCH (1) +#define LOG0(level,msg) fprintf(stderr,msg) +#define LOG1(level,msg,a1) fprintf(stderr,msg,a1) +#define LOG2(level,msg,a1,a2) fprintf(stderr,msg,a1,a2) +#else +#define SHOWFETCH FLAGSET(nccomm->controls,NCF_SHOWFETCH) +#define LOG0(level,msg) nclog(level,msg) +#define LOG1(level,msg,a1) nclog(level,msg,a1) +#define LOG2(level,msg,a1,a2) nclog(level,msg,a1,a2) +#endif + +#endif /*DEBUG_H*/ + diff --git a/extern/src_netcdf4/dapdump.c b/extern/src_netcdf4/dapdump.c new file mode 100644 index 0000000000000000000000000000000000000000..f26bdea7cc93fa44b9caf42b61f85699720f2ed7 --- /dev/null +++ b/extern/src_netcdf4/dapdump.c @@ -0,0 +1,607 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapdump.c,v 1.21 2010/05/26 21:43:31 dmh Exp $ + *********************************************************************/ +#include "config.h" +#ifdef USE_PARALLEL +#include "netcdf_par.h" +#endif +#include "ncdap3.h" +#include "dapdump.h" +#include "dceconstraints.h" + +#define CHECK(n) if((n) != NC_NOERR) {return (n);} else {} + +static void dumptreer(CDFnode* root, NCbytes* buf, int indent, int visible); + +int +dumpmetadata(int ncid, NChdr** hdrp) +{ + int stat,i,j,k; + NChdr* hdr = (NChdr*)calloc(1,sizeof(NChdr)); + MEMCHECK(hdr,NC_ENOMEM); + hdr->ncid = ncid; + hdr->content = ncbytesnew(); + if(hdrp) *hdrp = hdr; + + stat = nc_inq(hdr->ncid, + &hdr->ndims, + &hdr->nvars, + &hdr->ngatts, + &hdr->unlimid); + CHECK(stat); + if(ncdap3debug > 0) { + fprintf(stdout,"ncid=%d ngatts=%d ndims=%d nvars=%d unlimid=%d\n", + hdr->ncid,hdr->ngatts,hdr->ndims,hdr->nvars,hdr->unlimid); + } + hdr->gatts = (NCattribute*)calloc(1,hdr->ngatts*sizeof(NCattribute)); + MEMCHECK(hdr->gatts,NC_ENOMEM); + if(hdr->ngatts > 0) + fprintf(stdout,"global attributes:\n"); + for(i=0;ingatts;i++) { + NCattribute* att = &hdr->gatts[i]; + char attname[NC_MAX_NAME]; + nc_type nctype; + size_t typesize; + size_t nvalues; + + stat = nc_inq_attname(hdr->ncid,NC_GLOBAL,i,attname); + CHECK(stat); + att->name = nulldup(attname); + stat = nc_inq_att(hdr->ncid,NC_GLOBAL,att->name,&nctype,&nvalues); + CHECK(stat); + att->etype = nctypetodap(nctype); + typesize = nctypesizeof(att->etype); + fprintf(stdout,"\t[%d]: name=%s type=%s values(%lu)=", + i,att->name,nctypetostring(octypetonc(att->etype)), + (unsigned long)nvalues); + if(nctype == NC_CHAR) { + size_t len = typesize*nvalues; + char* values = (char*)malloc(len+1);/* for null terminate*/ + MEMCHECK(values,NC_ENOMEM); + stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values); + CHECK(stat); + values[len] = '\0'; + fprintf(stdout," '%s'",values); + } else { + size_t len = typesize*nvalues; + char* values = (char*)malloc(len); + MEMCHECK(values,NC_ENOMEM); + stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values); + CHECK(stat); + for(k=0;ketype),k,values); + } + } + fprintf(stdout,"\n"); + } + + hdr->dims = (Dim*)malloc(hdr->ndims*sizeof(Dim)); + MEMCHECK(hdr->dims,NC_ENOMEM); + for(i=0;indims;i++) { + hdr->dims[i].dimid = i; + stat = nc_inq_dim(hdr->ncid, + hdr->dims[i].dimid, + hdr->dims[i].name, + &hdr->dims[i].size); + CHECK(stat); + fprintf(stdout,"dim[%d]: name=%s size=%lu\n", + i,hdr->dims[i].name,(unsigned long)hdr->dims[i].size); + } + hdr->vars = (Var*)malloc(hdr->nvars*sizeof(Var)); + MEMCHECK(hdr->vars,NC_ENOMEM); + for(i=0;invars;i++) { + Var* var = &hdr->vars[i]; + nc_type nctype; + var->varid = i; + stat = nc_inq_var(hdr->ncid, + var->varid, + var->name, + &nctype, + &var->ndims, + var->dimids, + &var->natts); + CHECK(stat); + var->nctype = (nctype); + fprintf(stdout,"var[%d]: name=%s type=%s |dims|=%d", + i, + var->name, + nctypetostring(var->nctype), + var->ndims); + fprintf(stdout," dims={"); + for(j=0;jndims;j++) { + fprintf(stdout," %d",var->dimids[j]); + } + fprintf(stdout,"}\n"); + var->atts = (NCattribute*)malloc(var->natts*sizeof(NCattribute)); + MEMCHECK(var->atts,NC_ENOMEM); + for(j=0;jnatts;j++) { + NCattribute* att = &var->atts[j]; + char attname[NC_MAX_NAME]; + size_t typesize; + char* values; + nc_type nctype; + size_t nvalues; + stat = nc_inq_attname(hdr->ncid,var->varid,j,attname); + CHECK(stat); + att->name = nulldup(attname); + stat = nc_inq_att(hdr->ncid,var->varid,att->name,&nctype,&nvalues); + CHECK(stat); + att->etype = nctypetodap(nctype); + typesize = nctypesizeof(att->etype); + values = (char*)malloc(typesize*nvalues); + MEMCHECK(values,NC_ENOMEM); + stat = nc_get_att(hdr->ncid,var->varid,att->name,values); + CHECK(stat); + fprintf(stdout,"\tattr[%d]: name=%s type=%s values(%lu)=", + j,att->name,nctypetostring(octypetonc(att->etype)),(unsigned long)nvalues); + for(k=0;ketype),k,values); + } + fprintf(stdout,"\n"); + } + } + fflush(stdout); + return NC_NOERR; +} + +void +dumpdata1(nc_type nctype, size_t index, char* data) +{ + switch (nctype) { + case NC_CHAR: + fprintf(stdout,"'%c' %hhd",data[index],data[index]); + break; + case NC_BYTE: + fprintf(stdout,"%hdB",((signed char*)data)[index]); + break; + case NC_UBYTE: + fprintf(stdout,"%huB",((unsigned char*)data)[index]); + break; + case NC_SHORT: + fprintf(stdout,"%hdS",((short*)data)[index]); + break; + case NC_USHORT: + fprintf(stdout,"%hdUS",((unsigned short*)data)[index]); + break; + case NC_INT: + fprintf(stdout,"%d",((int*)data)[index]); + break; + case NC_UINT: + fprintf(stdout,"%uU",((unsigned int*)data)[index]); + break; + case NC_FLOAT: + fprintf(stdout,"%#gF",((float*)data)[index]); + break; + case NC_DOUBLE: + fprintf(stdout,"%#gD",((double*)data)[index]); + break; + case NC_STRING: + fprintf(stdout,"\"%s\"",((char**)data)[index]); + break; + default: + fprintf(stdout,"Unknown type: %i",nctype); + break; + } + fflush(stdout); +} + +/* Following should be kept consistent with + the makeXXXstring3 routines in constraints3.c +*/ + +/* Convert an NCprojection instance into a string + that can be used with the url +*/ +char* +dumpprojections(NClist* projections) +{ + char* tmp; + int v = dceverbose; + dceverbose = 1; + tmp = dcelisttostring(projections,","); + dceverbose = v; + return tmp; +} + +char* +dumpprojection(DCEprojection* proj) +{ + char* tmp; + int v = dceverbose; + dceverbose = 1; + tmp = dcetostring((DCEnode*)proj); + dceverbose = v; + return tmp; +} + +char* +dumpselections(NClist* selections) +{ + return dcelisttostring(selections,"&"); +} + +char* +dumpselection(DCEselection* sel) +{ + return dcetostring((DCEnode*)sel); +} + +char* +dumpconstraint(DCEconstraint* con) +{ + char* tmp; + int v = dceverbose; + dceverbose = 1; + tmp = dcetostring((DCEnode*)con); + dceverbose = v; + return tmp; +} + +char* +dumpsegments(NClist* segments) +{ + return dcelisttostring(segments,"."); +} + +char* +dumppath(CDFnode* leaf) +{ + NClist* path = nclistnew(); + NCbytes* buf = ncbytesnew(); + char* result; + int i; + + if(leaf == NULL) return nulldup(""); + collectnodepath3(leaf,path,!WITHDATASET); + for(i=0;i 0) ncbytescat(buf,"."); + ncbytescat(buf,node->ncbasename); + } + result = ncbytesdup(buf); + ncbytesfree(buf); + nclistfree(path); + return result; +} + +static void +dumpindent(int indent, NCbytes* buf) +{ + static char* indentstr = " "; + int i; + for(i=0;isubnodes);i++) { + CDFnode* node = (CDFnode*)nclistget(root->subnodes,i); + if(visible && !root->visible) continue; + if(root->nctype == NC_Grid) { + if(i==0) { + dumpindent(indent+1,buf); + ncbytescat(buf,"Array:\n"); + } else if(i==1) { + dumpindent(indent+1,buf); + ncbytescat(buf,"Maps:\n"); + } + dumptreer(node,buf,indent+2,visible); + } else { + dumptreer(node,buf,indent+1,visible); + } + } + dumpindent(indent,buf); + ncbytescat(buf,"} "); + ncbytescat(buf,root->ncbasename); +} + +static void +dumptreer(CDFnode* root, NCbytes* buf, int indent, int visible) +{ + int i; + char* primtype = NULL; + NClist* dimset = NULL; + + if(visible && !root->visible) return; + switch (root->nctype) { + case NC_Dataset: + dumptreer1(root,buf,indent,"Dataset",visible); + break; + case NC_Sequence: + dumptreer1(root,buf,indent,"Sequence",visible); + break; + case NC_Structure: + dumptreer1(root,buf,indent,"Structure",visible); + break; + case NC_Grid: + dumptreer1(root,buf,indent,"Grid",visible); + break; + case NC_Primitive: + switch (root->etype) { + case NC_BYTE: primtype = "byte"; break; + case NC_CHAR: primtype = "char"; break; + case NC_SHORT: primtype = "short"; break; + case NC_INT: primtype = "int"; break; + case NC_FLOAT: primtype = "float"; break; + case NC_DOUBLE: primtype = "double"; break; + case NC_UBYTE: primtype = "ubyte"; break; + case NC_USHORT: primtype = "ushort"; break; + case NC_UINT: primtype = "uint"; break; + case NC_INT64: primtype = "int64"; break; + case NC_UINT64: primtype = "uint64"; break; + case NC_STRING: primtype = "string"; break; + default: break; + } + dumpindent(indent,buf); + ncbytescat(buf,primtype); + ncbytescat(buf," "); + ncbytescat(buf,root->ncbasename); + break; + default: break; + } + + if(nclistlength(root->array.dimsetplus) > 0) dimset = root->array.dimsetplus; + else if(nclistlength(root->array.dimset0) > 0) dimset = root->array.dimset0; + if(dimset != NULL) { + for(i=0;incbasename != NULL) { + ncbytescat(buf,dim->ncbasename); + ncbytescat(buf,"="); + } + snprintf(tmp,sizeof(tmp),"%lu",(unsigned long)dim->dim.declsize); + ncbytescat(buf,tmp); + ncbytescat(buf,"]"); + } + } + ncbytescat(buf,";\n"); +} + +char* +dumptree(CDFnode* root) +{ + NCbytes* buf = ncbytesnew(); + char* result; + dumptreer(root,buf,0,0); + result = ncbytesdup(buf); + ncbytesfree(buf); + return result; +} + +char* +dumpvisible(CDFnode* root) +{ + NCbytes* buf = ncbytesnew(); + char* result; + dumptreer(root,buf,0,1); + result = ncbytesdup(buf); + ncbytesfree(buf); + return result; +} + +/* Provide detailed data on a CDFnode */ +char* +dumpnode(CDFnode* node) +{ + NCbytes* buf = ncbytesnew(); + char* result; + int i; + char* nctype = NULL; + char* primtype = NULL; + char tmp[1024]; + + switch (node->nctype) { + case NC_Dataset: nctype = "Dataset"; break; + case NC_Sequence: nctype = "Sequence"; break; + case NC_Structure: nctype = "Structure"; break; + case NC_Grid: nctype = "Grid"; break; + case NC_Primitive: + switch (node->etype) { + case NC_BYTE: primtype = "byte"; break; + case NC_CHAR: primtype = "char"; break; + case NC_SHORT: primtype = "short"; break; + case NC_INT: primtype = "int"; break; + case NC_FLOAT: primtype = "float"; break; + case NC_DOUBLE: primtype = "double"; break; + case NC_UBYTE: primtype = "ubyte"; break; + case NC_USHORT: primtype = "ushort"; break; + case NC_UINT: primtype = "uint"; break; + case NC_INT64: primtype = "int64"; break; + case NC_UINT64: primtype = "uint64"; break; + case NC_STRING: primtype = "string"; break; + default: break; + } + break; + default: break; + } + snprintf(tmp,sizeof(tmp),"%s %s {\n", + (nctype?nctype:primtype),node->ocname); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"ocnode=%lx\n",(unsigned long)node->ocnode); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"container=%s\n", + (node->container?node->container->ocname:"null")); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"root=%s\n", + (node->root?node->root->ocname:"null")); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"ncbasename=%s\n",node->ncbasename); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"ncfullname=%s\n",node->ncfullname); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"|subnodes|=%d\n",nclistlength(node->subnodes)); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"externaltype=%d\n",node->externaltype); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"ncid=%d\n",node->ncid); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"maxstringlength=%ld\n",node->maxstringlength); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"sequencelimit=%ld\n",node->sequencelimit); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"usesequence=%d\n",node->usesequence); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"elided=%d\n",node->elided); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"visible=%d\n",node->visible); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"attachment=%s\n", + (node->attachment?node->attachment->ocname:"null")); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp),"rank=%u\n",nclistlength(node->array.dimset0)); + ncbytescat(buf,tmp); + for(i=0;iarray.dimset0);i++) { + CDFnode* dim = (CDFnode*)nclistget(node->array.dimset0,i); + snprintf(tmp,sizeof(tmp),"dims[%d]={\n",i); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp)," ocname=%s\n",dim->ocname); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp)," ncbasename=%s\n",dim->ncbasename); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp)," dimflags=%u\n", + (unsigned int)dim->dim.dimflags); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp)," declsize=%lu\n", + (unsigned long)dim->dim.declsize); + ncbytescat(buf,tmp); + snprintf(tmp,sizeof(tmp)," }\n"); + ncbytescat(buf,tmp); + } + + result = ncbytesdup(buf); + ncbytesfree(buf); + return result; +} + +char* +dumpalign(NCalignment* ncalign) +{ + char* result; + char tmp[1024]; + if(ncalign == NULL) + result = nulldup("NCalignment{size=-- alignment=-- offset=--}"); + else { + snprintf(tmp,sizeof(tmp),"NCalignment{size=%lu alignment=%lu offset=%lu}", + ncalign->size,ncalign->alignment,ncalign->offset); + result = nulldup(tmp); + } + return result; +} + +char* +dumpcachenode(NCcachenode* node) +{ + char* result = NULL; + char tmp[8192]; + int i; + NCbytes* buf; + + if(node == NULL) return strdup("cachenode{null}"); + buf = ncbytesnew(); + result = buildconstraintstring3(node->constraint); + snprintf(tmp,sizeof(tmp),"cachenode%s(%lx){size=%lu; constraint=%s; vars=", + node->prefetch?"*":"", + (unsigned long)node, + (unsigned long)node->xdrsize, + result); + ncbytescat(buf,tmp); + if(nclistlength(node->vars)==0) + ncbytescat(buf,"null"); + else for(i=0;ivars);i++) { + CDFnode* var = (CDFnode*)nclistget(node->vars,i); + if(i > 0) ncbytescat(buf,","); + ncbytescat(buf,makecdfpathstring3(var,".")); + } + ncbytescat(buf,"}"); + result = ncbytesdup(buf); + ncbytesfree(buf); + return result; +} + +char* +dumpcache(NCcache* cache) +{ + char* result = NULL; + char tmp[8192]; + int i; + NCbytes* buf; + + if(cache == NULL) return strdup("cache{null}"); + buf = ncbytesnew(); + snprintf(tmp,sizeof(tmp),"cache{limit=%lu; size=%lu;\n", + (unsigned long)cache->cachelimit, + (unsigned long)cache->cachesize); + ncbytescat(buf,tmp); + if(cache->prefetch) { + ncbytescat(buf,"\tprefetch="); + ncbytescat(buf,dumpcachenode(cache->prefetch)); + ncbytescat(buf,"\n"); + } + if(nclistlength(cache->nodes) > 0) { + for(i=0;inodes);i++) { + NCcachenode* node = (NCcachenode*)nclistget(cache->nodes,i); + ncbytescat(buf,"\t"); + ncbytescat(buf,dumpcachenode(node)); + ncbytescat(buf,"\n"); + } + } + ncbytescat(buf,"}"); + result = ncbytesdup(buf); + ncbytesfree(buf); + return result; +} + +/* This should be consistent with makeslicestring3 in constraints3.c */ +char* +dumpslice(DCEslice* slice) +{ + char buf[8192]; + char tmp[8192]; + size_t last = (slice->first+slice->length)-1; + buf[0] = '\0'; + if(last > slice->declsize && slice->declsize > 0) + last = slice->declsize - 1; + if(slice->count == 1) { + snprintf(tmp,sizeof(tmp),"[%lu]", + (unsigned long)slice->first); + } else if(slice->stride == 1) { + snprintf(tmp,sizeof(tmp),"[%lu:%lu]", + (unsigned long)slice->first, + (unsigned long)last); + } else { + snprintf(tmp,sizeof(tmp),"[%lu:%lu:%lu]", + (unsigned long)slice->first, + (unsigned long)slice->stride, + (unsigned long)last); + } + strcat(buf,tmp); + return strdup(tmp); +} + +char* +dumpslices(DCEslice* slice, unsigned int rank) +{ + int i; + NCbytes* buf; + char* result = NULL; + + buf = ncbytesnew(); + for(i=0;i +#include "dapparselex.h" + +#undef URLCVT /* NEVER turn this on */ +#define DAP2ENCODE + +/* Forward */ +static void dumptoken(DAPlexstate* lexstate); +static void dapaddyytext(DAPlexstate* lex, int c); +#ifndef DAP2ENCODE +static int tohex(int c); +#endif + +/****************************************************/ + +#if 0 /* Following definitions are for informational purposes */ +/* Set of all ascii printable characters */ +static char ascii[] = " !\"#$%&'()*+,-./:;<=>?@[]\\^_`|{}~"; + +/* Define the set of legal nonalphanum characters as specified in the DAP2 spec. */ +static char* daplegal ="_!~*'-\""; +#endif + +static char* ddsworddelims = + "{}[]:;=,"; + +/* Define 1 and > 1st legal characters */ +static char* ddswordchars1 = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\.*"; +static char* ddswordcharsn = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\.*#"; +static char* daswordcharsn = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\.*#:"; +static char* cewordchars1 = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\"; +static char* cewordcharsn = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\"; + +/* Current sets of legal characters */ +/* +static char* wordchars1 = NULL; +static char* wordcharsn = NULL; +static char* worddelims = NULL; +*/ + +static char* keywords[] = { +"alias", +"array", +"attributes", +"byte", +"dataset", +"error", +"float32", +"float64", +"grid", +"int16", +"int32", +"maps", +"sequence", +"string", +"structure", +"uint16", +"uint32", +"url", +"code", +"message", +"program_type", +"program", +NULL /* mark end of the keywords list */ +}; + +static int keytokens[] = { +SCAN_ALIAS, +SCAN_ARRAY, +SCAN_ATTR, +SCAN_BYTE, +SCAN_DATASET, +SCAN_ERROR, +SCAN_FLOAT32, +SCAN_FLOAT64, +SCAN_GRID, +SCAN_INT16, +SCAN_INT32, +SCAN_MAPS, +SCAN_SEQUENCE, +SCAN_STRING, +SCAN_STRUCTURE, +SCAN_UINT16, +SCAN_UINT32, +SCAN_URL, +SCAN_CODE, +SCAN_MESSAGE, +SCAN_PTYPE, +SCAN_PROG +}; + +/**************************************************/ + +int +daplex(YYSTYPE* lvalp, DAPparsestate* state) +{ + DAPlexstate* lexstate = state->lexstate; + int token; + int c; + unsigned int i; + char* p; + char* tmp; + + token = 0; + ocbytesclear(lexstate->yytext); + /* invariant: p always points to current char */ + for(p=lexstate->next;token==0&&(c=*p);p++) { + if(c == '\n') { + lexstate->lineno++; + } else if(c <= ' ' || c == '\177') { + /* whitespace: ignore */ + } else if(c == '#') { + /* single line comment */ + while((c=*(++p))) {if(c == '\n') break;} + } else if(strchr(lexstate->worddelims,c) != NULL) { + /* don't put in lexstate->yytext to avoid memory leak */ + token = c; + } else if(c == '"') { + int more = 1; + /* We have a string token; will be reported as WORD_STRING */ + while(more && (c=*(++p))) { +#ifdef DAP2ENCODE + if(c == '"') + more = 0; + else if(c == '\\') { + /* Remove spec ambiguity by convering \c to c + for any character c */ + c=*(++p); + if(c == '\0') more = 0; + } +#else /*Non-standard*/ + switch (c) { + case '"': more=0; break; + case '\\': + c=*(++p); + switch (c) { + case 'r': c = '\r'; break; + case 'n': c = '\n'; break; + case 'f': c = '\f'; break; + case 't': c = '\t'; break; + case 'x': { + int d1,d2; + c = '?'; + ++p; + d1 = tohex(*p++); + if(d1 < 0) { + daperror(state,"Illegal \\xDD in TOKEN_STRING"); + } else { + d2 = tohex(*p++); + if(d2 < 0) { + daperror(state,"Illegal \\xDD in TOKEN_STRING"); + } else { + c=(((unsigned int)d1)<<4) | (unsigned int)d2; + } + } + } break; + default: break; + } + break; + default: break; + } +#endif /*!DAP2ENCODE*/ + if(more) dapaddyytext(lexstate,c); + } + token=WORD_STRING; + } else if(strchr(lexstate->wordchars1,c) != NULL) { + int isdatamark = 0; + /* we have a WORD_WORD */ + dapaddyytext(lexstate,c); + while((c=*(++p))) { +#ifdef URLCVT + if(c == '%' && p[1] != 0 && p[2] != 0 + && strchr(hexdigits,p[1]) != NULL + && strchr(hexdigits,p[2]) != NULL) { + int d1,d2; + d1 = tohex(p[1]); + d2 = tohex(p[2]); + if(d1 >= 0 || d2 >= 0) { + c=(((unsigned int)d1)<<4) | (unsigned int)d2; + p+=2; + } + } else { + if(strchr(lexstate->wordcharsn,c) == NULL) {p--; break;} + } + dapaddyytext(lexstate,c); +#else + if(strchr(lexstate->wordcharsn,c) == NULL) {p--; break;} + dapaddyytext(lexstate,c); +#endif + } + /* Special check for Data: */ + tmp = ocbytescontents(lexstate->yytext); + if(strcmp(tmp,"Data")==0 && *p == ':') { + dapaddyytext(lexstate,*p); p++; + if(p[0] == '\n') { + token = SCAN_DATA; + isdatamark = 1; + p++; + } else if(p[0] == '\r' && p[1] == '\n') { + token = SCAN_DATA; + isdatamark = 1; + p+=2; + } + } + if(!isdatamark) { + /* check for keyword */ + token=WORD_WORD; /* assume */ + for(i=0;;i++) { + if(keywords[i] == NULL) break; + if(strcasecmp(keywords[i],tmp)==0) { + token=keytokens[i]; + break; + } + } + } + } else { /* illegal */ + } + } + lexstate->next = p; + strncpy(lexstate->lasttokentext,ocbytescontents(lexstate->yytext),MAX_TOKEN_LENGTH); + lexstate->lasttoken = token; + if(ocdebug >= 2) + dumptoken(lexstate); + + /*Put return value onto Bison stack*/ + + if(ocbyteslength(lexstate->yytext) == 0) + *lvalp = NULL; + else { + *lvalp = ocbytesdup(lexstate->yytext); + oclistpush(lexstate->reclaim,(ocelem)*lvalp); + } + return token; /* Return the type of the token. */ +} + +static void +dapaddyytext(DAPlexstate* lex, int c) +{ + ocbytesappend(lex->yytext,(char)c); +} + +#ifndef DAP2ENCODE +static int +tohex(int c) +{ + if(c >= 'a' && c <= 'f') return (c - 'a') + 0xa; + if(c >= 'A' && c <= 'F') return (c - 'A') + 0xa; + if(c >= '0' && c <= '9') return (c - '0'); + return -1; +} +#endif + +static void +dumptoken(DAPlexstate* lexstate) +{ + fprintf(stderr,"TOKEN = |%s|\n",ocbytescontents(lexstate->yytext)); +} + +/* +Simple lexer +*/ + +void +dapsetwordchars(DAPlexstate* lexstate, int kind) +{ + switch (kind) { + case 0: + lexstate->worddelims = ddsworddelims; + lexstate->wordchars1 = ddswordchars1; + lexstate->wordcharsn = ddswordcharsn; + break; + case 1: + lexstate->worddelims = ddsworddelims; + lexstate->wordchars1 = ddswordchars1; + lexstate->wordcharsn = daswordcharsn; + break; + case 2: + lexstate->worddelims = ddsworddelims; + lexstate->wordchars1 = cewordchars1; + lexstate->wordcharsn = cewordcharsn; + break; + default: break; + } +} + +void +daplexinit(char* input, DAPlexstate** lexstatep) +{ + DAPlexstate* lexstate = (DAPlexstate*)malloc(sizeof(DAPlexstate)); + if(lexstatep) *lexstatep = lexstate; + if(lexstate == NULL) return; + memset((void*)lexstate,0,sizeof(DAPlexstate)); + lexstate->input = strdup(input); + lexstate->next = lexstate->input; + lexstate->yytext = ocbytesnew(); + lexstate->reclaim = oclistnew(); + dapsetwordchars(lexstate,0); /* Assume DDS */ +} + +void +daplexcleanup(DAPlexstate** lexstatep) +{ + DAPlexstate* lexstate = *lexstatep; + if(lexstate == NULL) return; + if(lexstate->input != NULL) ocfree(lexstate->input); + if(lexstate->reclaim != NULL) { + while(oclistlength(lexstate->reclaim) > 0) { + char* word = (char*)oclistpop(lexstate->reclaim); + if(word) free(word); + } + oclistfree(lexstate->reclaim); + } + ocbytesfree(lexstate->yytext); + free(lexstate); + *lexstatep = NULL; +} + +/* Dap identifiers will come to us with some + characters escaped using the URL notation of + %HH. The assumption here is that any character + that is encoded is left encoded, except as follows: + 1. if the encoded character is in fact a legal DAP2 character + (alphanum+"_!~*'-\"") then it is decoded, otherwise not. +*/ +#ifndef DECODE_IDENTIFIERS +static char* decodelist = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_!~*'-\""; +#endif + +char* +dapdecode(DAPlexstate* lexstate, char* name) +{ + char* decoded; +#ifdef DECODE_IDENTIFIERS + decoded = ocuridecode(name); +#else + decoded = ocuridecodeonly(name,decodelist); +#endif + oclistpush(lexstate->reclaim,(ocelem)decoded); + return decoded; +} diff --git a/extern/src_netcdf4/dapnc.h b/extern/src_netcdf4/dapnc.h new file mode 100644 index 0000000000000000000000000000000000000000..c75482b31294a6b403bb379a27c8884399c86a0b --- /dev/null +++ b/extern/src_netcdf4/dapnc.h @@ -0,0 +1,21 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapnc.h,v 1.10 2009/09/23 22:26:01 dmh Exp $ + *********************************************************************/ +#ifndef DAPNC_H +#define DAPNC_H + +/* Take some types from libsrc4/netcdf.h*/ +#define NC_UBYTE 7 /* unsigned 1 byte int */ +#define NC_USHORT 8 /* unsigned 2-byte int */ +#define NC_UINT 9 /* unsigned 4-byte int */ +#define NC_INT64 10 /* signed 8-byte int */ +#define NC_UINT64 11 /* unsigned 8-byte int */ +#define NC_STRING 12 /* string */ +#define NC_VLEN 13 /* used internally for vlen types */ +#define NC_OPAQUE 14 /* used internally for opaque types */ +#define NC_ENUM 15 /* used internally for enum types */ +#define NC_COMPOUND 16 /* used internally for compound types */ + +#endif /*DAPNC_H*/ diff --git a/extern/src_netcdf4/dapodom.c b/extern/src_netcdf4/dapodom.c new file mode 100644 index 0000000000000000000000000000000000000000..7b34d141d5156aaa0394ecce89e5ba5f3a90be60 --- /dev/null +++ b/extern/src_netcdf4/dapodom.c @@ -0,0 +1,252 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapodom.c,v 1.12 2010/05/27 21:34:08 dmh Exp $ + *********************************************************************/ + +#include "ncdap3.h" +#include "dapodom.h" + +/**********************************************/ +/* Define methods for a dimension dapodometer*/ + +Dapodometer* +newdapodometer(DCEslice* slices, unsigned int first, unsigned int rank) +{ + int i; + Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); + MEMCHECK(odom,NULL); + if(rank == 0) { + return newdapodometer1(1); + } + odom->rank = rank; + ASSERT(odom->rank <= NC_MAX_VAR_DIMS); + for(i=0;irank;i++) { + DCEslice* slice = slices+(first+i); + odom->slices[i] = *slice; + odom->index[i] = odom->slices[i].first; + } + return odom; +} + +Dapodometer* +newsimpledapodometer(DCEsegment* segment, unsigned int rank) +{ + int i; + Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); + MEMCHECK(odom,NULL); + if(rank == 0) { + return newdapodometer1(1); + } + odom->rank = rank; + assert(odom->rank <= NC_MAX_VAR_DIMS); + assert(segment->slicesdefined && segment->slicesdeclized); + for(i=0;irank;i++) { + DCEslice* odslice = &odom->slices[i]; + DCEslice* segslice = &segment->slices[i]; + odslice->first = 0; + odslice->stride = 1; + odslice->declsize = segslice->count; + odslice->length = odslice->declsize; + odslice->stop = odslice->declsize; + odslice->count = odslice->declsize; + odom->index[i] = 0; + } + return odom; +} + +Dapodometer* +newdapodometer1(unsigned int count) +{ + Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); + MEMCHECK(odom,NULL); + odom->rank = 1; + odom->slices[0].first = 0; + odom->slices[0].length = count; + odom->slices[0].stride = 1; + odom->slices[0].stop = count; + odom->slices[0].declsize = count; + odom->slices[0].count = count; + odom->index[0] = 0; + return odom; +} + +void +freedapodometer(Dapodometer* odom) +{ + if(odom) free(odom); +} + +char* +dapodometerprint(Dapodometer* odom) +{ + int i; + static char line[1024]; + char tmp[64]; + line[0] = '\0'; + if(odom->rank == 0) { + strcat(line,"[]"); + } else for(i=0;irank;i++) { + sprintf(tmp,"[%lu/%lu:%lu:%lu]", + (unsigned long)odom->index[i], + (unsigned long)odom->slices[i].first, + (unsigned long)odom->slices[i].stride, + (unsigned long)odom->slices[i].length); + strcat(line,tmp); + } + return line; +} + +int +dapodometermore(Dapodometer* odom) +{ + return (odom->index[0] < odom->slices[0].stop); +} + +void +dapodometerreset(Dapodometer* odom) +{ + int rank = odom->rank; + while(rank-- > 0) {odom->index[rank] = odom->slices[rank].first;} +} + +/* Convert current dapodometer settings to a single integer count*/ +size_t +dapodometercount(Dapodometer* odom) +{ + int i; + size_t offset = 0; + for(i=0;irank;i++) { + offset *= odom->slices[i].declsize; + offset += odom->index[i]; + } + return offset; +} + +/* +Given a dapodometer, compute the total +number of elements in its space +as determined by declsize; start at +offset wheel +*/ + +size_t +dapodometerspace(Dapodometer* odom, unsigned int wheel) +{ + unsigned int i,rank = odom->rank; + size_t count = 1; + DCEslice* slice; + ASSERT((wheel < rank)); + slice = odom->slices+wheel; + for(i=wheel;ideclsize; + } + return count; +} + +/* +Compute the number of elements +that will be returned as the odometer +is incremented to its stop point. +*/ + +size_t +dapodometerpoints(Dapodometer* odom) +{ + unsigned int i,rank = odom->rank; + size_t count = 1; + DCEslice* slice = odom->slices; + for(i=0;ilength/slice->stride); + count *= slicecount; + } + return count; +} + +int +dapodometerincr(Dapodometer* odom) +{ + return dapodometerincrith(odom,-1); +} + +int +dapodometerincrith(Dapodometer* odom, int wheel) +{ + int i; /* do not make unsigned */ + DCEslice* slice; + if(odom->rank == 0) return 0; + if(wheel < 0) wheel = (odom->rank - 1); + for(slice=odom->slices+(wheel),i=wheel;i>=0;i--,slice--) { + odom->index[i] += slice->stride; + if(odom->index[i] < slice->stop) break; + if(i == 0) return 0; /* leave the 0th entry if it overflows*/ + odom->index[i] = slice->first; /* reset this position*/ + } + return 1; +} + +/**************************************************/ +int +dapodometervarmcount(Dapodometer* odom, const ptrdiff_t* steps, const size_t* declsizes) +{ + int i; + size_t offset = 0; + for(i=0;irank;i++) { + size_t tmp; + tmp = odom->index[i]; + tmp = tmp - odom->slices[i].first; + tmp = tmp / odom->slices[i].stride; + tmp = tmp * steps[i]; + offset += tmp; + } + return offset; +} + + +/* Return the current set of indices */ +size_t* +dapodometerindices(Dapodometer* odom) +{ + if(odom == NULL) return NULL; + return odom->index; +} + +Dapodometer* +newdapodometer2(const size_t* start, const size_t* count, const ptrdiff_t* stride, + unsigned int first, unsigned int rank) +{ + int i; + Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); + MEMCHECK(odom,NULL); + odom->rank = rank; + assert(odom->rank <= NC_MAX_VAR_DIMS); + for(i=0;irank;i++) { + odom->slices[i].first = start[first+i]; + odom->slices[i].stride = (size_t)stride[first+i]; + odom->slices[i].length = count[first+i] * stride[first+i]; + odom->slices[i].stop = (odom->slices[i].first+odom->slices[i].length); + odom->slices[i].declsize = odom->slices[i].stop; + odom->slices[i].count = (odom->slices[i].length /odom->slices[i].stride); + odom->index[i] = odom->slices[i].first; + } + return odom; +} + +Dapodometer* +newdapodometer3(int rank, size_t* dimsizes) +{ + int i; + Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); + MEMCHECK(odom,NULL); + odom->rank = rank; + for(i=0;islices[i].first = 0; + odom->slices[i].length = dimsizes[i]; + odom->slices[i].stride = 1; + odom->slices[i].stop = dimsizes[i]; + odom->slices[i].declsize = dimsizes[i]; + odom->slices[i].count = (odom->slices[i].length / odom->slices[i].stride); + odom->index[i] = 0; + } + return odom; +} diff --git a/extern/src_netcdf4/dapodom.h b/extern/src_netcdf4/dapodom.h new file mode 100644 index 0000000000000000000000000000000000000000..05c10ac64ee94c1d3aa020b2d46820f7d2f61fb8 --- /dev/null +++ b/extern/src_netcdf4/dapodom.h @@ -0,0 +1,42 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header$ + *********************************************************************/ + +#ifndef DAPODOM_H +#define DAPODOM_H 1 + +typedef struct Dapodometer { + int rank; + DCEslice slices[NC_MAX_VAR_DIMS]; + size_t index[NC_MAX_VAR_DIMS]; +} Dapodometer; + +/* Odometer operators*/ +extern Dapodometer* newdapodometer(DCEslice* slices, unsigned int first, unsigned int count); + +extern Dapodometer* newsimpledapodometer(struct DCEsegment*,unsigned int); + +extern Dapodometer* newdapodometer1(unsigned int count); +extern Dapodometer* newdapodometer2(const size_t*, const size_t*, + const ptrdiff_t*, unsigned int, unsigned int); +extern Dapodometer* newdapodometer3(int, size_t*); + +extern void freedapodometer(Dapodometer*); +extern char* dapodometerprint(Dapodometer* odom); + +extern int dapodometermore(Dapodometer* odom); +extern int dapodometerincr(Dapodometer* odo); +extern int dapodometerincrith(Dapodometer* odo,int); +extern size_t dapodometercount(Dapodometer* odo); +extern void dapodometerreset(Dapodometer*); +extern Dapodometer* dapodometersplit(Dapodometer* odom, int tail); + +extern size_t dapodometerspace(Dapodometer* odom, unsigned int wheel); +extern size_t dapodometerpoints(Dapodometer*); + +extern size_t* dapodometerindices(Dapodometer*); +extern int dapodometervarmcount(Dapodometer*, const ptrdiff_t*, const size_t*); + +#endif /*DAPODOM_H*/ diff --git a/extern/src_netcdf4/dapparse.c b/extern/src_netcdf4/dapparse.c new file mode 100644 index 0000000000000000000000000000000000000000..a3a1a16650c2e5c88e290429f60d0e9af5aefc41 --- /dev/null +++ b/extern/src_netcdf4/dapparse.c @@ -0,0 +1,480 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include "dapparselex.h" + +/* Forward */ + +static void addedges(OCnode* node); +static void setroot(OCnode*,OClist*); +static int isglobalname(char* name); +static OCnode* newocnode(char* name, OCtype octype, DAPparsestate* state); +static OCtype octypefor(Object etype); +static char* scopeduplicates(OClist* list); +static int check_int32(char* val, long* value); + + +/****************************************************/ + +/* Switch to DAS parsing SCAN_WORD definition */ + +/* Use the initial keyword to indicate what we are parsing */ +void +dap_tagparse(DAPparsestate* state, int kind) +{ + switch (kind) { + case SCAN_DATASET: + case SCAN_ERROR: + break; + case SCAN_ATTR: + dapsetwordchars(state->lexstate,1); + break; + default: + fprintf(stderr,"tagparse: Unknown tag argument: %d\n",kind); + } +} + + +Object +dap_datasetbody(DAPparsestate* state, Object name, Object decls) +{ + OCnode* root = newocnode((char*)name,OC_Dataset,state); + root->subnodes = (OClist*)decls; + OCASSERT((state->root == NULL)); + state->root = root; + state->root->root = state->root; /* make sure to cross link */ + addedges(root); + setroot(root,state->ocnodes); + return NULL; +} + +Object +dap_attributebody(DAPparsestate* state, Object attrlist) +{ + OCnode* node = newocnode(NULL,OC_Attributeset,state); + OCASSERT((state->root == NULL)); + state->root = node; + /* make sure to cross link */ + state->root->root = state->root; + node->subnodes = (OClist*)attrlist; + addedges(node); + return NULL; +} + +void +dap_errorbody(DAPparsestate* state, + Object code, Object msg, Object ptype, Object prog) +{ + state->svcerror = 1; + state->code = nulldup((char*)code); + state->message = nulldup((char*)msg); + /* Ignore ptype and prog for now */ +} + +void +dap_unrecognizedresponse(DAPparsestate* state) +{ + /* see if this is an HTTP error */ + unsigned int httperr = 0; + int i; + char iv[32]; + sscanf(state->lexstate->input,"%u ",&httperr); + sprintf(iv,"%u",httperr); + state->lexstate->next = state->lexstate->input; + /* Limit the amount of input to prevent runaway */ + for(i=0;i<4096;i++) {if(state->lexstate->input[i] == '\0') break;} + state->lexstate->input[i] = '\0'; + dap_errorbody(state,iv,state->lexstate->input,NULL,NULL); +} + +Object +dap_declarations(DAPparsestate* state, Object decls, Object decl) +{ + OClist* alist = (OClist*)decls; + if(alist == NULL) + alist = oclistnew(); + else + oclistpush(alist,(ocelem)decl); + return alist; +} + +Object +dap_arraydecls(DAPparsestate* state, Object arraydecls, Object arraydecl) +{ + OClist* alist = (OClist*)arraydecls; + if(alist == NULL) + alist = oclistnew(); + else + oclistpush(alist,(ocelem)arraydecl); + return alist; +} + +Object +dap_arraydecl(DAPparsestate* state, Object name, Object size) +{ + long value; + OCnode* dim; + if(!check_int32(size,&value)) + dap_parse_error(state,"Dimension not an integer"); + if(name != NULL) + dim = newocnode((char*)name,OC_Dimension,state); + else + dim = newocnode(NULL,OC_Dimension,state); + dim->dim.declsize = value; + return dim; +} + +Object +dap_attrlist(DAPparsestate* state, Object attrlist, Object attrtuple) +{ + OClist* alist = (OClist*)attrlist; + if(alist == NULL) + alist = oclistnew(); + else { + char* dupname; + if(attrtuple != NULL) {/* NULL=>alias encountered, ignore */ + oclistpush(alist,(ocelem)attrtuple); + if((dupname=scopeduplicates(alist))!=NULL) { + dap_parse_error(state,"Duplicate attribute names in same scope: %s",dupname); + /* Remove this attribute */ + oclistpop(alist); + } + } + } + return alist; +} + +Object +dap_attrvalue(DAPparsestate* state, Object valuelist, Object value, Object etype) +{ + OClist* alist = (OClist*)valuelist; + if(alist == NULL) alist = oclistnew(); + /* Watch out for null values */ + if(value == NULL) value = ""; + oclistpush(alist,(ocelem)strdup(value)); + return alist; +} + +Object +dap_attribute(DAPparsestate* state, Object name, Object values, Object etype) +{ + OCnode* att; + att = newocnode((char*)name,OC_Attribute,state); + att->etype = octypefor(etype); + att->att.values = (OClist*)values; + return att; +} + +Object +dap_attrset(DAPparsestate* state, Object name, Object attributes) +{ + OCnode* attset; + attset = newocnode((char*)name,OC_Attributeset,state); + /* Check var set vs global set */ + attset->att.isglobal = isglobalname(name); + attset->subnodes = (OClist*)attributes; + addedges(attset); + return attset; +} + +static int +isglobalname(char* name) +{ + int len = strlen(name); + int glen = strlen("global"); + char* p; + if(len < glen) return 0; + p = name + (len - glen); + if(strcasecmp(p,"global") != 0) + return 0; + return 1; +} + +#if 0 +static int +isnumber(const char* text) +{ + for(;*text;text++) {if(!isdigit(*text)) return 0;} + return 1; +} +#endif + +static void +dimension(OCnode* node, OClist* dimensions) +{ + unsigned int i; + unsigned int rank = oclistlength(dimensions); + node->array.dimensions = (OClist*)dimensions; + node->array.rank = rank; + for(i=0;iarray.dimensions,i); + dim->dim.array = node; + dim->dim.arrayindex = i; +#if 0 + if(dim->name == NULL) { + dim->dim.anonymous = 1; + dim->name = dimnameanon(node->name,i); + } +#endif + } +} + +char* +dimnameanon(char* basename, unsigned int index) +{ + char name[64]; + sprintf(name,"%s_%d",basename,index); + return strdup(name); +} + +Object +dap_makebase(DAPparsestate* state, Object name, Object etype, Object dimensions) +{ + OCnode* node; + node = newocnode((char*)name,OC_Primitive,state); + node->etype = octypefor(etype); + dimension(node,(OClist*)dimensions); + return node; +} + +Object +dap_makestructure(DAPparsestate* state, Object name, Object dimensions, Object fields) +{ + OCnode* node; + char* dupname; + if((dupname=scopeduplicates((OClist*)fields))!= NULL) { + dap_parse_error(state,"Duplicate structure field names in same scope: %s.%s",(char*)name,dupname); + return (Object)NULL; + } + node = newocnode(name,OC_Structure,state); + node->subnodes = fields; + dimension(node,(OClist*)dimensions); + addedges(node); + return node; +} + +Object +dap_makesequence(DAPparsestate* state, Object name, Object members) +{ + OCnode* node; + char* dupname; + if((dupname=scopeduplicates((OClist*)members)) != NULL) { + dap_parse_error(state,"Duplicate sequence member names in same scope: %s.%s",(char*)name,dupname); + return (Object)NULL; + } + node = newocnode(name,OC_Sequence,state); + node->subnodes = members; + addedges(node); + return node; +} + +Object +dap_makegrid(DAPparsestate* state, Object name, Object arraydecl, Object mapdecls) +{ + OCnode* node; + /* Check for duplicate map names */ + char* dupname; + if((dupname=scopeduplicates((OClist*)mapdecls)) != NULL) { + dap_parse_error(state,"Duplicate grid map names in same scope: %s.%s",(char*)name,dupname); + return (Object)NULL; + } + node = newocnode(name,OC_Grid,state); + node->subnodes = (OClist*)mapdecls; + oclistinsert(node->subnodes,0,(ocelem)arraydecl); + addedges(node); + return node; +} + +static void +addedges(OCnode* node) +{ + unsigned int i; + if(node->subnodes == NULL) return; + for(i=0;isubnodes);i++) { + OCnode* subnode = (OCnode*)oclistget(node->subnodes,i); + subnode->container = node; + } +} + +static void +setroot(OCnode* root, OClist* ocnodes) +{ + int i; + for(i=0;iroot = root; + } +} + +int +daperror(DAPparsestate* state, const char* msg) +{ + dap_parse_error(state,msg); + return 0; +} + +static char* +flatten(char* s, char* tmp, int tlen) +{ + int c; + char* p,*q; + strncpy(tmp,s,tlen); + tmp[tlen] = '\0'; + p = (q = tmp); + while((c=*p++)) { + switch (c) { + case '\r': case '\n': break; + case '\t': *q++ = ' '; break; + case ' ': if(*p != ' ') *q++ = c; break; + default: *q++ = c; + } + } + *q = '\0'; + return tmp; +} + +/* Create an ocnode and capture in the state->ocnode list */ +static OCnode* +newocnode(char* name, OCtype octype, DAPparsestate* state) +{ + OCnode* node = ocmakenode(name,octype,state->root); + oclistpush(state->ocnodes,(ocelem)node); + return node; +} + +static int +check_int32(char* val, long* value) +{ + char* ptr; + int ok = 1; + long iv = strtol(val,&ptr,0); /* 0=>auto determine base */ + if((iv == 0 && val == ptr) || *ptr != '\0') {ok=0; iv=1;} + else if(iv > OC_INT32_MAX || iv < OC_INT32_MIN) ok=0; + if(value != NULL) *value = iv; + return ok; +} + +static char* +scopeduplicates(OClist* list) +{ + unsigned int i,j; + for(i=0;iname,jo->name)==0) + return io->name; + } + } + return NULL; +} + +static OCtype +octypefor(Object etype) +{ + switch ((long)etype) { + case SCAN_BYTE: return OC_Byte; + case SCAN_INT16: return OC_Int16; + case SCAN_UINT16: return OC_UInt16; + case SCAN_INT32: return OC_Int32; + case SCAN_UINT32: return OC_UInt32; + case SCAN_FLOAT32: return OC_Float32; + case SCAN_FLOAT64: return OC_Float64; + case SCAN_URL: return OC_URL; + case SCAN_STRING: return OC_String; + default: abort(); + } + return OC_NAT; +} + +void +dap_parse_error(DAPparsestate* state, const char *fmt, ...) +{ + size_t len, suffixlen, prefixlen; + va_list argv; + char* tmp = NULL; + va_start(argv,fmt); + (void) vfprintf(stderr,fmt,argv) ; + (void) fputc('\n',stderr) ; + len = strlen(state->lexstate->input); + suffixlen = strlen(state->lexstate->next); + prefixlen = (len - suffixlen); + tmp = (char*)ocmalloc(len+1); + flatten(state->lexstate->input,tmp,prefixlen); + (void) fprintf(stderr,"context: %s",tmp); + flatten(state->lexstate->next,tmp,suffixlen); + (void) fprintf(stderr,"^%s\n",tmp); + (void) fflush(stderr); /* to ensure log files are current */ + ocfree(tmp); +} + +static void +dap_parse_cleanup(DAPparsestate* state) +{ + daplexcleanup(&state->lexstate); + if(state->ocnodes != NULL) ocfreenodes(state->ocnodes); + state->ocnodes = NULL; + free(state); +} + +static DAPparsestate* +dap_parse_init(char* buf) +{ + DAPparsestate* state = (DAPparsestate*)ocmalloc(sizeof(DAPparsestate)); /*ocmalloc zeros*/ + MEMCHECK(state,(DAPparsestate*)NULL); + if(buf==NULL) { + dap_parse_error(state,"dap_parse_init: no input buffer"); + dap_parse_cleanup(state); + return NULL; + } + daplexinit(buf,&state->lexstate); + return state; +} + +/* Wrapper for dapparse */ +OCerror +DAPparse(OCstate* conn, OCtree* tree, char* parsestring) +{ + DAPparsestate* state = dap_parse_init(parsestring); + int parseresult; + OCerror ocerr = OC_NOERR; + state->ocnodes = oclistnew(); + state->conn = conn; + if(ocdebug >= 2) + dapdebug = 1; + parseresult = dapparse(state); + if(parseresult == 0) {/* 0 => parse ok */ + /* Check to see if we ended up parsing an error message */ + if(state->svcerror) { + conn->error.code = nulldup(state->code); + conn->error.message = nulldup(state->message); + tree->root = NULL; + /* Attempt to further decipher the error code */ + if(state->code != NULL + && (strcmp(state->code,"404") == 0 /* tds returns 404 */ + || strcmp(state->code,"5") == 0)) /* hyrax returns 5 */ + ocerr = OC_ENOFILE; + else + ocerr = OC_EDAPSVC; + } else { + OCASSERT((state->root != NULL)); + tree->root = state->root; + state->root = NULL; /* avoid reclaim */ + tree->nodes = state->ocnodes; + state->ocnodes = NULL; /* avoid reclaim */ + tree->root->tree = tree; + ocerr = OC_NOERR; + } + } else { /* Parse failed */ + switch (tree->dxdclass) { + case OCDAS: ocerr = OC_EDAS; break; + case OCDDS: ocerr = OC_EDDS; break; + case OCDATADDS: ocerr = OC_EDATADDS; break; + default: ocerr = OC_EDAPSVC; + } + } + dap_parse_cleanup(state); + return ocerr; +} + diff --git a/extern/src_netcdf4/dapparselex.h b/extern/src_netcdf4/dapparselex.h new file mode 100644 index 0000000000000000000000000000000000000000..36611575c0f4a5f292ccbac4ab2104e57e4b5fec --- /dev/null +++ b/extern/src_netcdf4/dapparselex.h @@ -0,0 +1,95 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef DAPPARSELEX_H +#define DAPPARSELEX_H 1 + +#include "ocinternal.h" +#include "ocdebug.h" +#ifdef USE_DAP +/* To avoid "make distclean" wiping out dap.tab.h */ +#include "daptab.h" +#else +#include "daptab.h" +#endif + +#ifdef WIN32 +#define strcasecmp stricmp +#define snprintf _snprintf +#endif + +/* For consistency with Java parser */ +#define null NULL + +typedef void* Object; + +#define YYSTYPE Object + +#define MAX_TOKEN_LENGTH 1024 + +/*! Specifies the Lexstate. */ +typedef struct DAPlexstate { + char* input; + char* next; /* next char in uri.query*/ + OCbytes* yytext; + int lineno; + /*! Specifies the Lasttoken. */ + int lasttoken; + char lasttokentext[MAX_TOKEN_LENGTH+1]; + char* wordchars1; + char* wordcharsn; + char* worddelims; + OClist* reclaim; /* reclaim WORD_WORD instances */ +} DAPlexstate; + +/*! Specifies the DAPparsestate. */ +typedef struct DAPparsestate { + struct OCnode* root; + DAPlexstate* lexstate; + OClist* ocnodes; + struct OCstate* conn; + /* For error returns from the server */ + int svcerror; /* 1 => we had an error from the server */ + char* code; + char* message; + char* progtype; + char* progname; + /* State for constraint expressions */ + struct CEstate* cestate; +} DAPparsestate; + +extern int daperror(DAPparsestate* state, const char* msg); +extern void dap_parse_error(DAPparsestate*,const char *fmt, ...); +/* bison parse entry point */ +extern int dapparse(DAPparsestate*); + +extern Object dap_datasetbody(DAPparsestate*,Object decls, Object name); +extern Object dap_declarations(DAPparsestate*,Object decls, Object decl); +extern Object dap_arraydecls(DAPparsestate*,Object arraydecls, Object arraydecl); +extern Object dap_arraydecl(DAPparsestate*,Object name, Object size); + +extern void dap_dassetup(DAPparsestate*); +extern Object dap_attributebody(DAPparsestate*,Object attrlist); +extern Object dap_attrlist(DAPparsestate*,Object attrlist, Object attrtuple); +extern Object dap_attribute(DAPparsestate*,Object name, Object value, Object etype); +extern Object dap_attrset(DAPparsestate*,Object name, Object attributes); +extern Object dap_attrvalue(DAPparsestate*,Object valuelist, Object value, Object etype); + +extern Object dap_makebase(DAPparsestate*,Object name, Object etype, Object dimensions); +extern Object dap_makestructure(DAPparsestate*,Object name, Object dimensions, Object fields); +extern Object dap_makesequence(DAPparsestate*,Object name, Object members); +extern Object dap_makegrid(DAPparsestate*,Object name, Object arraydecl, Object mapdecls); + +extern void dap_errorbody(DAPparsestate*, Object, Object, Object, Object); +extern void dap_unrecognizedresponse(DAPparsestate*); + +extern void dap_tagparse(DAPparsestate*,int); + +/* Lexer entry points */ +extern int daplex(YYSTYPE*, DAPparsestate*); +extern void daplexinit(char* input, DAPlexstate** lexstatep); +extern void daplexcleanup(DAPlexstate** lexstatep); +extern void dapsetwordchars(DAPlexstate* lexstate, int kind); +extern char* dapdecode(DAPlexstate*,char*); + +#endif /*DAPPARSELEX_H*/ diff --git a/extern/src_netcdf4/daptab.c b/extern/src_netcdf4/daptab.c new file mode 100644 index 0000000000000000000000000000000000000000..2de8f1e067f3e8110bdb71797515147bfba152a1 --- /dev/null +++ b/extern/src_netcdf4/daptab.c @@ -0,0 +1,2493 @@ +/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse dapparse +#define yylex daplex +#define yyerror daperror +#define yylval daplval +#define yychar dapchar +#define yydebug dapdebug +#define yynerrs dapnerrs + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 11 "dap.y" + +#include "config.h" +#include "dapparselex.h" +int dapdebug = 0; + + +/* Line 189 of yacc.c */ +#line 87 "dap.tab.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + SCAN_ALIAS = 258, + SCAN_ARRAY = 259, + SCAN_ATTR = 260, + SCAN_BYTE = 261, + SCAN_CODE = 262, + SCAN_DATASET = 263, + SCAN_DATA = 264, + SCAN_ERROR = 265, + SCAN_FLOAT32 = 266, + SCAN_FLOAT64 = 267, + SCAN_GRID = 268, + SCAN_INT16 = 269, + SCAN_INT32 = 270, + SCAN_MAPS = 271, + SCAN_MESSAGE = 272, + SCAN_SEQUENCE = 273, + SCAN_STRING = 274, + SCAN_STRUCTURE = 275, + SCAN_UINT16 = 276, + SCAN_UINT32 = 277, + SCAN_URL = 278, + SCAN_PTYPE = 279, + SCAN_PROG = 280, + WORD_WORD = 281, + WORD_STRING = 282 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 156 "dap.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 9 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 361 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 36 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 34 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 106 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 201 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 282 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 35, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 31, 30, + 2, 34, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 32, 2, 33, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 28, 2, 29, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 6, 10, 13, 16, 18, 20, 22, + 24, 30, 31, 34, 39, 47, 54, 66, 68, 70, + 72, 74, 76, 78, 80, 82, 84, 86, 87, 90, + 94, 99, 105, 107, 109, 111, 113, 117, 119, 120, + 123, 126, 131, 136, 141, 146, 151, 156, 161, 166, + 171, 176, 178, 180, 184, 186, 190, 192, 196, 198, + 202, 204, 208, 210, 214, 216, 220, 222, 226, 228, + 232, 234, 236, 238, 242, 250, 251, 256, 257, 262, + 263, 268, 269, 274, 276, 278, 280, 282, 284, 286, + 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, + 308, 310, 312, 314, 316, 318, 320 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 37, 0, -1, 38, 41, -1, 38, 41, 9, -1, + 39, 49, -1, 40, 64, -1, 1, -1, 8, -1, + 5, -1, 10, -1, 28, 42, 29, 47, 30, -1, + -1, 42, 43, -1, 44, 48, 45, 30, -1, 20, + 28, 42, 29, 48, 45, 30, -1, 18, 28, 42, + 29, 48, 30, -1, 13, 28, 4, 31, 43, 16, + 31, 42, 29, 48, 30, -1, 1, -1, 6, -1, + 14, -1, 21, -1, 15, -1, 22, -1, 11, -1, + 12, -1, 23, -1, 19, -1, -1, 45, 46, -1, + 32, 26, 33, -1, 32, 34, 26, 33, -1, 32, + 69, 34, 26, 33, -1, 1, -1, 48, -1, 1, + -1, 69, -1, 28, 50, 29, -1, 1, -1, -1, + 50, 51, -1, 63, 30, -1, 6, 69, 52, 30, + -1, 14, 69, 53, 30, -1, 21, 69, 54, 30, + -1, 15, 69, 55, 30, -1, 22, 69, 56, 30, + -1, 11, 69, 57, 30, -1, 12, 69, 58, 30, + -1, 19, 69, 59, 30, -1, 23, 69, 60, 30, + -1, 69, 28, 50, 29, -1, 1, -1, 26, -1, + 52, 35, 26, -1, 26, -1, 53, 35, 26, -1, + 26, -1, 54, 35, 26, -1, 26, -1, 55, 35, + 26, -1, 26, -1, 56, 35, 26, -1, 26, -1, + 57, 35, 26, -1, 26, -1, 58, 35, 26, -1, + 62, -1, 59, 35, 62, -1, 61, -1, 60, 35, + 61, -1, 69, -1, 69, -1, 27, -1, 3, 26, + 26, -1, 28, 65, 66, 67, 68, 29, 30, -1, + -1, 7, 34, 26, 30, -1, -1, 17, 34, 26, + 30, -1, -1, 24, 34, 26, 30, -1, -1, 25, + 34, 26, 30, -1, 26, -1, 3, -1, 4, -1, + 5, -1, 6, -1, 8, -1, 9, -1, 10, -1, + 11, -1, 12, -1, 13, -1, 14, -1, 15, -1, + 16, -1, 18, -1, 19, -1, 20, -1, 21, -1, + 22, -1, 23, -1, 7, -1, 17, -1, 25, -1, + 24, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 53, 53, 54, 55, 56, 57, 61, 65, 69, + 74, 80, 81, 87, 89, 91, 93, 96, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 114, 115, 119, + 120, 121, 122, 127, 128, 132, 135, 136, 141, 142, + 146, 147, 149, 151, 153, 155, 157, 159, 161, 163, + 165, 166, 171, 172, 176, 177, 181, 182, 186, 187, + 191, 192, 195, 196, 199, 200, 203, 204, 208, 209, + 213, 217, 218, 229, 233, 237, 237, 238, 238, 239, + 239, 240, 240, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "SCAN_ALIAS", "SCAN_ARRAY", "SCAN_ATTR", + "SCAN_BYTE", "SCAN_CODE", "SCAN_DATASET", "SCAN_DATA", "SCAN_ERROR", + "SCAN_FLOAT32", "SCAN_FLOAT64", "SCAN_GRID", "SCAN_INT16", "SCAN_INT32", + "SCAN_MAPS", "SCAN_MESSAGE", "SCAN_SEQUENCE", "SCAN_STRING", + "SCAN_STRUCTURE", "SCAN_UINT16", "SCAN_UINT32", "SCAN_URL", "SCAN_PTYPE", + "SCAN_PROG", "WORD_WORD", "WORD_STRING", "'{'", "'}'", "';'", "':'", + "'['", "']'", "'='", "','", "$accept", "start", "dataset", "attr", "err", + "datasetbody", "declarations", "declaration", "base_type", "array_decls", + "array_decl", "datasetname", "var_name", "attributebody", "attr_list", + "attribute", "bytes", "int16", "uint16", "int32", "uint32", "float32", + "float64", "strs", "urls", "url", "str_or_id", "alias", "errorbody", + "errorcode", "errormsg", "errorptype", "errorprog", "name", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 123, 125, + 59, 58, 91, 93, 61, 44 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 36, 37, 37, 37, 37, 37, 38, 39, 40, + 41, 42, 42, 43, 43, 43, 43, 43, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 45, 45, 46, + 46, 46, 46, 47, 47, 48, 49, 49, 50, 50, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, + 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, + 61, 62, 62, 63, 64, 65, 65, 66, 66, 67, + 67, 68, 68, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 2, 3, 2, 2, 1, 1, 1, 1, + 5, 0, 2, 4, 7, 6, 11, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 2, 3, + 4, 5, 1, 1, 1, 1, 3, 1, 0, 2, + 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 1, 1, 3, 1, 3, 1, 3, 1, 3, + 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, + 1, 1, 1, 3, 7, 0, 4, 0, 4, 0, + 4, 0, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 6, 8, 7, 9, 0, 0, 0, 0, 1, + 11, 2, 37, 38, 4, 75, 5, 0, 3, 0, + 0, 77, 17, 18, 23, 24, 0, 19, 21, 0, + 26, 0, 20, 22, 25, 0, 12, 0, 51, 84, + 85, 86, 87, 103, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 104, 97, 98, 99, 100, 101, 102, + 106, 105, 83, 36, 39, 0, 0, 0, 0, 79, + 0, 11, 11, 34, 84, 87, 91, 92, 94, 95, + 98, 100, 101, 102, 0, 33, 35, 27, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 40, 38, + 0, 0, 0, 81, 0, 0, 0, 10, 0, 73, + 52, 0, 62, 0, 64, 0, 54, 0, 58, 0, + 72, 0, 66, 71, 56, 0, 60, 0, 0, 68, + 70, 0, 76, 0, 0, 0, 0, 0, 0, 0, + 32, 13, 0, 28, 41, 0, 46, 0, 47, 0, + 42, 0, 44, 0, 48, 0, 43, 0, 45, 0, + 49, 0, 50, 78, 0, 0, 0, 0, 0, 27, + 83, 0, 0, 53, 63, 65, 55, 59, 67, 57, + 61, 69, 80, 0, 74, 0, 15, 0, 29, 0, + 0, 82, 11, 14, 30, 0, 0, 31, 0, 0, + 16 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 5, 6, 7, 8, 11, 17, 36, 37, 108, + 143, 84, 85, 14, 19, 64, 111, 117, 125, 119, + 127, 113, 115, 121, 128, 129, 122, 65, 16, 21, + 69, 103, 136, 86 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -70 +static const yytype_int16 yypact[] = +{ + 5, -70, -70, -70, -70, 8, -1, 3, 0, -70, + -70, 10, -70, -70, -70, 28, -70, 69, -70, 159, + 34, 57, -70, -70, -70, -70, 50, -70, -70, 58, + -70, 65, -70, -70, -70, 263, -70, 312, -70, 59, + -70, -70, 312, -70, -70, -70, -70, 312, 312, -70, + 312, 312, -70, -70, -70, 312, -70, 312, 312, 312, + -70, -70, -70, -70, -70, 64, 67, 70, 63, 75, + 96, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, 73, -70, -70, -70, 78, 79, + 80, 81, 82, 83, 287, 84, 85, 312, -70, -70, + 86, 88, 87, 90, 89, 127, 212, -70, 4, -70, + -70, -23, -70, -21, -70, -19, -70, -13, -70, -12, + -70, -10, -70, -70, -70, -9, -70, 36, 42, -70, + -70, 186, -70, 92, 91, 93, 97, 338, 312, 312, + -70, -70, 39, -70, -70, 99, -70, 103, -70, 104, + -70, 105, -70, 106, -70, 287, -70, 108, -70, 109, + -70, 312, -70, -70, 114, 110, 121, 102, 122, -70, + 120, 128, 123, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, 125, -70, 155, -70, 37, -70, 126, + 132, -70, -70, -70, -70, 181, 236, -70, 312, 187, + -70 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -70, -70, -70, -70, -70, -70, -69, -25, -70, -50, + -70, -70, -37, -70, 117, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, 60, 74, -70, -70, -70, + -70, -70, -70, -18 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 87, 66, 105, 106, 12, 140, 1, 144, 9, 146, + 2, 148, 145, 3, 147, 4, 149, 150, 152, 18, + 154, 156, 151, 153, 89, 155, 157, 10, 15, 90, + 91, 13, 92, 93, 141, 20, 142, 94, 140, 95, + 96, 97, 74, 40, 41, 75, 43, 44, 45, 46, + 76, 77, 49, 78, 79, 52, 53, 54, 80, 56, + 81, 82, 83, 60, 61, 170, 158, 193, 67, 142, + 22, 159, 160, 171, 68, 23, 123, 161, 70, 130, + 24, 25, 26, 27, 28, 88, 71, 29, 30, 31, + 32, 33, 34, 72, 98, 99, 100, 101, 35, 102, + 104, 168, 169, 107, 109, 110, 112, 114, 116, 118, + 124, 126, 167, 66, 133, 135, 132, 164, 185, 187, + 137, 134, 163, 196, 172, 173, 166, 165, 22, 174, + 175, 176, 177, 23, 179, 180, 183, 123, 24, 25, + 26, 27, 28, 130, 182, 29, 30, 31, 32, 33, + 34, 184, 186, 188, 189, 191, 138, 190, 195, 194, + 38, 199, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 192, 38, 63, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 22, 197, 162, 131, 200, 23, 0, + 0, 181, 0, 24, 25, 26, 27, 28, 0, 178, + 29, 30, 31, 32, 33, 34, 0, 22, 0, 0, + 0, 139, 23, 0, 0, 0, 0, 24, 25, 26, + 27, 28, 0, 0, 29, 30, 31, 32, 33, 34, + 0, 0, 0, 0, 73, 198, 74, 40, 41, 75, + 43, 44, 45, 46, 76, 77, 49, 78, 79, 52, + 53, 54, 80, 56, 81, 82, 83, 60, 61, 62, + 74, 40, 41, 75, 43, 44, 45, 46, 76, 77, + 49, 78, 79, 52, 53, 54, 80, 56, 81, 82, + 83, 60, 61, 62, 120, 74, 40, 41, 75, 43, + 44, 45, 46, 76, 77, 49, 78, 79, 52, 53, + 54, 80, 56, 81, 82, 83, 60, 61, 62, 22, + 0, 0, 0, 0, 23, 0, 0, 0, 0, 24, + 25, 26, 27, 28, 0, 0, 29, 30, 31, 32, + 33, 34 +}; + +static const yytype_int16 yycheck[] = +{ + 37, 19, 71, 72, 1, 1, 1, 30, 0, 30, + 5, 30, 35, 8, 35, 10, 35, 30, 30, 9, + 30, 30, 35, 35, 42, 35, 35, 28, 28, 47, + 48, 28, 50, 51, 30, 7, 32, 55, 1, 57, + 58, 59, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 30, 30, 34, 32, + 1, 35, 30, 34, 17, 6, 94, 35, 28, 97, + 11, 12, 13, 14, 15, 26, 28, 18, 19, 20, + 21, 22, 23, 28, 30, 28, 26, 34, 29, 24, + 4, 138, 139, 30, 26, 26, 26, 26, 26, 26, + 26, 26, 137, 131, 26, 25, 30, 26, 16, 169, + 31, 34, 30, 192, 142, 26, 29, 34, 1, 26, + 26, 26, 26, 6, 26, 26, 26, 155, 11, 12, + 13, 14, 15, 161, 30, 18, 19, 20, 21, 22, + 23, 30, 30, 33, 26, 30, 29, 34, 26, 33, + 1, 198, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 31, 1, 29, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 1, 33, 29, 99, 30, 6, -1, + -1, 161, -1, 11, 12, 13, 14, 15, -1, 155, + 18, 19, 20, 21, 22, 23, -1, 1, -1, -1, + -1, 29, 6, -1, -1, -1, -1, 11, 12, 13, + 14, 15, -1, -1, 18, 19, 20, 21, 22, 23, + -1, -1, -1, -1, 1, 29, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 1, + -1, -1, -1, -1, 6, -1, -1, -1, -1, 11, + 12, 13, 14, 15, -1, -1, 18, 19, 20, 21, + 22, 23 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 1, 5, 8, 10, 37, 38, 39, 40, 0, + 28, 41, 1, 28, 49, 28, 64, 42, 9, 50, + 7, 65, 1, 6, 11, 12, 13, 14, 15, 18, + 19, 20, 21, 22, 23, 29, 43, 44, 1, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 29, 51, 63, 69, 34, 17, 66, + 28, 28, 28, 1, 3, 6, 11, 12, 14, 15, + 19, 21, 22, 23, 47, 48, 69, 48, 26, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 30, 28, + 26, 34, 24, 67, 4, 42, 42, 30, 45, 26, + 26, 52, 26, 57, 26, 58, 26, 53, 26, 55, + 27, 59, 62, 69, 26, 54, 26, 56, 60, 61, + 69, 50, 30, 26, 34, 25, 68, 31, 29, 29, + 1, 30, 32, 46, 30, 35, 30, 35, 30, 35, + 30, 35, 30, 35, 30, 35, 30, 35, 30, 35, + 30, 35, 29, 30, 26, 34, 29, 43, 48, 48, + 26, 34, 69, 26, 26, 26, 26, 26, 62, 26, + 26, 61, 30, 26, 30, 16, 30, 45, 33, 26, + 34, 30, 31, 30, 33, 26, 42, 33, 29, 48, + 30 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (parsestate, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, parsestate) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, parsestate); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, DAPparsestate* parsestate) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, parsestate) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + DAPparsestate* parsestate; +#endif +{ + if (!yyvaluep) + return; + YYUSE (parsestate); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, DAPparsestate* parsestate) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, parsestate) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + DAPparsestate* parsestate; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, parsestate); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, DAPparsestate* parsestate) +#else +static void +yy_reduce_print (yyvsp, yyrule, parsestate) + YYSTYPE *yyvsp; + int yyrule; + DAPparsestate* parsestate; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , parsestate); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule, parsestate); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, DAPparsestate* parsestate) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, parsestate) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + DAPparsestate* parsestate; +#endif +{ + YYUSE (yyvaluep); + YYUSE (parsestate); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (DAPparsestate* parsestate); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (DAPparsestate* parsestate) +#else +int +yyparse (parsestate) + DAPparsestate* parsestate; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 6: + +/* Line 1464 of yacc.c */ +#line 57 "dap.y" + {dap_unrecognizedresponse(parsestate); YYABORT;;} + break; + + case 7: + +/* Line 1464 of yacc.c */ +#line 62 "dap.y" + {dap_tagparse(parsestate,SCAN_DATASET);;} + break; + + case 8: + +/* Line 1464 of yacc.c */ +#line 66 "dap.y" + {dap_tagparse(parsestate,SCAN_ATTR);;} + break; + + case 9: + +/* Line 1464 of yacc.c */ +#line 70 "dap.y" + {dap_tagparse(parsestate,SCAN_ERROR);;} + break; + + case 10: + +/* Line 1464 of yacc.c */ +#line 75 "dap.y" + {dap_datasetbody(parsestate,(yyvsp[(4) - (5)]),(yyvsp[(2) - (5)]));;} + break; + + case 11: + +/* Line 1464 of yacc.c */ +#line 80 "dap.y" + {(yyval)=dap_declarations(parsestate,null,null);;} + break; + + case 12: + +/* Line 1464 of yacc.c */ +#line 81 "dap.y" + {(yyval)=dap_declarations(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));;} + break; + + case 13: + +/* Line 1464 of yacc.c */ +#line 88 "dap.y" + {(yyval)=dap_makebase(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(1) - (4)]),(yyvsp[(3) - (4)]));;} + break; + + case 14: + +/* Line 1464 of yacc.c */ +#line 90 "dap.y" + {if(((yyval)=dap_makestructure(parsestate,(yyvsp[(5) - (7)]),(yyvsp[(6) - (7)]),(yyvsp[(3) - (7)])))==null) {YYABORT;};} + break; + + case 15: + +/* Line 1464 of yacc.c */ +#line 92 "dap.y" + {if(((yyval)=dap_makesequence(parsestate,(yyvsp[(5) - (6)]),(yyvsp[(3) - (6)])))==null) {YYABORT;};} + break; + + case 16: + +/* Line 1464 of yacc.c */ +#line 95 "dap.y" + {if(((yyval)=dap_makegrid(parsestate,(yyvsp[(10) - (11)]),(yyvsp[(5) - (11)]),(yyvsp[(8) - (11)])))==null) {YYABORT;};} + break; + + case 17: + +/* Line 1464 of yacc.c */ +#line 97 "dap.y" + {daperror(parsestate,"Unrecognized type"); YYABORT;;} + break; + + case 18: + +/* Line 1464 of yacc.c */ +#line 102 "dap.y" + {(yyval)=(Object)SCAN_BYTE;;} + break; + + case 19: + +/* Line 1464 of yacc.c */ +#line 103 "dap.y" + {(yyval)=(Object)SCAN_INT16;;} + break; + + case 20: + +/* Line 1464 of yacc.c */ +#line 104 "dap.y" + {(yyval)=(Object)SCAN_UINT16;;} + break; + + case 21: + +/* Line 1464 of yacc.c */ +#line 105 "dap.y" + {(yyval)=(Object)SCAN_INT32;;} + break; + + case 22: + +/* Line 1464 of yacc.c */ +#line 106 "dap.y" + {(yyval)=(Object)SCAN_UINT32;;} + break; + + case 23: + +/* Line 1464 of yacc.c */ +#line 107 "dap.y" + {(yyval)=(Object)SCAN_FLOAT32;;} + break; + + case 24: + +/* Line 1464 of yacc.c */ +#line 108 "dap.y" + {(yyval)=(Object)SCAN_FLOAT64;;} + break; + + case 25: + +/* Line 1464 of yacc.c */ +#line 109 "dap.y" + {(yyval)=(Object)SCAN_URL;;} + break; + + case 26: + +/* Line 1464 of yacc.c */ +#line 110 "dap.y" + {(yyval)=(Object)SCAN_STRING;;} + break; + + case 27: + +/* Line 1464 of yacc.c */ +#line 114 "dap.y" + {(yyval)=dap_arraydecls(parsestate,null,null);;} + break; + + case 28: + +/* Line 1464 of yacc.c */ +#line 115 "dap.y" + {(yyval)=dap_arraydecls(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));;} + break; + + case 29: + +/* Line 1464 of yacc.c */ +#line 119 "dap.y" + {(yyval)=dap_arraydecl(parsestate,null,(yyvsp[(2) - (3)]));;} + break; + + case 30: + +/* Line 1464 of yacc.c */ +#line 120 "dap.y" + {(yyval)=dap_arraydecl(parsestate,null,(yyvsp[(3) - (4)]));;} + break; + + case 31: + +/* Line 1464 of yacc.c */ +#line 121 "dap.y" + {(yyval)=dap_arraydecl(parsestate,(yyvsp[(2) - (5)]),(yyvsp[(4) - (5)]));;} + break; + + case 32: + +/* Line 1464 of yacc.c */ +#line 123 "dap.y" + {daperror(parsestate,"Illegal dimension declaration"); YYABORT;;} + break; + + case 33: + +/* Line 1464 of yacc.c */ +#line 127 "dap.y" + {(yyval)=(yyvsp[(1) - (1)]);;} + break; + + case 34: + +/* Line 1464 of yacc.c */ +#line 129 "dap.y" + {daperror(parsestate,"Illegal dataset declaration"); YYABORT;;} + break; + + case 35: + +/* Line 1464 of yacc.c */ +#line 132 "dap.y" + {(yyval)=(yyvsp[(1) - (1)]);;} + break; + + case 36: + +/* Line 1464 of yacc.c */ +#line 135 "dap.y" + {dap_attributebody(parsestate,(yyvsp[(2) - (3)]));;} + break; + + case 37: + +/* Line 1464 of yacc.c */ +#line 137 "dap.y" + {daperror(parsestate,"Illegal DAS body"); YYABORT;;} + break; + + case 38: + +/* Line 1464 of yacc.c */ +#line 141 "dap.y" + {(yyval)=dap_attrlist(parsestate,null,null);;} + break; + + case 39: + +/* Line 1464 of yacc.c */ +#line 142 "dap.y" + {(yyval)=dap_attrlist(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));;} + break; + + case 40: + +/* Line 1464 of yacc.c */ +#line 146 "dap.y" + {(yyval)=null;;} + break; + + case 41: + +/* Line 1464 of yacc.c */ +#line 148 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_BYTE);;} + break; + + case 42: + +/* Line 1464 of yacc.c */ +#line 150 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_INT16);;} + break; + + case 43: + +/* Line 1464 of yacc.c */ +#line 152 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_UINT16);;} + break; + + case 44: + +/* Line 1464 of yacc.c */ +#line 154 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_INT32);;} + break; + + case 45: + +/* Line 1464 of yacc.c */ +#line 156 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_UINT32);;} + break; + + case 46: + +/* Line 1464 of yacc.c */ +#line 158 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_FLOAT32);;} + break; + + case 47: + +/* Line 1464 of yacc.c */ +#line 160 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_FLOAT64);;} + break; + + case 48: + +/* Line 1464 of yacc.c */ +#line 162 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_STRING);;} + break; + + case 49: + +/* Line 1464 of yacc.c */ +#line 164 "dap.y" + {(yyval)=dap_attribute(parsestate,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(Object)SCAN_URL);;} + break; + + case 50: + +/* Line 1464 of yacc.c */ +#line 165 "dap.y" + {(yyval)=dap_attrset(parsestate,(yyvsp[(1) - (4)]),(yyvsp[(3) - (4)]));;} + break; + + case 51: + +/* Line 1464 of yacc.c */ +#line 167 "dap.y" + {daperror(parsestate,"Illegal attribute"); YYABORT;;} + break; + + case 52: + +/* Line 1464 of yacc.c */ +#line 171 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_BYTE);;} + break; + + case 53: + +/* Line 1464 of yacc.c */ +#line 173 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_BYTE);;} + break; + + case 54: + +/* Line 1464 of yacc.c */ +#line 176 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_INT16);;} + break; + + case 55: + +/* Line 1464 of yacc.c */ +#line 178 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_INT16);;} + break; + + case 56: + +/* Line 1464 of yacc.c */ +#line 181 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_UINT16);;} + break; + + case 57: + +/* Line 1464 of yacc.c */ +#line 183 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_UINT16);;} + break; + + case 58: + +/* Line 1464 of yacc.c */ +#line 186 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_INT32);;} + break; + + case 59: + +/* Line 1464 of yacc.c */ +#line 188 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_INT32);;} + break; + + case 60: + +/* Line 1464 of yacc.c */ +#line 191 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_UINT32);;} + break; + + case 61: + +/* Line 1464 of yacc.c */ +#line 192 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_UINT32);;} + break; + + case 62: + +/* Line 1464 of yacc.c */ +#line 195 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_FLOAT32);;} + break; + + case 63: + +/* Line 1464 of yacc.c */ +#line 196 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_FLOAT32);;} + break; + + case 64: + +/* Line 1464 of yacc.c */ +#line 199 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_FLOAT64);;} + break; + + case 65: + +/* Line 1464 of yacc.c */ +#line 200 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_FLOAT64);;} + break; + + case 66: + +/* Line 1464 of yacc.c */ +#line 203 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_STRING);;} + break; + + case 67: + +/* Line 1464 of yacc.c */ +#line 204 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_STRING);;} + break; + + case 68: + +/* Line 1464 of yacc.c */ +#line 208 "dap.y" + {(yyval)=dap_attrvalue(parsestate,null,(yyvsp[(1) - (1)]),(Object)SCAN_URL);;} + break; + + case 69: + +/* Line 1464 of yacc.c */ +#line 209 "dap.y" + {(yyval)=dap_attrvalue(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]),(Object)SCAN_URL);;} + break; + + case 70: + +/* Line 1464 of yacc.c */ +#line 213 "dap.y" + {(yyval)=(yyvsp[(1) - (1)]);;} + break; + + case 71: + +/* Line 1464 of yacc.c */ +#line 217 "dap.y" + {(yyval)=(yyvsp[(1) - (1)]);;} + break; + + case 72: + +/* Line 1464 of yacc.c */ +#line 218 "dap.y" + {(yyval)=(yyvsp[(1) - (1)]);;} + break; + + case 73: + +/* Line 1464 of yacc.c */ +#line 229 "dap.y" + {(yyval)=(yyvsp[(2) - (3)]); (yyval)=(yyvsp[(3) - (3)]); (yyval)=null;;} + break; + + case 74: + +/* Line 1464 of yacc.c */ +#line 234 "dap.y" + {dap_errorbody(parsestate,(yyvsp[(2) - (7)]),(yyvsp[(3) - (7)]),(yyvsp[(4) - (7)]),(yyvsp[(5) - (7)]));;} + break; + + case 75: + +/* Line 1464 of yacc.c */ +#line 237 "dap.y" + {(yyval)=null;;} + break; + + case 76: + +/* Line 1464 of yacc.c */ +#line 237 "dap.y" + {(yyval)=(yyvsp[(3) - (4)]);;} + break; + + case 77: + +/* Line 1464 of yacc.c */ +#line 238 "dap.y" + {(yyval)=null;;} + break; + + case 78: + +/* Line 1464 of yacc.c */ +#line 238 "dap.y" + {(yyval)=(yyvsp[(3) - (4)]);;} + break; + + case 79: + +/* Line 1464 of yacc.c */ +#line 239 "dap.y" + {(yyval)=null;;} + break; + + case 80: + +/* Line 1464 of yacc.c */ +#line 239 "dap.y" + {(yyval)=(yyvsp[(3) - (4)]);;} + break; + + case 81: + +/* Line 1464 of yacc.c */ +#line 240 "dap.y" + {(yyval)=null;;} + break; + + case 82: + +/* Line 1464 of yacc.c */ +#line 240 "dap.y" + {(yyval)=(yyvsp[(3) - (4)]);;} + break; + + case 83: + +/* Line 1464 of yacc.c */ +#line 246 "dap.y" + {(yyval)=dapdecode(parsestate->lexstate,(yyvsp[(1) - (1)]));;} + break; + + case 84: + +/* Line 1464 of yacc.c */ +#line 247 "dap.y" + {(yyval)=strdup("alias");;} + break; + + case 85: + +/* Line 1464 of yacc.c */ +#line 248 "dap.y" + {(yyval)=strdup("array");;} + break; + + case 86: + +/* Line 1464 of yacc.c */ +#line 249 "dap.y" + {(yyval)=strdup("attributes");;} + break; + + case 87: + +/* Line 1464 of yacc.c */ +#line 250 "dap.y" + {(yyval)=strdup("byte");;} + break; + + case 88: + +/* Line 1464 of yacc.c */ +#line 251 "dap.y" + {(yyval)=strdup("dataset");;} + break; + + case 89: + +/* Line 1464 of yacc.c */ +#line 252 "dap.y" + {(yyval)=strdup("data");;} + break; + + case 90: + +/* Line 1464 of yacc.c */ +#line 253 "dap.y" + {(yyval)=strdup("error");;} + break; + + case 91: + +/* Line 1464 of yacc.c */ +#line 254 "dap.y" + {(yyval)=strdup("float32");;} + break; + + case 92: + +/* Line 1464 of yacc.c */ +#line 255 "dap.y" + {(yyval)=strdup("float64");;} + break; + + case 93: + +/* Line 1464 of yacc.c */ +#line 256 "dap.y" + {(yyval)=strdup("grid");;} + break; + + case 94: + +/* Line 1464 of yacc.c */ +#line 257 "dap.y" + {(yyval)=strdup("int16");;} + break; + + case 95: + +/* Line 1464 of yacc.c */ +#line 258 "dap.y" + {(yyval)=strdup("int32");;} + break; + + case 96: + +/* Line 1464 of yacc.c */ +#line 259 "dap.y" + {(yyval)=strdup("maps");;} + break; + + case 97: + +/* Line 1464 of yacc.c */ +#line 260 "dap.y" + {(yyval)=strdup("sequence");;} + break; + + case 98: + +/* Line 1464 of yacc.c */ +#line 261 "dap.y" + {(yyval)=strdup("string");;} + break; + + case 99: + +/* Line 1464 of yacc.c */ +#line 262 "dap.y" + {(yyval)=strdup("structure");;} + break; + + case 100: + +/* Line 1464 of yacc.c */ +#line 263 "dap.y" + {(yyval)=strdup("uint16");;} + break; + + case 101: + +/* Line 1464 of yacc.c */ +#line 264 "dap.y" + {(yyval)=strdup("uint32");;} + break; + + case 102: + +/* Line 1464 of yacc.c */ +#line 265 "dap.y" + {(yyval)=strdup("url");;} + break; + + case 103: + +/* Line 1464 of yacc.c */ +#line 266 "dap.y" + {(yyval)=strdup("code");;} + break; + + case 104: + +/* Line 1464 of yacc.c */ +#line 267 "dap.y" + {(yyval)=strdup("message");;} + break; + + case 105: + +/* Line 1464 of yacc.c */ +#line 268 "dap.y" + {(yyval)=strdup("program");;} + break; + + case 106: + +/* Line 1464 of yacc.c */ +#line 269 "dap.y" + {(yyval)=strdup("program_type");;} + break; + + + +/* Line 1464 of yacc.c */ +#line 2280 "dap.tab.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (parsestate, YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (parsestate, yymsg); + } + else + { + yyerror (parsestate, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, parsestate); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, parsestate); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (parsestate, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, parsestate); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, parsestate); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1684 of yacc.c */ +#line 272 "dap.y" + + diff --git a/extern/src_netcdf4/daptab.h b/extern/src_netcdf4/daptab.h new file mode 100644 index 0000000000000000000000000000000000000000..f5341cfc5a56f3e148b9f184925577bea6d7ca53 --- /dev/null +++ b/extern/src_netcdf4/daptab.h @@ -0,0 +1,80 @@ +/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + SCAN_ALIAS = 258, + SCAN_ARRAY = 259, + SCAN_ATTR = 260, + SCAN_BYTE = 261, + SCAN_CODE = 262, + SCAN_DATASET = 263, + SCAN_DATA = 264, + SCAN_ERROR = 265, + SCAN_FLOAT32 = 266, + SCAN_FLOAT64 = 267, + SCAN_GRID = 268, + SCAN_INT16 = 269, + SCAN_INT32 = 270, + SCAN_MAPS = 271, + SCAN_MESSAGE = 272, + SCAN_SEQUENCE = 273, + SCAN_STRING = 274, + SCAN_STRUCTURE = 275, + SCAN_UINT16 = 276, + SCAN_UINT32 = 277, + SCAN_URL = 278, + SCAN_PTYPE = 279, + SCAN_PROG = 280, + WORD_WORD = 281, + WORD_STRING = 282 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + + diff --git a/extern/src_netcdf4/daputil.c b/extern/src_netcdf4/daputil.c new file mode 100644 index 0000000000000000000000000000000000000000..ef97a90f2fc607a8826296d2b314f1bfa4927c60 --- /dev/null +++ b/extern/src_netcdf4/daputil.c @@ -0,0 +1,786 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/daputil.c,v 1.47 2010/05/21 23:24:15 dmh Exp $ + *********************************************************************/ + +#include "config.h" + +#include + +#include "oc.h" +extern int oc_dumpnode(OClink, OCobject); + +#include "ncdap3.h" +#include "dapalign.h" +#include "dapodom.h" + +#define LBRACKET '[' +#define RBRACKET ']' + + +/**************************************************/ +/** + * Provide a hidden interface to allow utilities + * to check if a given path name is really an ncdap3 url. + * If no, return null, else return basename of the url + * minus any extension. + */ + +int +nc__testurl(const char* path, char** basenamep) +{ + NC_URI* uri; + int ok = nc_uriparse(path,&uri); + if(ok) { + char* slash = strrchr(uri->file, '/'); + char* dot; + if(slash == NULL) slash = (char*)path; else slash++; + slash = nulldup(slash); + dot = strrchr(slash, '.'); + if(dot != NULL && dot != slash) *dot = '\0'; + if(basenamep) *basenamep=slash ; else free(slash); + nc_urifree(uri); + } + return ok; +} + +/**************************************************/ + +/* +Given a legal dap name with arbitrary characters, +convert to equivalent legal cdf name +With the new name policy for netcdf, this procedure +does nothing. +*/ + +char* +cdflegalname3(char* dapname) +{ + return nulldup(dapname); +} + +/* Define the type conversion of the DAP variables + to the external netCDF variable type. + The proper way is to, for example, convert unsigned short + to an int to maintain the values. + Unfortuneately, libnc-dap does not do this: + it translates the types directly. For example + libnc-dap upgrades the DAP byte type, which is unsigned char, + to NC_BYTE, which signed char. + Oh well. + For netcdf-4, we can do proper type conversion. +*/ +nc_type +nctypeconvert(NCDAPCOMMON* drno, nc_type nctype) +{ + nc_type upgrade = NC_NAT; + if(drno->controls.flags & NCF_NC3) { + /* libnc-dap mimic invariant is to maintain type size */ + switch (nctype) { + case NC_CHAR: upgrade = NC_CHAR; break; + case NC_BYTE: upgrade = NC_BYTE; break; + case NC_UBYTE: upgrade = NC_BYTE; break; + case NC_SHORT: upgrade = NC_SHORT; break; + case NC_USHORT: upgrade = NC_SHORT; break; + case NC_INT: upgrade = NC_INT; break; + case NC_UINT: upgrade = NC_INT; break; + case NC_INT64: upgrade = NC_INT64; break; + case NC_UINT64: upgrade = NC_UINT64; break; + case NC_FLOAT: upgrade = NC_FLOAT; break; + case NC_DOUBLE: upgrade = NC_DOUBLE; break; + case NC_URL: + case NC_STRING: upgrade = NC_CHAR; break; + default: break; + } + } else if(drno->controls.flags & NCF_NC4) { + /* netcdf-4 conversion is more correct */ + switch (nctype) { + case NC_CHAR: upgrade = NC_CHAR; break; + case NC_BYTE: upgrade = NC_BYTE; break; + case NC_UBYTE: upgrade = NC_UBYTE; break; + case NC_SHORT: upgrade = NC_SHORT; break; + case NC_USHORT: upgrade = NC_USHORT; break; + case NC_INT: upgrade = NC_INT; break; + case NC_UINT: upgrade = NC_UINT; break; + case NC_INT64: upgrade = NC_INT64; break; + case NC_UINT64: upgrade = NC_UINT64; break; + case NC_FLOAT: upgrade = NC_FLOAT; break; + case NC_DOUBLE: upgrade = NC_DOUBLE; break; + case NC_URL: + case NC_STRING: upgrade = NC_STRING; break; + default: break; + } + } + return upgrade; +} + +nc_type +octypetonc(OCtype etype) +{ + switch (etype) { + case OC_Char: return NC_CHAR; + case OC_Byte: return NC_UBYTE; + case OC_UByte: return NC_UBYTE; + case OC_Int16: return NC_SHORT; + case OC_UInt16: return NC_USHORT; + case OC_Int32: return NC_INT; + case OC_UInt32: return NC_UINT; + case OC_Int64: return NC_INT64; + case OC_UInt64: return NC_UINT64; + case OC_Float32: return NC_FLOAT; + case OC_Float64: return NC_DOUBLE; + case OC_String: return NC_STRING; + case OC_URL: return NC_STRING; + case OC_Dataset: return NC_Dataset; + case OC_Sequence: return NC_Sequence; + case OC_Structure: return NC_Structure; + case OC_Grid: return NC_Grid; + case OC_Dimension: return NC_Dimension; + case OC_Primitive: return NC_Primitive; + default: break; + } + return NC_NAT; +} + +OCtype +nctypetodap(nc_type nctype) +{ + switch (nctype) { + case NC_CHAR: return OC_Char; + case NC_BYTE: return OC_Byte; + case NC_UBYTE: return OC_UByte; + case NC_SHORT: return OC_Int16; + case NC_USHORT: return OC_UInt16; + case NC_INT: return OC_Int32; + case NC_UINT: return OC_UInt32; + case NC_INT64: return OC_Int64; + case NC_UINT64: return OC_UInt64; + case NC_FLOAT: return OC_Float32; + case NC_DOUBLE: return OC_Float64; + case NC_STRING: return OC_String; + default : break; + } + return OC_NAT; +} + +size_t +nctypesizeof(nc_type nctype) +{ + switch (nctype) { + case NC_CHAR: return sizeof(char); + case NC_BYTE: return sizeof(signed char); + case NC_UBYTE: return sizeof(unsigned char); + case NC_SHORT: return sizeof(short); + case NC_USHORT: return sizeof(unsigned short); + case NC_INT: return sizeof(int); + case NC_UINT: return sizeof(unsigned int); + case NC_INT64: return sizeof(long long); + case NC_UINT64: return sizeof(unsigned long long); + case NC_FLOAT: return sizeof(float); + case NC_DOUBLE: return sizeof(double); + case NC_STRING: return sizeof(char*); + default: PANIC("nctypesizeof"); + } + return 0; +} + +char* +nctypetostring(nc_type nctype) +{ + switch (nctype) { + case NC_NAT: return "NC_NAT"; + case NC_BYTE: return "NC_BYTE"; + case NC_CHAR: return "NC_CHAR"; + case NC_SHORT: return "NC_SHORT"; + case NC_INT: return "NC_INT"; + case NC_FLOAT: return "NC_FLOAT"; + case NC_DOUBLE: return "NC_DOUBLE"; + case NC_UBYTE: return "NC_UBYTE"; + case NC_USHORT: return "NC_USHORT"; + case NC_UINT: return "NC_UINT"; + case NC_INT64: return "NC_INT64"; + case NC_UINT64: return "NC_UINT64"; + case NC_STRING: return "NC_STRING"; + case NC_VLEN: return "NC_VLEN"; + case NC_OPAQUE: return "NC_OPAQUE"; + case NC_ENUM: return "NC_ENUM"; + case NC_COMPOUND: return "NC_COMPOUND"; + case NC_URL: return "NC_URL"; + case NC_SET: return "NC_SET"; + case NC_Dataset: return "NC_Dataset"; + case NC_Sequence: return "NC_Sequence"; + case NC_Structure: return "NC_Structure"; + case NC_Grid: return "NC_Grid"; + case NC_Dimension: return "NC_Dimension"; + case NC_Primitive: return "NC_Primitive"; + default: break; + } + return NULL; +} + + +/* Pad a buffer */ +int +alignbuffer3(NCbytes* buf, int alignment) +{ + int pad; + unsigned long len; + if(buf == NULL) return 0; + len = ncbyteslength(buf); + pad = nccpadding(len,alignment); + +#ifdef TEST + for(;pad > 0;pad--) + ncbytesappend(buf,0x3a); /* 0x3a was chosen at random */ +#else + ncbytessetlength(buf,len+pad); +#endif + return 1; +} + +size_t +dimproduct3(NClist* dimensions) +{ + size_t size = 1; + unsigned int i; + if(dimensions == NULL) return size; + for(i=0;idim.declsize; + } + return size; +} + + +/* Return value of param or NULL if not found */ +const char* +paramvalue34(NCDAPCOMMON* nccomm, const char* key) +{ + const char* value; + + if(nccomm == NULL || key == NULL) return 0; + if(!nc_urilookup(nccomm->oc.url,key,&value)) + return NULL; + return value; +} + +static const char* checkseps = "+,:;"; + +/* Search for substring in value of param. If substring == NULL; then just + check if param is defined. +*/ +int +paramcheck34(NCDAPCOMMON* nccomm, const char* key, const char* subkey) +{ + const char* value; + char* p; + + if(nccomm == NULL || key == NULL) return 0; + if(!nc_urilookup(nccomm->oc.url,key,&value)) + return 0; + if(subkey == NULL) return 1; + p = strstr(value,subkey); + if(p == NULL) return 0; + p += strlen(subkey); + if(*p != '\0' && strchr(checkseps,*p) == NULL) return 0; + return 1; +} + + +/* This is NOT UNION */ +int +nclistconcat(NClist* l1, NClist* l2) +{ + unsigned int i; + for(i=0;i=0;i--) { + ncelem test = nclistget(l,i); + if(test==elem) { + nclistremove(l,i); + found=1; + } + } + return found; +} + +/* Collect the set of container nodes ending in "container"*/ +void +collectnodepath3(CDFnode* node, NClist* path, int withdataset) +{ + if(node == NULL) return; + nclistpush(path,(ncelem)node); + while(node->container != NULL) { + node = node->container; + if(!withdataset && node->nctype == NC_Dataset) break; + nclistinsert(path,0,(ncelem)node); + } +} + +/* Like collectnodepath3, but in ocspace */ +void +collectocpath(OCconnection conn, OCobject node, NClist* path) +{ + OCobject container; + OCtype octype; + if(node == OCNULL) return; + oc_inq_class(conn,node,&octype); + if(octype == OC_Dataset) return; + oc_inq_container(conn,node,&container); + if(container != OCNULL) + collectocpath(conn,container,path); + nclistpush(path,(ncelem)node); +} + +char* +makeocpathstring3(OCconnection conn, OCobject node, const char* sep) +{ + int slen,i,len,first,seplen; + char* pathname; + OCtype octype; + NClist* ocpath = nclistnew(); + + collectocpath(conn,node,ocpath); + len = nclistlength(ocpath); + assert(len > 0); /* dataset at least */ + + oc_inq_type(conn,node,&octype); + if(octype == OC_Dataset) + {pathname = nulldup(""); goto done;} /* Dataset */ + + seplen = strlen(sep); + for(slen=0,i=0;i 0); /* dataset at least */ + seplen = strlen(separator); + ASSERT(seplen > 0); + for(slen=0,i=0;inctype == NC_Dataset) continue; + slen += strlen(node->ncbasename); + slen += seplen; + } + slen += 1; /* for null terminator*/ + pathname = (char*)malloc(slen); + MEMCHECK(pathname,NULL); + pathname[0] = '\0'; + for(first=1,i=0;ielided || (flags & PATHELIDE)==0) { + if(node->nctype != NC_Dataset) { + name = node->ncbasename; + if(!first) strcat(pathname,separator); + strcat(pathname,name); + first = 0; + } + } + } + return pathname; +} + + +/* convert path to string using the ncname field */ +char* +makecdfpathstring3(CDFnode* var, const char* separator) +{ + char* spath; + NClist* path = nclistnew(); + collectnodepath3(var,path,WITHDATASET); /* <= note */ + spath = makepathstring3(path,separator,PATHNC); + nclistfree(path); + return spath; +} + +/* Collect the set names of container nodes ending in "container"*/ +void +clonenodenamepath3(CDFnode* node, NClist* path, int withdataset) +{ + if(node == NULL) return; + /* stop at the dataset container as well*/ + if(node->nctype != NC_Dataset) + clonenodenamepath3(node->container,path,withdataset); + if(node->nctype != NC_Dataset || withdataset) + nclistpush(path,(ncelem)nulldup(node->ncbasename)); +} + +char* +simplepathstring3(NClist* names, char* separator) +{ + int i; + size_t len; + char* result; + if(nclistlength(names) == 0) return nulldup(""); + for(len=0,i=0;i 0) strcat(result,separator); + strcat(result,segment); + } + return result; +} + +/* Define a number of location tests */ + +/* Is node contained (transitively) in a sequence ? */ +BOOL +dapinsequence(CDFnode* node) +{ + if(node == NULL || node->container == NULL) return TRUE; + for(node=node->container;node->nctype != NC_Dataset;node=node->container) { + if(node->nctype == NC_Sequence) return TRUE; + } + return FALSE; +} + +/* Is node a map field of a grid? */ +BOOL +dapgridmap(CDFnode* node) +{ + if(node != NULL && node->container != NULL + && node->container->nctype == NC_Grid) { + CDFnode* array = (CDFnode*)nclistget(node->container->subnodes,0); + return (node != array); + } + return FALSE; +} + +/* Is node an array field of a grid? */ +BOOL +dapgridarray(CDFnode* node) +{ + if(node != NULL && node->container != NULL + && node->container->nctype == NC_Grid) { + CDFnode* array = (CDFnode*)nclistget(node->container->subnodes,0); + return (node == array); + } + return FALSE; +} + +BOOL +dapgridelement(CDFnode* node) +{ + return dapgridarray(node) + || dapgridmap(node); +} + +/* Is node a top-level grid node? */ +BOOL +daptopgrid(CDFnode* grid) +{ + if(grid == NULL || grid->nctype != NC_Grid) return FALSE; + return daptoplevel(grid); +} + +/* Is node a top-level sequence node? */ +BOOL +daptopseq(CDFnode* seq) +{ + if(seq == NULL || seq->nctype != NC_Sequence) return FALSE; + return daptoplevel(seq); +} + +/* Is node a top-level node? */ +BOOL +daptoplevel(CDFnode* node) +{ + if(node->container == NULL + || node->container->nctype != NC_Dataset) return FALSE; + return TRUE; +} + +unsigned int +modeldecode(int translation, const char* smodel, + const struct NCTMODEL* models, + unsigned int dfalt) +{ + for(;models->translation;models++) { + if(translation != models->translation) continue; + if(smodel == models->model + || (models->model != NULL && strcasecmp(smodel,models->model)==0)) { + /* We have a match */ + return models->flags; + } + } + return dfalt; +} + +unsigned long +getlimitnumber(const char* limit) +{ + size_t slen; + unsigned long multiplier = 1; + unsigned long lu; + + if(limit == NULL) return 0; + slen = strlen(limit); + if(slen == 0) return 0; + switch (limit[slen-1]) { + case 'G': case 'g': multiplier = GIGBYTE; break; + case 'M': case 'm': multiplier = MEGBYTE; break; + case 'K': case 'k': multiplier = KILBYTE; break; + default: break; + } + sscanf(limit,"%lu",&lu); + return (lu*multiplier); +} + +void +dapexpandescapes(char *termstring) +{ + char *s, *t, *endp; + + /* expand "\" escapes, e.g. "\t" to tab character; + will only shorten string length, never increase it + */ + s = termstring; + t = termstring; + while(*t) { + if (*t == '\\') { + t++; + switch (*t) { + case 'a': + *s++ = '\007'; t++; /* will use '\a' when STDC */ + break; + case 'b': + *s++ = '\b'; t++; + break; + case 'f': + *s++ = '\f'; t++; + break; + case 'n': + *s++ = '\n'; t++; + break; + case 'r': + *s++ = '\r'; t++; + break; + case 't': + *s++ = '\t'; t++; + break; + case 'v': + *s++ = '\v'; t++; + break; + case '\\': + *s++ = '\\'; t++; + break; + case '?': + *s++ = '\177'; t++; + break; + case 'x': + t++; /* now t points to one or more hex digits */ + *s++ = (char) strtol(t, &endp, 16); + t = endp; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { + /* t should now point to 3 octal digits */ + int c; + c = t[0]; + if(c == 0 || c < '0' || c > '7') goto normal; + c = t[1]; + if(c == 0 || c < '0' || c > '7') goto normal; + c = t[2]; + if(c == 0 || c < '0' || c > '7') goto normal; + c = ((t[0]-'0')<<6)+((t[1]-'0')<<3)+(t[2]-'0'); + *s++ = (char)c; + t += 3; + } break; + default: + if(*t == 0) + *s++ = '\\'; + else + *s++ = *t++; + break; + } + } else { +normal: *s++ = *t++; + } + } + *s = '\0'; + return; +} + +#ifdef HAVE_GETTIMEOFDAY +static struct timeval time0; +static struct timeval time1; + +static double +deltatime() +{ + double t0, t1; + t0 = ((double)time0.tv_sec); + t0 += ((double)time0.tv_usec) / 1000000.0; + t1 = ((double)time1.tv_sec); + t1 += ((double)time1.tv_usec) / 1000000.0; + return (t1 - t0); +} +#endif + +/* Provide a wrapper for oc_fetch so we can log what it does */ +OCerror +dap_fetch(NCDAPCOMMON* nccomm, OCconnection conn, const char* ce, + OCdxd dxd, OCobject* rootp) +{ + OCerror ocstat; + char* ext; + OCflags flags = 0; + + if(dxd == OCDDS) ext = ".dds"; + else if(dxd == OCDAS) ext = ".das"; + else ext = ".dods"; + + if(ce != NULL && strlen(ce) == 0) + ce = NULL; + + if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) { + ce = NULL; + } + + if(FLAGSET(nccomm->controls,NCF_ONDISK)) { + flags |= OCONDISK; + } + + if(SHOWFETCH) { + /* Build uri string minus the constraint */ + char* baseurl = nc_uribuild(nccomm->oc.url,NULL,ext,0); + if(ce == NULL) + LOG1(NCLOGNOTE,"fetch: %s\n",baseurl); + else + LOG2(NCLOGNOTE,"fetch: %s?%s\n",baseurl,ce); + nullfree(baseurl); +#ifdef HAVE_GETTIMEOFDAY + gettimeofday(&time0,NULL); +#endif + } + ocstat = oc_fetchf(conn,ce,dxd,flags,rootp); + if(FLAGSET(nccomm->controls,NCF_SHOWFETCH)) { +#ifdef HAVE_GETTIMEOFDAY + double secs; + gettimeofday(&time1,NULL); + secs = deltatime(); + nclog(NCLOGNOTE,"fetch complete: %0.3f secs",secs); +#else + nclog(NCLOGNOTE,"fetch complete."); +#endif + } +#ifdef DEBUG2 +fprintf(stderr,"fetch: dds:\n"); +oc_dumpnode(conn,*rootp); +#endif + return ocstat; +} + +/* Check a name to see if it contains illegal dap characters +*/ + +static char* badchars = "./"; + + +int +dap_badname(char* name) +{ + char* p; + if(name == NULL) return 0; + for(p=badchars;*p;p++) { + if(strchr(name,*p) != NULL) return 1; + } + return 0; +} + +/* Check a name to see if it contains illegal dap characters + and repair them +*/ + +char* +dap_repairname(char* name) +{ + char* newname; + char *p, *q; int c; + + if(name == NULL) return NULL; + /* assume that dap_badname was called on this name and returned 1 */ + newname = (char*)malloc(1+(3*strlen(name))); /* max needed */ + newname[0] = '\0'; /* so we can use strcat */ + for(p=name,q=newname;(c=*p);p++) { + if(strchr(badchars,c) != NULL) { + char newchar[8]; + snprintf(newchar,sizeof(newchar),"%%%hhx",c); + strcat(newname,newchar); + q += 3; /*strlen(newchar)*/ + } else + *q++ = c; + *q = '\0'; /* so we can always do strcat */ + } + *q = '\0'; /* ensure trailing null */ + return newname; +} diff --git a/extern/src_netcdf4/daputil.h b/extern/src_netcdf4/daputil.h new file mode 100644 index 0000000000000000000000000000000000000000..f0541daacac42a7c7d483ec42790d49d8f22d299 --- /dev/null +++ b/extern/src_netcdf4/daputil.h @@ -0,0 +1,86 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/daputil.h,v 1.25 2010/05/05 22:15:16 dmh Exp $ + *********************************************************************/ +#ifndef DAPUTIL_H +#define DAPUTIL_H 1 + +/* Define a set of flags to control path construction */ +#define PATHNC 1 /*Use ->ncname*/ +#define PATHELIDE 2 /*Leave out elided nodes*/ + +/* mnemonic */ +#define WITHDATASET 1 +#define WITHOUTDATASET 0 + +/* sigh!, Forwards */ +struct CDFnode; +struct NCTMODEL; +struct NCDAPCOMMON; + +extern nc_type nctypeconvert(struct NCDAPCOMMON*, nc_type); +extern nc_type octypetonc(OCtype); +extern OCtype nctypetodap(nc_type); +extern size_t nctypesizeof(nc_type); +extern char* nctypetostring(nc_type); +extern char* maketmppath(char* path, char* prefix); + +extern void collectnodepath3(struct CDFnode*, NClist* path, int dataset); +extern void collectocpath(OCconnection conn, OCobject node, NClist* path); + +extern char* makecdfpathstring3(struct CDFnode*,const char*); +extern void clonenodenamepath3(struct CDFnode*, NClist*, int); +extern char* makepathstring3(NClist* path, const char* separator, int flags); + +extern char* makeocpathstring3(OCconnection, OCobject, const char*); + +extern char* cdflegalname3(char* dapname); + +/* Given a param string; return its value or null if not found*/ +extern const char* paramvalue34(struct NCDAPCOMMON* drno, const char* param); +/* Given a param string; check for a given substring */ +extern int paramcheck34(struct NCDAPCOMMON* drno, const char* param, const char* substring); + +extern int nclistconcat(NClist* l1, NClist* l2); +extern int nclistminus(NClist* l1, NClist* l2); +extern int nclistdeleteall(NClist* l1, ncelem); + +extern char* getvaraprint(void* gv); + +extern int dapinsequence(struct CDFnode* node); +extern int daptopgrid(struct CDFnode* node); +extern int daptopseq(struct CDFnode* node); +extern int daptoplevel(struct CDFnode* node); +extern int dapgridmap(struct CDFnode* node); +extern int dapgridarray(struct CDFnode* node); +extern int dapgridelement(struct CDFnode* node); + +extern unsigned int modeldecode(int, const char*, const struct NCTMODEL*, unsigned int); +extern unsigned long getlimitnumber(const char* limit); + +extern void dapexpandescapes(char *termstring); + +/* Only used by libncdap4 */ +extern int alignbuffer3(NCbytes*, int alignment); +extern size_t dimproduct3(NClist* dimensions); + +#if defined(DLL_NETCDF) +# if defined(DLL_EXPORT) +# define NCC_EXTRA __declspec(dllexport) +#else +# define NCC_EXTRA __declspec(dllimport) +# endif +NCC_EXTRA extern int nc__testurl(const char* path, char** basename); +#else +extern int nc__testurl(const char* parth, char** basename); +#endif + + +/* Provide a wrapper for oc_fetch so we can log what it does */ +extern OCerror dap_fetch(struct NCDAPCOMMON*,OCconnection,const char*,OCdxd,OCobject*); + +extern int dap_badname(char* name); +extern char* dap_repairname(char* name); + +#endif /*DAPUTIL_H*/ diff --git a/extern/src_netcdf4/datt.c b/extern/src_netcdf4/datt.c new file mode 100644 index 0000000000000000000000000000000000000000..cfdc501a78ae9d3e71294842f707dbdbe1bc1f3c --- /dev/null +++ b/extern/src_netcdf4/datt.c @@ -0,0 +1,166 @@ +/** \file +Attribute functions + +These functions read and write attributes. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \defgroup attributes Attributes + +Attributes hold metadata about data and files. + +\image html ncatts.png "Attributes store metadata." + +Attributes may be associated with a netCDF variable to specify such +properties as units, special values, maximum and minimum valid values, +scaling factors, and offsets. + +Attributes for a netCDF dataset are defined when the dataset is first +created, while the netCDF dataset is in define mode. Additional +attributes may be added later by reentering define mode. + +A netCDF attribute has a netCDF variable to which it is assigned, a +name, a type, a length, and a sequence of one or more values. + +An attribute is designated by its variable ID and name. When an +attribute name is not known, it may be designated by its variable ID +and number in order to determine its name, using the function +nc_inq_attname(). + +The attributes associated with a variable are typically defined +immediately after the variable is created, while still in define +mode. The data type, length, and value of an attribute may be changed +even when in data mode, as long as the changed attribute requires no +more space than the attribute as originally defined. + +It is also possible to have attributes that are not associated with +any variable. These are called global attributes and are identified by +using ::NC_GLOBAL as a variable pseudo-ID. Global attributes are usually +related to the netCDF dataset as a whole and may be used for purposes +such as providing a title or processing history for a netCDF dataset. + +Operations supported on attributes are: +- Create an attribute, given its variable ID, name, data type, length, + and value. +- Get attribute's data type and length from its variable ID and name. +- Get attribute's value from its variable ID and name. +- Copy attribute from one netCDF variable to another. +- Get name of attribute from its number. +- Rename an attribute. +- Delete an attribute. +*/ + +/*! \{*/ /* All these functions are part of the above defgroup... */ + + +/** \name Deleting and Renaming Attributes + +Functions to delete or rename an attribute. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/*! +Rename an attribute. + +The function nc_rename_att() changes the name of an attribute. If the +new name is longer than the original name, the netCDF dataset must be +in define mode. You cannot rename an attribute to have the same name +as another attribute of the same variable. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL for +a global attribute. + +\param name Attribute \ref object_name. + +\param newname The new attribute \ref object_name. + +

Example

+ +Here is an example using nc_rename_att() to rename the variable +attribute units to Units for a variable rh in an existing netCDF +dataset named foo.nc: + +\code + #include + ... + int status; + int ncid; + int rh_id; + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_rename_att(ncid, rh_id, "units", "Units"); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_rename_att(int ncid, int varid, const char *name, const char *newname) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->rename_att(ncid, varid, name, newname); +} + +/*! +Delete an attribute. + +The function nc_del_att() deletes a netCDF attribute from an open +netCDF dataset. The netCDF dataset must be in define mode. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL +for a global attribute. + +\param name Attribute name. + +

Example

+ +Here is an example using nc_del_att() to delete the variable attribute +Units for a variable rh in an existing netCDF dataset named foo.nc: + +\code + #include + ... + int status; + int ncid; + int rh_id; + ... + status = nc_open("foo.nc", NC_WRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_redef(ncid); + if (status != NC_NOERR) handle_error(status); + status = nc_del_att(ncid, rh_id, "Units"); + if (status != NC_NOERR) handle_error(status); + status = nc_enddef(ncid); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_del_att(int ncid, int varid, const char *name) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->del_att(ncid, varid, name); +} +/*! \} */ /* End of named group ...*/ + +/*! \} */ /* End of defgroup. */ diff --git a/extern/src_netcdf4/dattget.c b/extern/src_netcdf4/dattget.c new file mode 100644 index 0000000000000000000000000000000000000000..4f79e8c10298775b8fb1e467221c93743acc9b1d --- /dev/null +++ b/extern/src_netcdf4/dattget.c @@ -0,0 +1,256 @@ +/** \file +Attribute functions + +These functions read and write attributes. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \name Getting Attributes + +Functions to get the values of attributes. + */ +/*! \{ */ + +/*! +\ingroup attributes +Get an attribute of any type. + +The nc_get_att() functions works for any type of attribute, and must +be used to get attributes of user-defined type. We recommend that they +type safe versions of this function be used where possible. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL +for a global attribute. + +\param name Attribute \ref object_name. + +\param value Pointer to location for returned attribute value(s). All +elements of the vector of attribute values are returned, so you must +allocate enough space to hold them. Before using the value as a C +string, make sure it is null-terminated. Call nc_inq_attlen() first to +find out the length of the attribute. +*/ +int +nc_get_att(int ncid, int varid, const char *name, void *value) +{ + NC* ncp; + int stat = NC_NOERR; + nc_type xtype; + + if ((stat = NC_check_id(ncid, &ncp))) + return stat; + + /* Need to get the type */ + if ((stat = nc_inq_atttype(ncid, varid, name, &xtype))) + return stat; + + return ncp->dispatch->get_att(ncid, varid, name, value, xtype); +} +/*! \} */ + +/*! +\ingroup attributes +Get an attribute. + +This function gets an attribute from the netCDF file. The nc_get_att() +function works with any type of data, including user defined types. + +\note The netCDF library reads all attributes into memory when the +file is opened with nc_open(). Getting an attribute copies the value +from the in-memory store, and does not incure any file I/O penalties. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL +for a global attribute. + +\param name Attribute \ref object_name. + +\param value Pointer to location for returned attribute value(s). All +elements of the vector of attribute values are returned, so you must +allocate enough space to hold them. If you don't know how much +space to reserve, call nc_inq_attlen() first to find out the length of +the attribute. + +

Example

+ +Here is an example using nc_get_att_double() to determine the values +of a variable attribute named valid_range for a netCDF variable named +rh and using nc_get_att_text() to read a global attribute named title +in an existing netCDF dataset named foo.nc. + +In this example, it is assumed that we don't know how many values will +be returned, but that we do know the types of the attributes. Hence, +to allocate enough space to store them, we must first inquire about +the length of the attributes. + +\code + #include + ... + int status; + int ncid; + int rh_id; + int vr_len, t_len; + double *vr_val; + char *title; + extern char *malloc() + + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_attlen (ncid, rh_id, "valid_range", &vr_len); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_attlen (ncid, NC_GLOBAL, "title", &t_len); + if (status != NC_NOERR) handle_error(status); + + vr_val = (double *) malloc(vr_len * sizeof(double)); + title = (char *) malloc(t_len + 1); + + status = nc_get_att_double(ncid, rh_id, "valid_range", vr_val); + if (status != NC_NOERR) handle_error(status); + status = nc_get_att_text(ncid, NC_GLOBAL, "title", title); + if (status != NC_NOERR) handle_error(status); + title[t_len] = '\0'; + ... +\endcode +*/ +/*! \{ */ +int +nc_get_att_text(int ncid, int varid, const char *name, char *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_CHAR); +} + +int +nc_get_att_schar(int ncid, int varid, const char *name, signed char *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_BYTE); +} + +int +nc_get_att_uchar(int ncid, int varid, const char *name, unsigned char *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UBYTE); +} + +int +nc_get_att_short(int ncid, int varid, const char *name, short *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_SHORT); +} + +int +nc_get_att_int(int ncid, int varid, const char *name, int *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_INT); +} + +int +nc_get_att_long(int ncid, int varid, const char *name, long *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, longtype); +} + +int +nc_get_att_float(int ncid, int varid, const char *name, float *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_FLOAT); +} + +int +nc_get_att_double(int ncid, int varid, const char *name, double *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_DOUBLE); +} + +int +nc_get_att_ubyte(int ncid, int varid, const char *name, unsigned char *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UBYTE); +} + +int +nc_get_att_ushort(int ncid, int varid, const char *name, unsigned short *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_USHORT); +} + +int +nc_get_att_uint(int ncid, int varid, const char *name, unsigned int *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UINT); +} + +int +nc_get_att_longlong(int ncid, int varid, const char *name, long long *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_INT64); +} + +int +nc_get_att_ulonglong(int ncid, int varid, const char *name, unsigned long long *value) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid, varid, name, (void *)value, NC_UINT64); +} + +int +nc_get_att_string(int ncid, int varid, const char *name, char **value) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_att(ncid,varid,name,(void*)value, NC_STRING); +} +/*! \} */ diff --git a/extern/src_netcdf4/dattinq.c b/extern/src_netcdf4/dattinq.c new file mode 100644 index 0000000000000000000000000000000000000000..c9d2c0755804e155db3d460e26ca5d2441418726 --- /dev/null +++ b/extern/src_netcdf4/dattinq.c @@ -0,0 +1,208 @@ +/** \file +Attribute inquiry functions + +These functions find out about attributes. + +Copyright 2011 University Corporation for Atmospheric +Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \name Learning about Attributes + +Functions to learn about the attributes in a file. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/** +\ingroup attributes +Return information about a netCDF attribute. + +The function nc_inq_att returns the attribute's type and length. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL +for a global attribute. + +\param name Pointer to the location for the returned attribute \ref +object_name. \ref ignored_if_null. + +\param xtypep Pointer to location for returned attribute \ref +data_type. \ref ignored_if_null. + +\param lenp Pointer to location for returned number of values +currently stored in the attribute. For attributes of type ::NC_CHAR, +you should not assume that this includes a trailing zero byte; it +doesn't if the attribute was stored without a trailing zero byte, for +example from a FORTRAN program. Before using the value as a C string, +make sure it is null-terminated. \ref ignored_if_null. + +\section Example + +Here is an example using nc_inq_att() to find out the type and length of +a variable attribute named valid_range for a netCDF variable named rh +and a global attribute named title in an existing netCDF dataset named +foo.nc: + +\code + #include + ... + int status; + int ncid; + int rh_id; + nc_type vr_type, t_type; + size_t vr_len, t_len; + + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_att (ncid, rh_id, "valid_range", &vr_type, &vr_len); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_att (ncid, NC_GLOBAL, "title", &t_type, &t_len); + if (status != NC_NOERR) handle_error(status); +\endcode +*/ +int +nc_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, + size_t *lenp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_att(ncid, varid, name, xtypep, lenp); +} + +/** +\ingroup attributes +Find an attribute ID. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL for +a global attribute. + +\param name Attribute \ref object_name. + +\param idp Pointer to location for returned attribute number that +specifies which attribute this is for this variable (or which global +attribute). If you already know the attribute name, knowing its number +is not very useful, because accessing information about an attribute +requires its name. +*/ +int +nc_inq_attid(int ncid, int varid, const char *name, int *idp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_attid(ncid, varid, name, idp); +} + +/** +\ingroup attributes +Find the name of an attribute. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL +for a global attribute. + +\param attnum Attribute number. The attributes for each variable are +numbered from 0 (the first attribute) to natts-1, where natts is the +number of attributes for the variable, as returned from a call to +nc_inq_varnatts(). + +\param name Pointer to the location for the returned attribute \ref +object_name. +*/ +int +nc_inq_attname(int ncid, int varid, int attnum, char *name) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_attname(ncid, varid, attnum, name); +} + +/** +\ingroup attributes +Find number of global or group attributes. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param nattsp Pointer where number of global or group attributes will be +written. \ref ignored_if_null. +*/ +int +nc_inq_natts(int ncid, int *nattsp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + if(nattsp == NULL) return NC_NOERR; + return ncp->dispatch->inq(ncid, NULL, NULL, nattsp, NULL); +} + +/** +\ingroup attributes +Find the type of an attribute. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL +for a global or group attribute. + +\param name Attribute \ref object_name. + +\param xtypep Pointer to location for returned attribute \ref data_type. +*/ +int +nc_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_att(ncid, varid, name, xtypep, NULL); +} + +/** +\ingroup attributes +Find the length of an attribute. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the attribute's variable, or ::NC_GLOBAL +for a global or group attribute. + +\param name Attribute \ref object_name. + +\param lenp Pointer to location for returned number of values +currently stored in the attribute. Before using the value as a C +string, make sure it is null-terminated. \ref ignored_if_null. +*/ +int +nc_inq_attlen(int ncid, int varid, const char *name, size_t *lenp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_att(ncid, varid, name, NULL, lenp); +} + +/*! \} */ /* End of named group ...*/ diff --git a/extern/src_netcdf4/dattput.c b/extern/src_netcdf4/dattput.c new file mode 100644 index 0000000000000000000000000000000000000000..5b74dc244a55d7a067dd882d712cb2a114d0ef65 --- /dev/null +++ b/extern/src_netcdf4/dattput.c @@ -0,0 +1,366 @@ +/** \file +Functions to write attributes. + +These functions read and write attributes. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \name Writing Attributes + +Functions to write attributes. */ +/*! \{ */ + +/*! +\ingroup attributes +Write a string attribute. + +The function nc_put_att_string adds or changes a variable attribute or +global attribute of an open netCDF dataset. The string type is only +available in netCDF-4/HDF5 files, when ::NC_CLASSIC_MODEL has not been +used in nc_create(). + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the variable to which the attribute will +be assigned or ::NC_GLOBAL for a global or group attribute. + +\param name Attribute \ref object_name. \ref attribute_conventions may +apply. + +\param len Number of values provided for the attribute. + +\param value Pointer to one or more values. + +\returns ::NC_NOERR No error. +\returns ::NC_EINVAL Trying to set global _FillValue. +\returns ::NC_ENOTVAR Couldn't find varid. +\returns ::NC_EBADTYPE Fill value and var must be same type. +\returns ::NC_ENOMEM Out of memory +\returns ::NC_ELATEFILL Fill values must be written while the file +is still in initial define mode. +*/ +int +nc_put_att_string(int ncid, int varid, const char *name, + size_t len, const char** value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, NC_STRING, + len, (void*)value, NC_STRING); +} + +/*! +\ingroup attributes +Write a text attribute. + +Add or change a text attribute. If this attribute is new, +or if the space required to store the attribute is greater than +before, the netCDF dataset must be in define mode. + +Although it's possible to create attributes of all types, text and +double attributes are adequate for most purposes. + +Use the nc_put_att function to create attributes of any type, +including user-defined types. We recommend using the type safe +versions of this function whenever possible. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the variable to which the attribute will +be assigned or ::NC_GLOBAL for a global attribute. + +\param name Attribute \ref object_name. \ref attribute_conventions may +apply. + +\param len Number of values provided for the attribute. + +\param value Pointer to one or more values. + +\returns ::NC_NOERR No error. +\returns ::NC_EINVAL Trying to set global _FillValue. +\returns ::NC_ENOTVAR Couldn't find varid. +\returns ::NC_EBADTYPE Fill value and var must be same type. +\returns ::NC_ENOMEM Out of memory +\returns ::NC_ELATEFILL Fill values must be written while the file +is still in initial define mode. + +\note With netCDF-4 files, nc_put_att will notice if you are writing a +_Fill_Value_ attribute, and will tell the HDF5 layer to use the +specified fill value for that variable. + +\section Example + +Here is an example using nc_put_att_double() to add a variable +attribute named valid_range for a netCDF variable named rh and +nc_put_att_text() to add a global attribute named title to an existing +netCDF dataset named foo.nc: + +\code + #include + ... + int status; + int ncid; + int rh_id; + static double rh_range[] = {0.0, 100.0}; + static char title[] = "example netCDF dataset"; + ... + status = nc_open("foo.nc", NC_WRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_redef(ncid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_put_att_double (ncid, rh_id, "valid_range", + NC_DOUBLE, 2, rh_range); + if (status != NC_NOERR) handle_error(status); + status = nc_put_att_text (ncid, NC_GLOBAL, "title", + strlen(title), title) + if (status != NC_NOERR) handle_error(status); + ... + status = nc_enddef(ncid); + if (status != NC_NOERR) handle_error(status); +\endcode +*/ +int +nc_put_att_text(int ncid, int varid, const char *name, + size_t len, const char *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, NC_CHAR, len, + (void *)value, NC_CHAR); +} + +/*! \} */ +/*! +\ingroup attributes +Write an attribute. + +The function nc_put_att_ type adds or changes a variable attribute or +global attribute of an open netCDF dataset. If this attribute is new, +or if the space required to store the attribute is greater than +before, the netCDF dataset must be in define mode. + +With netCDF-4 files, nc_put_att will notice if you are writing a +_Fill_Value_ attribute, and will tell the HDF5 layer to use the +specified fill value for that variable. + +Although it's possible to create attributes of all types, text and +double attributes are adequate for most purposes. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID of the variable to which the attribute will +be assigned or ::NC_GLOBAL for a global or group attribute. + +\param name Attribute \ref object_name. \ref attribute_conventions may +apply. + +\param xtype \ref data_type of the attribute. + +\param len Number of values provided for the attribute. + +\param value Pointer to one or more values. + +\returns ::NC_NOERR No error. +\returns ::NC_EINVAL Trying to set global _FillValue. +\returns ::NC_ENOTVAR Couldn't find varid. +\returns ::NC_EBADTYPE Fill value and var must be same type. +\returns ::NC_ENOMEM Out of memory +\returns ::NC_ELATEFILL Fill values must be written while the file +is still in initial define mode. + +\section Example + +Here is an example using nc_put_att_double() to add a variable +attribute named valid_range for a netCDF variable named rh and +nc_put_att_text() to add a global attribute named title to an existing +netCDF dataset named foo.nc: + +\code + #include + ... + int status; + int ncid; + int rh_id; + static double rh_range[] = {0.0, 100.0}; + static char title[] = "example netCDF dataset"; + ... + status = nc_open("foo.nc", NC_WRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_redef(ncid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_put_att_double (ncid, rh_id, "valid_range", + NC_DOUBLE, 2, rh_range); + if (status != NC_NOERR) handle_error(status); + status = nc_put_att_text (ncid, NC_GLOBAL, "title", + strlen(title), title) + if (status != NC_NOERR) handle_error(status); + ... + status = nc_enddef(ncid); + if (status != NC_NOERR) handle_error(status); +\endcode +*/ +/*! \{*/ +int +nc_put_att(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const void *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + value, xtype); +} + +int +nc_put_att_schar(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const signed char *value) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_BYTE); +} + +int +nc_put_att_uchar(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const unsigned char *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_UBYTE); +} + +int +nc_put_att_short(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const short *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_SHORT); +} + +int +nc_put_att_int(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const int *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_INT); +} + +int +nc_put_att_long(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const long *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, longtype); +} + +int +nc_put_att_float(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const float *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_FLOAT); +} + +int +nc_put_att_double(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const double *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_DOUBLE); +} + +int +nc_put_att_ubyte(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const unsigned char *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_UBYTE); +} + +int +nc_put_att_ushort(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const unsigned short *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_USHORT); +} + +int +nc_put_att_uint(int ncid, int varid, const char *name, + nc_type xtype, size_t len, const unsigned int *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_UINT); +} + +int +nc_put_att_longlong(int ncid, int varid, const char *name, + nc_type xtype, size_t len, + const long long *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_INT64); +} + +int +nc_put_att_ulonglong(int ncid, int varid, const char *name, + nc_type xtype, size_t len, + const unsigned long long *value) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_att(ncid, varid, name, xtype, len, + (void *)value, NC_UINT64); +} + diff --git a/extern/src_netcdf4/dceconstraints.c b/extern/src_netcdf4/dceconstraints.c new file mode 100644 index 0000000000000000000000000000000000000000..c43e53b9e075a427b16a769cfd160b2e9a7d9ca9 --- /dev/null +++ b/extern/src_netcdf4/dceconstraints.c @@ -0,0 +1,866 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/constraints3.c,v 1.40 2010/05/27 21:34:07 dmh Exp $ + *********************************************************************/ + +#include "config.h" + +#include +#include +#include +#include + +#include "nclist.h" +#include "ncbytes.h" +#include "nclog.h" + +#include "netcdf.h" +#include "dceconstraints.h" +#include "dapdebug.h" +#include "dceparselex.h" + +#define DEBUG + +int dceverbose = 0; + +static char* opstrings[] = OPSTRINGS ; + +static void ceallnodesr(DCEnode* node, NClist* allnodes, CEsort which); + +/* Parse incoming url constraints, if any, + to check for syntactic correctness +*/ +int +dapparseconstraints(char* constraints, DCEconstraint* dapconstraint) +{ + int ncstat = NC_NOERR; + char* errmsg; + + assert(dapconstraint != NULL); + nclistclear(dapconstraint->projections); + nclistclear(dapconstraint->selections); + + ncstat = dapceparse(constraints,dapconstraint,&errmsg); + if(ncstat) { + nclog(NCLOGWARN,"DAP constraint parse failure: %s",errmsg); + if(errmsg) free(errmsg); + nclistclear(dapconstraint->projections); + nclistclear(dapconstraint->selections); + } + +#ifdef DEBUG +fprintf(stderr,"constraint: %s",dcetostring((DCEnode*)dapconstraint)); +#endif + return ncstat; +} + +/* Worksheet + +mg.st = md.st * ms.st +mg.f = md.f+(ms.f*md.st) +mg.l = ((ms.l-1) / ms.st) * mg.st + 1 +mg.p = mg.f + mg.l +mg.c = mg.l / mg.st + +0000000000111111111122222222223 +0123456789012345678901234567890 + xxxxxx + xxxxxx + 0 1 2 3 4 5 6 7 8 md=(st=3 f=1 l=25 p=26) + 0 1 2 ms=(st=2 f=3 l=5 p=8 ) + ---------------------------- + mg=(st=6 f=10 p=23 l=13) +c = 4 / 2 = 2 +l = 2 * 6 + 1 = 13 + +0000000000111111 +0123456789012345 + 0 1 2 3 4 md=(st=2 f=1 l=9 p=10) + 0 1 2 ms=(st=1 f=2 l=3 p=5) + ---------------------------- + mg=(st=2 f=5 p=10 l=5 ) +c = 2/1 = 2 +l = 2 * 2 + 1 = 13 + +0000000000111111111 +0123456789012345678 + 0 1 2 3 4 5 6 7 8 md=(st=2 f=1 l=17 p=18) + 0 1 2 ms=(st=2 f=3 l=5 p=8) + ---------------------------- + mg=(st=4 f=7 p=16 l=9 ) +c = 4/2 = 2 +l = 2 * 4 + 1 = 9 + +0000000000111111111 +0123456789012345678 + 0 1 2 3 4 md=(st=2 f=1 l=9 p=10) + 0 1 2 3 4 ms=(st=1 f=0 l=5 p=5) + ---------------------------- + mg=(st=2 f=1 p=10 l=9 ) +c = 4/1 = 4 +l = 4 * 2 + 1 = 9 + +00000 +01234 +01 md=(st=1 f=0 l=2 p=2) +0 ms=(st=1 f=0 l=1 p=1) + ---------------------------- + mg=(st=1 f=0 p=1 l=1 ) +c = 0/1 = 0 +l = 0 * 1 + 1 = 1 + +000000000011 +012345678901 +012 md=(st=1 f=0 l=3 p=3) +012 ms=(st=1 f=0 l=3 p=2) + ---------------------------- + mg=(st=1 f=0 p=3 l=3 ) +c = 2/1 = 2 +l = 2 * 1 + 1 = 3 + +*/ + +/* Merge slice src into slice dst; dst != src */ + +int +dceslicemerge(DCEslice* dst, DCEslice* src) +{ + int err = NC_NOERR; + DCEslice tmp; + + tmp.node.sort = CES_SLICE; + tmp.stride = (dst->stride * src->stride); + tmp.first = (dst->first+((src->first)*(dst->stride))); + tmp.length = (((src->length - 1) / src->stride) * tmp.stride) + 1; + tmp.stop = tmp.first + tmp.length; + tmp.count = tmp.length / tmp.stride; + /* use max declsize */ + if(dst->declsize > src->declsize) { + tmp.declsize = dst->declsize; + } else { + tmp.declsize = src->declsize; + } + if(tmp.length % tmp.stride != 0) tmp.count++; + if(tmp.first >= dst->stop || tmp.stop > dst->stop) + err = NC_EINVALCOORDS; + else + *dst = tmp; + return err; +} + + +/* +Given two projection lists, merge +src into dst taking +overlapping projections into acct. +*/ +int +dcemergeprojectionlists(NClist* dst, NClist* src) +{ + int i; + NClist* cat = nclistnew(); + int ncstat = NC_NOERR; + +#ifdef DEBUG +fprintf(stderr,"dapmergeprojection: dst = %s\n",dcetostring((DCEnode*)dst)); +fprintf(stderr,"dapmergeprojection: src = %s\n",dcetostring((DCEnode*)src)); +#endif + + /* get dst concat clone(src) */ + nclistsetalloc(cat,nclistlength(dst)+nclistlength(src)); + for(i=0;i 0) { + DCEprojection* target = (DCEprojection*)nclistremove(cat,0); + if(target == NULL) continue; + if(target->discrim != CES_VAR) continue; + for(i=0;idiscrim != CES_VAR) continue; + if(dcesamepath(target->var->segments, + p2->var->segments)!=0) continue; + /* This entry matches our current target; merge */ + ncstat = dcemergeprojections(target,p2); + /* null out this merged entry and release it */ + nclistset(cat,i,(ncelem)NULL); + dcefree((DCEnode*)p2); + } + /* Capture the clone */ + nclistpush(dst,(ncelem)target); + } + nclistfree(cat); + return ncstat; +} + +/* Modify merged projection to include "addition" projection */ +int +dcemergeprojections(DCEprojection* merged, DCEprojection* addition) +{ + int ncstat = NC_NOERR; + int i,j; + + ASSERT((merged->discrim == CES_VAR && addition->discrim == CES_VAR)); + ASSERT((nclistlength(merged->var->segments) == nclistlength(addition->var->segments))); + for(i=0;ivar->segments);i++) { + DCEsegment* mergedseg = (DCEsegment*)nclistget(merged->var->segments,i); + DCEsegment* addedseg = (DCEsegment*)nclistget(addition->var->segments,i); + /* If one segment has larger rank, then copy the extra slices unchanged */ + for(j=0;jrank;j++) { + if(j < mergedseg->rank) + dceslicemerge(mergedseg->slices+j,addedseg->slices+j); + else + mergedseg->slices[j] = addedseg->slices[j]; + } + if(addedseg->rank > mergedseg->rank) + mergedseg->rank = addedseg->rank; + } + return ncstat; +} + +/* Convert a DCEprojection instance into a string + that can be used with the url +*/ + +char* +buildprojectionstring(NClist* projections) +{ + char* pstring; + NCbytes* buf = ncbytesnew(); + dcelisttobuffer(projections,buf,","); + pstring = ncbytesdup(buf); + ncbytesfree(buf); + return pstring; +} + +char* +buildselectionstring(NClist* selections) +{ + NCbytes* buf = ncbytesnew(); + char* sstring; + dcelisttobuffer(selections,buf,","); + sstring = ncbytesdup(buf); + ncbytesfree(buf); + return sstring; +} + +char* +buildconstraintstring(DCEconstraint* constraints) +{ + NCbytes* buf = ncbytesnew(); + char* result = NULL; + dcetobuffer((DCEnode*)constraints,buf); + result = ncbytesdup(buf); + ncbytesfree(buf); + return result; +} + +DCEnode* +dceclone(DCEnode* node) +{ + DCEnode* result = NULL; + + result = (DCEnode*)dcecreate(node->sort); + if(result == NULL) goto done; + + switch (node->sort) { + + case CES_SLICE: { + DCEslice* clone = (DCEslice*)result; + DCEslice* orig = (DCEslice*)node; + *clone = *orig; + } break; + + case CES_SEGMENT: { + DCEsegment* clone = (DCEsegment*)result; + DCEsegment* orig = (DCEsegment*)node; + *clone = *orig; + clone->name = nulldup(orig->name); + if(orig->rank > 0) + memcpy(clone->slices,orig->slices,orig->rank*sizeof(DCEslice)); + } break; + + case CES_VAR: { + DCEvar* clone = (DCEvar*)result; + DCEvar* orig = (DCEvar*)node; + *clone = *orig; + clone->segments = dceclonelist(clone->segments); + } break; + + case CES_FCN: { + DCEfcn* clone = (DCEfcn*)result; + DCEfcn* orig = (DCEfcn*)node; + *clone = *orig; + clone->name = nulldup(orig->name); + clone->args = dceclonelist(orig->args); + } break; + + case CES_CONST: { + DCEconstant* clone = (DCEconstant*)result; + DCEconstant* orig = (DCEconstant*)node; + *clone = *orig; + if(clone->discrim == CES_STR) + clone->text = nulldup(clone->text); + } break; + + case CES_VALUE: { + DCEvalue* clone = (DCEvalue*)result; + DCEvalue* orig = (DCEvalue*)node; + *clone = *orig; + switch (clone->discrim) { + case CES_CONST: + clone->constant = (DCEconstant*)dceclone((DCEnode*)orig->constant); break; + case CES_VAR: + clone->var = (DCEvar*)dceclone((DCEnode*)orig->var); break; + case CES_FCN: + clone->fcn = (DCEfcn*)dceclone((DCEnode*)orig->fcn); break; + default: assert(0); + } + } break; + + case CES_PROJECT: { + DCEprojection* clone = (DCEprojection*)result; + DCEprojection* orig = (DCEprojection*)node; + *clone = *orig; + switch (orig->discrim) { + case CES_VAR: + clone->var = (DCEvar*)dceclone((DCEnode*)orig->var); break; + case CES_FCN: + clone->fcn = (DCEfcn*)dceclone((DCEnode*)orig->fcn); break; + default: assert(0); + } + } break; + + case CES_SELECT: { + DCEselection* clone = (DCEselection*)result; + DCEselection* orig = (DCEselection*)node; + *clone = *orig; + clone->lhs = (DCEvalue*)dceclone((DCEnode*)orig->lhs); + clone->rhs = dceclonelist(orig->rhs); + } break; + + case CES_CONSTRAINT: { + DCEconstraint* clone = (DCEconstraint*)result; + DCEconstraint* orig = (DCEconstraint*)node; + *clone = *orig; + clone->projections = dceclonelist(orig->projections); + clone->selections = dceclonelist(orig->selections); + } break; + + default: + assert(0); + } + +done: + return result; +} + +NClist* +dceclonelist(NClist* list) +{ + int i; + NClist* clone; + if(list == NULL) return NULL; + clone = nclistnew(); + for(i=0;isort) { + + case CES_VAR: { + DCEvar* target = (DCEvar*)node; + dcefreelist(target->segments); + } break; + + case CES_FCN: { + DCEfcn* target = (DCEfcn*)node; + dcefreelist(target->args); + nullfree(target->name); + } break; + + case CES_CONST: { + DCEconstant* target = (DCEconstant*)node; + if(target->discrim == CES_STR) + nullfree(target->text); + } break; + + case CES_VALUE: { + DCEvalue* target = (DCEvalue*)node; + switch(target->discrim) { + case CES_CONST: dcefree((DCEnode*)target->constant); break; + case CES_VAR: dcefree((DCEnode*)target->var); break; + case CES_FCN: dcefree((DCEnode*)target->fcn); break; + default: assert(0); + } + } break; + + case CES_PROJECT: { + DCEprojection* target = (DCEprojection*)node; + switch (target->discrim) { + case CES_VAR: dcefree((DCEnode*)target->var); break; + case CES_FCN: dcefree((DCEnode*)target->fcn); break; + default: assert(0); + } + } break; + + case CES_SELECT: { + DCEselection* target = (DCEselection*)node; + dcefreelist(target->rhs); + dcefree((DCEnode*)target->lhs); + } break; + + case CES_CONSTRAINT: { + DCEconstraint* target = (DCEconstraint*)node; + dcefreelist(target->projections); + dcefreelist(target->selections); + } break; + + case CES_SEGMENT: { + DCEsegment* target = (DCEsegment*)node; + target->rank = 0; + nullfree(target->name); + } break; + + case CES_SLICE: { + } break; + + default: + assert(0); + } + + /* final action */ + free(node); +} + +void +dcefreelist(NClist* list) +{ + int i; + if(list == NULL) return; + for(i=0;i"); return;} + + switch (node->sort) { + + case CES_SLICE: { + DCEslice* slice = (DCEslice*)node; + size_t last = (slice->first+slice->length)-1; + if(slice->count == 1) { + snprintf(tmp,sizeof(tmp),"[%lu%s]", + (unsigned long)slice->first,dimdecl(slice->declsize)); + } else if(slice->stride == 1) { + snprintf(tmp,sizeof(tmp),"[%lu:%lu%s]", + (unsigned long)slice->first, + (unsigned long)last, + dimdecl(slice->declsize)); + } else { + snprintf(tmp,sizeof(tmp),"[%lu:%lu:%lu%s]", + (unsigned long)slice->first, + (unsigned long)slice->stride, + (unsigned long)last, + dimdecl(slice->declsize)); + } + ncbytescat(buf,tmp); + } break; + + case CES_SEGMENT: { + DCEsegment* segment = (DCEsegment*)node; + int rank = segment->rank; + char* name = (segment->name?segment->name:""); + name = nulldup(name); + ncbytescat(buf,name); + nullfree(name); + if(dceverbose && dceiswholesegment(segment)) + ncbytescat(buf,"*"); + if(dceverbose || !dceiswholesegment(segment)) { + for(i=0;islices+i; + dcetobuffer((DCEnode*)slice,buf); + } + } + } break; + + case CES_VAR: { + DCEvar* var = (DCEvar*)node; + dcelisttobuffer(var->segments,buf,"."); + } break; + + case CES_FCN: { + DCEfcn* fcn = (DCEfcn*)node; + ncbytescat(buf,fcn->name); + ncbytescat(buf,"("); + dcelisttobuffer(fcn->args,buf,","); + ncbytescat(buf,")"); + } break; + + case CES_CONST: { + DCEconstant* value = (DCEconstant*)node; + switch (value->discrim) { + case CES_STR: + ncbytescat(buf,value->text); + break; + case CES_INT: + snprintf(tmp,sizeof(tmp),"%lld",value->intvalue); + ncbytescat(buf,tmp); + break; + case CES_FLOAT: + snprintf(tmp,sizeof(tmp),"%g",value->floatvalue); + ncbytescat(buf,tmp); + break; + default: assert(0); + } + } break; + + case CES_VALUE: { + DCEvalue* value = (DCEvalue*)node; + switch (value->discrim) { + case CES_CONST: + dcetobuffer((DCEnode*)value->constant,buf); + break; + case CES_VAR: + dcetobuffer((DCEnode*)value->var,buf); + break; + case CES_FCN: + dcetobuffer((DCEnode*)value->fcn,buf); + break; + default: assert(0); + } + } break; + + case CES_PROJECT: { + DCEprojection* target = (DCEprojection*)node; + switch (target->discrim) { + case CES_VAR: + dcetobuffer((DCEnode*)target->var,buf); + break; + case CES_FCN: dcetobuffer((DCEnode*)target->fcn,buf); break; + default: assert(0); + } + } break; + + case CES_SELECT: { + DCEselection* sel = (DCEselection*)node; + dcetobuffer((DCEnode*)sel->lhs,buf); + if(sel->operator == CES_NIL) break; + ncbytescat(buf,opstrings[(int)sel->operator]); + if(nclistlength(sel->rhs) > 1) + ncbytescat(buf,"{"); + dcelisttobuffer(sel->rhs,buf,","); + if(nclistlength(sel->rhs) > 1) + ncbytescat(buf,"}"); + } break; + + case CES_CONSTRAINT: { + DCEconstraint* con = (DCEconstraint*)node; + if(con->projections != NULL && nclistlength(con->projections) > 0) { + dcelisttobuffer(con->projections,buf,","); + } + if(con->selections != NULL && nclistlength(con->selections) > 0) { + ncbytescat(buf,"&"); /* because & is really a prefix */ + dcelisttobuffer(con->selections,buf,"&"); + } + } break; + + case CES_NIL: { + ncbytescat(buf,""); + } break; + + default: + assert(0); + } +} + +char* +dcelisttostring(NClist* list, char* sep) +{ + char* s; + NCbytes* buf = ncbytesnew(); + dcelisttobuffer(list,buf,sep); + s = ncbytesextract(buf); + ncbytesfree(buf); + return s; +} + +void +dcelisttobuffer(NClist* list, NCbytes* buf, char* sep) +{ + int i; + if(list == NULL || buf == NULL) return; + if(sep == NULL) sep = ","; + for(i=0;i0) ncbytescat(buf,sep); + dcetobuffer((DCEnode*)node,buf); + } +} + +/* Collect all nodes within a specified constraint tree */ +/* Caller frees result */ +NClist* +dceallnodes(DCEnode* node, CEsort which) +{ + NClist* allnodes = nclistnew(); + ceallnodesr(node,allnodes,which); + return allnodes; +} + +static void +ceallnodesr(DCEnode* node, NClist* allnodes, CEsort which) +{ + int i; + if(node == NULL) return; + if(nclistcontains(allnodes,(ncelem)node)) return; + if(which == CES_NIL || node->sort == which) + nclistpush(allnodes,(ncelem)node); + switch(node->sort) { + case CES_FCN: { + DCEfcn* fcn = (DCEfcn*)node; + for(i=0;iargs);i++) { + ceallnodesr((DCEnode*)nclistget(fcn->args,i),allnodes,which); + } + } break; + case CES_VAR: { + DCEvar* var = (DCEvar*)node; + for(i=0;isegments);i++) { + ceallnodesr((DCEnode*)nclistget(var->segments,i),allnodes,which); + } + } break; + case CES_VALUE: { + DCEvalue* value = (DCEvalue*)node; + if(value->discrim == CES_VAR) + ceallnodesr((DCEnode*)value->var,allnodes,which); + else if(value->discrim == CES_FCN) + ceallnodesr((DCEnode*)value->fcn,allnodes,which); + else + ceallnodesr((DCEnode*)value->constant,allnodes,which); + } break; + case CES_SELECT: { + DCEselection* selection = (DCEselection*)node; + ceallnodesr((DCEnode*)selection->lhs,allnodes,which); + for(i=0;irhs);i++) + ceallnodesr((DCEnode*)nclistget(selection->rhs,i),allnodes,which); + } break; + case CES_PROJECT: { + DCEprojection* projection = (DCEprojection*)node; + if(projection->discrim == CES_VAR) + ceallnodesr((DCEnode*)projection->var,allnodes,which); + else + ceallnodesr((DCEnode*)projection->fcn,allnodes,which); + } break; + case CES_CONSTRAINT: { + DCEconstraint* constraint = (DCEconstraint*)node; + for(i=0;iprojections);i++) + ceallnodesr((DCEnode*)nclistget(constraint->projections,i),allnodes,which); + for(i=0;iselections);i++) + ceallnodesr((DCEnode*)nclistget(constraint->selections,i),allnodes,which); + } break; + + /* All others have no subnodes */ + default: + break; + } +} + +DCEnode* +dcecreate(CEsort sort) +{ + DCEnode* node = NULL; + + switch (sort) { + + case CES_SLICE: { + DCEslice* target = (DCEslice*)calloc(1,sizeof(DCEslice)); + if(target == NULL) return NULL; + node = (DCEnode*)target; + } break; + + case CES_SEGMENT: { + int i; + DCEsegment* target = (DCEsegment*)calloc(1,sizeof(DCEsegment)); + if(target == NULL) return NULL; + /* Initialize the sort of the slices */ + for(i=0;islices[i].node.sort = CES_SLICE; + node = (DCEnode*)target; + } break; + + case CES_CONST: { + DCEconstant* target = (DCEconstant*)calloc(1,sizeof(DCEconstant)); + if(target == NULL) return NULL; + node = (DCEnode*)target; + target->discrim = CES_NIL; + } break; + + case CES_VALUE: { + DCEvalue* target = (DCEvalue*)calloc(1,sizeof(DCEvalue)); + if(target == NULL) return NULL; + node = (DCEnode*)target; + target->discrim = CES_NIL; + } break; + + case CES_VAR: { + DCEvar* target = (DCEvar*)calloc(1,sizeof(DCEvar)); + if(target == NULL) return NULL; + node = (DCEnode*)target; + } break; + + case CES_FCN: { + DCEfcn* target = (DCEfcn*)calloc(1,sizeof(DCEfcn)); + if(target == NULL) return NULL; + node = (DCEnode*)target; + } break; + + case CES_PROJECT: { + DCEprojection* target = (DCEprojection*)calloc(1,sizeof(DCEprojection)); + if(target == NULL) return NULL; + node = (DCEnode*)target; + } break; + + case CES_SELECT: { + DCEselection* target = (DCEselection*)calloc(1,sizeof(DCEselection)); + if(target == NULL) return NULL; + node = (DCEnode*)target; + target->operator = CEO_NIL; + } break; + + case CES_CONSTRAINT: { + DCEconstraint* target = (DCEconstraint*)calloc(1,sizeof(DCEconstraint)); + if(target == NULL) return NULL; + node = (DCEnode*)target; + } break; + + default: + assert(0); + } + + /* final action */ + node->sort = sort; + return node; +} + +int +dceiswholeslice(DCEslice* slice) +{ + if(slice->first != 0 + || slice->stride != 1 + || slice->stop != slice->declsize) return 0; + return 1; +} + +int +dceiswholesegment(DCEsegment* seg) +{ + int i,whole; + + if(!seg->slicesdefined) return 0; /* actually, we don't know */ + whole = 1; /* assume so */ + for(i=0;irank;i++) { + if(!dceiswholeslice(&seg->slices[i])) {whole = 0; break;} + } + return whole; +} + +void +dcemakewholeslice(DCEslice* slice, size_t declsize) +{ + slice->first = 0; + slice->stride = 1; + slice->length = declsize; + slice->stop = declsize; + slice->declsize = declsize; + slice->count = declsize; +} + +/* Remove slicing from terminal segment of p */ +void +dcemakewholeprojection(DCEprojection* p) +{ + /* Remove the slicing (if any) from the last segment */ + if(p->discrim == CES_VAR && p->var != NULL && p->var->segments != NULL) { + int lastindex = nclistlength(p->var->segments) - 1; + DCEsegment* lastseg = (DCEsegment*)nclistget(p->var->segments,lastindex); + lastseg->rank = 0; + } +} + +int +dcesamepath(NClist* list1, NClist* list2) +{ + int i; + int len = nclistlength(list1); + if(len != nclistlength(list2)) return 0; + for(i=0;iname,s2->name) != 0) return 0; + } + return 1; +} diff --git a/extern/src_netcdf4/dceconstraints.h b/extern/src_netcdf4/dceconstraints.h new file mode 100644 index 0000000000000000000000000000000000000000..160db423d4f94486d2391ec3cb9aea674eb8940b --- /dev/null +++ b/extern/src_netcdf4/dceconstraints.h @@ -0,0 +1,122 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + *********************************************************************/ +/* $Header$ */ + +#ifndef DCECONSTRAINTS_H +#define DCECONSTRAINTS_H 1 + +#include "ceconstraints.h" + +/* Provide a universal cast type containing common fields */ + +/* Define the common "supertype */ +typedef struct DCEnode { + CEsort sort; +} DCEnode; + +/* The slice structure is assumed common to all uses */ +typedef struct DCEslice { + DCEnode node; + size_t first; + size_t count; + size_t length; /* count*stride */ + size_t stride; + size_t stop; /* == first + count*/ + size_t declsize; /* from defining dimension, if any.*/ +} DCEslice; + +typedef struct DCEsegment { + DCEnode node; + char* name; + int slicesdefined; /*1=>slice counts defined, except declsize*/ + int slicesdeclized; /*1=>slice declsize defined */ + size_t rank; + DCEslice slices[NC_MAX_VAR_DIMS]; + void* annotation; +} DCEsegment; + +typedef struct DCEfcn { + DCEnode node; + char* name; + NClist* args; +} DCEfcn; + +typedef struct DCEvar { + DCEnode node; + NClist* segments; + void* annotation; +} DCEvar; + +typedef struct DCEconstant { + DCEnode node; + CEsort discrim; + char* text; + long long intvalue; + double floatvalue; +} DCEconstant; + +typedef struct DCEvalue { + DCEnode node; + CEsort discrim; + /* Do not bother with a union */ + DCEconstant* constant; + DCEvar* var; + DCEfcn* fcn; +} DCEvalue; + +typedef struct DCEselection { + DCEnode node; + CEsort operator; + DCEvalue* lhs; + NClist* rhs; +} DCEselection; + +typedef struct DCEprojection { + DCEnode node; + CEsort discrim; + /* Do not bother with a union */ + DCEvar* var; + DCEfcn* fcn; +} DCEprojection; + +typedef struct DCEconstraint { + DCEnode node; + NClist* projections; + NClist* selections; +} DCEconstraint; + + +extern int dceparseconstraints(char* constraints, DCEconstraint* DCEonstraint); +extern int dceslicemerge(DCEslice* dst, DCEslice* src); +extern int dcemergeprojectionlists(NClist* dst, NClist* src); + +extern DCEnode* dceclone(DCEnode* node); +extern NClist* dceclonelist(NClist* list); + +extern void dcefree(DCEnode* node); +extern void dcefreelist(NClist* list); + +extern char* dcetostring(DCEnode* node); +extern char* dcelisttostring(NClist* list,char*); +extern void dcetobuffer(DCEnode* node, NCbytes* buf); +extern void dcelisttobuffer(NClist* list, NCbytes* buf,char*); + +extern NClist* dceallnodes(DCEnode* node, CEsort which); + +extern DCEnode* dcecreate(CEsort sort); + +extern void dcemakewholeslice(DCEslice* slice, size_t declsize); +extern void dcemakewholeprojection(DCEprojection*); + +extern int dceiswholesegment(DCEsegment*); +extern int dceiswholeslice(DCEslice*); +extern int dceiswholeseglist(NClist*); +extern int dceiswholeprojection(DCEprojection*); +extern int dcesamepath(NClist* list1, NClist* list2); +extern int dcemergeprojections(DCEprojection* dst, DCEprojection* src); + +extern int dceverbose; + +#endif /*DCECONSTRAINTS_H*/ diff --git a/extern/src_netcdf4/dcelex.c b/extern/src_netcdf4/dcelex.c new file mode 100644 index 0000000000000000000000000000000000000000..456e5209bdbeea36f4378eeb3f1965b925db2e60 --- /dev/null +++ b/extern/src_netcdf4/dcelex.c @@ -0,0 +1,216 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include +#include +#include +#include + +#include "netcdf.h" + +#include "nclist.h" +#include "ncbytes.h" +#include "dceconstraints.h" +#include "dceparselex.h" + +/* Forward */ +static void dumptoken(DCElexstate* lexstate); +static int tohex(int c); +static void ceaddyytext(DCElexstate* lex, int c); + +/****************************************************/ +/* Define 1 and > 1st legal characters */ +static char* wordchars1 = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\"; +static char* wordcharsn = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-+_/%\\"; + +/* Number characters */ +static char* numchars1="+-0123456789"; +static char* numcharsn="Ee.+-0123456789"; + +/**************************************************/ + +int +dcelex(YYSTYPE* lvalp, DCEparsestate* state) +{ + DCElexstate* lexstate = state->lexstate; + int token; + int c; + int len; + char* p=lexstate->next; + token = 0; + ncbytesclear(lexstate->yytext); + ncbytesnull(lexstate->yytext); + p=lexstate->next; + while(token == 0 && (c=*p)) { + if(c <= ' ' || c >= '\177') {p++; continue;} + if(c == '"') { + int more = 1; + /* We have a SCAN_STRINGCONST */ + while(more && (c=*(++p))) { + switch (c) { + case '"': p++; more=0; break; + case '\\': + c=*(++p); + switch (c) { + case 'r': c = '\r'; break; + case 'n': c = '\n'; break; + case 'f': c = '\f'; break; + case 't': c = '\t'; break; + case 'x': { + int d1,d2; + c = '?'; + ++p; + d1 = tohex(*p++); + if(d1 < 0) { + dceerror(state,"Illegal \\xDD in SCAN_STRING"); + } else { + d2 = tohex(*p++); + if(d2 < 0) { + dceerror(state,"Illegal \\xDD in SCAN_STRING"); + } else { + c=(((unsigned int)d1)<<4) | (unsigned int)d2; + } + } + } break; + default: break; + } + break; + default: break; + } + ceaddyytext(lexstate,c); + } + token=SCAN_STRINGCONST; + } else if(strchr(numchars1,c) != NULL) { + /* we might have a SCAN_NUMBERCONST */ + int isnumber = 0; + char* yytext; + char* endpoint; + ceaddyytext(lexstate,c); + for(p++;(c=*p);p++) { + if(strchr(numcharsn,c) == NULL) break; + ceaddyytext(lexstate,c); + } + /* See if this is a number */ + ncbytesnull(lexstate->yytext); + yytext = ncbytescontents(lexstate->yytext); + (void)strtoll(yytext,&endpoint,10); + if(*yytext != '\0' && *endpoint == '\0') + isnumber = 1; + else { + (void)strtod(yytext,&endpoint); + if(*yytext != '\0' && *endpoint == '\0') + isnumber = 1; /* maybe */ + } + /* A number followed by an id char is assumed to just be + a funny id */ + if(isnumber && (*p == '\0' || strchr(wordcharsn,*p) == NULL)) { + token = SCAN_NUMBERCONST; + } else { + /* Now, if the funny word has a "." in it, + we have to back up to that dot */ + char* dotpoint = strchr(yytext,'.'); + if(dotpoint != NULL) { + p = dotpoint; + *dotpoint = '\0'; + } + token = SCAN_WORD; + } + } else if(strchr(wordchars1,c) != NULL) { + /* we have a SCAN_WORD */ + ceaddyytext(lexstate,c); + for(p++;(c=*p);p++) { + if(strchr(wordcharsn,c) == NULL) break; + ceaddyytext(lexstate,c); + } + token=SCAN_WORD; + } else { + /* we have a single char token */ + token = c; + ceaddyytext(lexstate,c); + p++; + } + } + lexstate->next = p; + len = ncbyteslength(lexstate->yytext); + if(len > MAX_TOKEN_LENGTH) len = MAX_TOKEN_LENGTH; + strncpy(lexstate->lasttokentext,ncbytescontents(lexstate->yytext),len); + lexstate->lasttokentext[len] = '\0'; + lexstate->lasttoken = token; + if(dcedebug) dumptoken(lexstate); + + /*Put return value onto Bison stack*/ + + if(ncbyteslength(lexstate->yytext) == 0) + *lvalp = NULL; + else { + *lvalp = ncbytesdup(lexstate->yytext); + nclistpush(lexstate->reclaim,(ncelem)*lvalp); + } + + return token; +} + +static void +ceaddyytext(DCElexstate* lex, int c) +{ + ncbytesappend(lex->yytext,(char)c); +} + +static int +tohex(int c) +{ + if(c >= 'a' && c <= 'f') return (c - 'a') + 0xa; + if(c >= 'A' && c <= 'F') return (c - 'A') + 0xa; + if(c >= '0' && c <= '9') return (c - '0'); + return -1; +} + +static void +dumptoken(DCElexstate* lexstate) +{ + switch (lexstate->lasttoken) { + case SCAN_STRINGCONST: + fprintf(stderr,"TOKEN = |\"%s\"|\n",lexstate->lasttokentext); + break; + case SCAN_WORD: + case SCAN_NUMBERCONST: + default: + fprintf(stderr,"TOKEN = |%s|\n",lexstate->lasttokentext); + break; + } +} + +void +dcelexinit(char* input, DCElexstate** lexstatep) +{ + DCElexstate* lexstate = (DCElexstate*)malloc(sizeof(DCElexstate)); + if(lexstatep) *lexstatep = lexstate; + if(lexstate == NULL) return; + memset((void*)lexstate,0,sizeof(DCElexstate)); + lexstate->input = strdup(input); + lexstate->next = lexstate->input; + lexstate->yytext = ncbytesnew(); + lexstate->reclaim = nclistnew(); +} + +void +dcelexcleanup(DCElexstate** lexstatep) +{ + DCElexstate* lexstate = *lexstatep; + if(lexstate == NULL) return; + if(lexstate->input != NULL) free(lexstate->input); + if(lexstate->reclaim != NULL) { + while(nclistlength(lexstate->reclaim) > 0) { + char* word = (char*)nclistpop(lexstate->reclaim); + if(word) free(word); + } + nclistfree(lexstate->reclaim); + } + ncbytesfree(lexstate->yytext); + free(lexstate); + *lexstatep = NULL; +} + diff --git a/extern/src_netcdf4/dceparse.c b/extern/src_netcdf4/dceparse.c new file mode 100644 index 0000000000000000000000000000000000000000..9e7c941ef7be7202435449b51c3a77cb0ddd9d7f --- /dev/null +++ b/extern/src_netcdf4/dceparse.c @@ -0,0 +1,397 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +/* Parser actions for constraint expressions */ + +/* Since oc does not use the constraint parser, + they functions all just abort if called. +*/ + +#include "config.h" +#include +#include +#include +#include + +#include "netcdf.h" + +#include "nclist.h" +#include "ncbytes.h" +#include "dceconstraints.h" +#include "dceparselex.h" + +static Object collectlist(Object list0, Object decl); + +void +projections(DCEparsestate* state, Object list0) +{ + NClist* list = (NClist*)list0; + if(list != NULL) { + nclistfree(state->constraint->projections); + state->constraint->projections = list; + } +#ifdef DEBUG +fprintf(stderr," ce.projections: %s\n", + dcetostring((DCEnode*)state->constraint->projections)); +#endif +} + +void +selections(DCEparsestate* state, Object list0) +{ + NClist* list = (NClist*)list0; + if(list != NULL) { + nclistfree(state->constraint->selections); + state->constraint->selections = list; + } +#ifdef DEBUG +fprintf(stderr," ce.selections: %s\n", + dcetostring((DCEnode*)state->constraint->selections)); +#endif +} + + +Object +projectionlist(DCEparsestate* state, Object list0, Object decl) +{ + return collectlist(list0,decl); +} + +Object +projection(DCEparsestate* state, Object varorfcn) +{ + DCEprojection* p = (DCEprojection*)dcecreate(CES_PROJECT); + CEsort tag = *(CEsort*)varorfcn; + if(tag == CES_FCN) + p->fcn = varorfcn; + else + p->var = varorfcn; + p->discrim = tag; +#ifdef DEBUG +fprintf(stderr," ce.projection: %s\n", + dcetostring((DCEnode*)p)); +#endif + return p; +} + +Object +segmentlist(DCEparsestate* state, Object var0, Object decl) +{ + /* watch out: this is non-standard */ + NClist* list; + DCEvar* v = (DCEvar*)var0; + if(v==NULL) v = (DCEvar*)dcecreate(CES_VAR); + list = v->segments; + if(list == NULL) list = nclistnew(); + nclistpush(list,(ncelem)decl); + v->segments = list; + return v; +} + +Object +segment(DCEparsestate* state, Object name, Object slices0) +{ + int i; + DCEsegment* segment = (DCEsegment*)dcecreate(CES_SEGMENT); + NClist* slices = (NClist*)slices0; + segment->name = strdup((char*)name); + if(slices != NULL && nclistlength(slices) > 0) { + segment->rank = nclistlength(slices); + segment->slicesdefined = 1; /* but not declsizes */ + for(i=0;islices[i] = *slice; + free(slice); + } + nclistfree(slices); + } else + segment->slicesdefined = 0; +#ifdef DEBUG +fprintf(stderr," ce.segment: %s\n", + dumpsegment(segment)); +#endif + return segment; +} + + +Object +rangelist(DCEparsestate* state, Object list0, Object decl) +{ + return collectlist(list0,decl); +} + +Object +range(DCEparsestate* state, Object sfirst, Object sstride, Object slast) +{ + DCEslice* slice = (DCEslice*)dcecreate(CES_SLICE); + unsigned long first,stride,last; + + /* Note: that incoming arguments are strings; we must convert to size_t; + but we do know they are legal integers or NULL */ + sscanf((char*)sfirst,"%lu",&first); /* always defined */ + if(slast != NULL) + sscanf((char*)slast,"%lu",&last); + else + last = first; + if(sstride != NULL) + sscanf((char*)sstride,"%lu",&stride); + else + stride = 1; /* default */ + + if(stride == 0) + dceerror(state,"Illegal index for range stride"); + if(last < first) + dceerror(state,"Illegal index for range last index"); + slice->first = first; + slice->stride = stride; + slice->stop = last + 1; + slice->length = slice->stop - slice->first; + slice->count = slice->length / slice->stride; +#ifdef DEBUG +fprintf(stderr," ce.slice: %s\n", + dumpslice(slice)); +#endif + return slice; +} + +Object +range1(DCEparsestate* state, Object rangenumber) +{ + int range = -1; + sscanf((char*)rangenumber,"%u",&range); + if(range < 0) { + dceerror(state,"Illegal range index"); + } + return rangenumber; +} + +Object +clauselist(DCEparsestate* state, Object list0, Object decl) +{ + return collectlist(list0,decl); +} + +Object +sel_clause(DCEparsestate* state, int selcase, + Object lhs, Object relop0, Object values) +{ + DCEselection* sel = (DCEselection*)dcecreate(CES_SELECT); + sel->operator = (CEsort)relop0; + sel->lhs = (DCEvalue*)lhs; + if(selcase == 2) {/*singleton value*/ + sel->rhs = nclistnew(); + nclistpush(sel->rhs,(ncelem)values); + } else + sel->rhs = (NClist*)values; + return sel; +} + +Object +indexpath(DCEparsestate* state, Object list0, Object index) +{ + return collectlist(list0,index); +} + +Object +array_indices(DCEparsestate* state, Object list0, Object indexno) +{ + DCEslice* slice; + long long start = -1; + NClist* list = (NClist*)list0; + if(list == NULL) list = nclistnew(); + sscanf((char*)indexno,"%lld",&start); + if(start < 0) { + dceerror(state,"Illegal array index"); + start = 1; + } + slice = (DCEslice*)dcecreate(CES_SLICE); + slice->first = start; + slice->stride = 1; + slice->count = 1; + slice->length = 1; + slice->stop = start+1; + nclistpush(list,(ncelem)slice); + return list; +} + +Object +indexer(DCEparsestate* state, Object name, Object indices) +{ + int i; + NClist* list = (NClist*)indices; + DCEsegment* seg = (DCEsegment*)dcecreate(CES_SEGMENT); + seg->name = strdup((char*)name); + for(i=0;islices[i] = *slice; + free(slice); + } + nclistfree(indices); + return seg; +} + +Object +function(DCEparsestate* state, Object fcnname, Object args) +{ + DCEfcn* fcn = (DCEfcn*)dcecreate(CES_FCN); + fcn->name = nulldup((char*)fcnname); + fcn->args = args; + return fcn; +} + +Object +arg_list(DCEparsestate* state, Object list0, Object decl) +{ + return collectlist(list0,decl); +} + + +Object +value_list(DCEparsestate* state, Object list0, Object decl) +{ + return collectlist(list0,decl); +} + +Object +value(DCEparsestate* state, Object val) +{ + DCEvalue* ncvalue = (DCEvalue*)dcecreate(CES_VALUE); + CEsort tag = *(CEsort*)val; + switch (tag) { + case CES_VAR: ncvalue->var = (DCEvar*)val; break; + case CES_FCN: ncvalue->fcn = (DCEfcn*)val; break; + case CES_CONST: ncvalue->constant = (DCEconstant*)val; break; + default: abort(); break; + } + ncvalue->discrim = tag; + return ncvalue; +} + +Object +var(DCEparsestate* state, Object indexpath) +{ + DCEvar* v = (DCEvar*)dcecreate(CES_VAR); + v->segments = (NClist*)indexpath; + return v; +} + +Object +constant(DCEparsestate* state, Object val, int tag) +{ + DCEconstant* con = (DCEconstant*)dcecreate(CES_CONST); + char* text = (char*)val; + char* endpoint = NULL; + switch (tag) { + case SCAN_STRINGCONST: + con->discrim = CES_STR; + con->text = nulldup(text); + break; + case SCAN_NUMBERCONST: + con->intvalue = strtoll(text,&endpoint,10); + if(*text != '\0' && *endpoint == '\0') { + con->discrim = CES_INT; + } else { + con->floatvalue = strtod(text,&endpoint); + if(*text != '\0' && *endpoint == '\0') + con->discrim = CES_FLOAT; + else abort(); + } + break; + default: abort(); break; + } + return con; +} + +static Object +collectlist(Object list0, Object decl) +{ + NClist* list = (NClist*)list0; + if(list == NULL) list = nclistnew(); + nclistpush(list,(ncelem)decl); + return list; +} + +Object +makeselectiontag(CEsort tag) +{ + return (Object) tag; +} + +int +dceerror(DCEparsestate* state, char* msg) +{ + strcpy(state->errorbuf,msg); + state->errorcode=1; + return 0; +} + +static void +dce_parse_cleanup(DCEparsestate* state) +{ + dcelexcleanup(&state->lexstate); /* will free */ +} + +static DCEparsestate* +ce_parse_init(char* input, DCEconstraint* constraint) +{ + DCEparsestate* state = NULL; + if(input==NULL) { + dceerror(state,"ce_parse_init: no input buffer"); + } else { + state = (DCEparsestate*)calloc(1,sizeof(DCEparsestate)); + if(state==NULL) return (DCEparsestate*)NULL; + state->errorbuf[0] = '\0'; + state->errorcode = 0; + dcelexinit(input,&state->lexstate); + state->constraint = constraint; + } + return state; +} + +#ifdef PARSEDEBUG +extern int dcedebug; +#endif + +/* Wrapper for ceparse */ +int +dapceparse(char* input, DCEconstraint* constraint, char** errmsgp) +{ + DCEparsestate* state; + int errcode = 0; + +#ifdef PARSEDEBUG +dcedebug = 1; +#endif + + if(input != NULL) { +#ifdef DEBUG +fprintf(stderr,"dceeparse: input=%s\n",input); +#endif + state = ce_parse_init(input,constraint); + if(dceparse(state) == 0) { +#ifdef DEBUG +if(nclistlength(constraint->projections) > 0) +fprintf(stderr,"dceeparse: projections=%s\n", + dcetostring((DCEnode*)constraint->projections)); +#endif +#ifdef DEBUG +if(nclistlength(constraint->selections) > 0) +fprintf(stderr,"dceeparse: selections=%s\n", + dumpselections(constraint->selections)); +#endif + } else { + if(errmsgp) *errmsgp = nulldup(state->errorbuf); + } + errcode = state->errorcode; + dce_parse_cleanup(state); + } + return errcode; +} + +#ifdef PARSEDEBUG +Object +debugobject(Object o) +{ + return o; +} +#endif diff --git a/extern/src_netcdf4/dceparselex.h b/extern/src_netcdf4/dceparselex.h new file mode 100644 index 0000000000000000000000000000000000000000..07f19d50698fa86bdcffa325c4251c0dddbd81a3 --- /dev/null +++ b/extern/src_netcdf4/dceparselex.h @@ -0,0 +1,100 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef DCEPARSELEX_H +#define DCEPARSELEX_H + +#include "config.h" +#include "dcetab.h" + +#ifdef WIN32 +#define strcasecmp stricmp +#define snprintf _snprintf +#endif + +/* For consistency with Java parser */ +#ifndef null +#define null NULL +#endif + +typedef void* Object; + +#define YYSTYPE Object + +#define MAX_TOKEN_LENGTH 1024 + +/*! Specifies DCElexstate. */ +typedef struct DCElexstate { + char* input; + char* next; /* next char in uri.query */ + NCbytes* yytext; + /*! Specifies the Lasttoken. */ + int lasttoken; + char lasttokentext[MAX_TOKEN_LENGTH+1]; /* leave room for trailing null */ + NClist* reclaim; /* reclaim SCAN_WORD instances */ +} DCElexstate; + +/*! Specifies DCEparsestate. */ +typedef struct DCEparsestate { + DCEconstraint* constraint; + char errorbuf[1024]; + int errorcode; + DCElexstate* lexstate; +} DCEparsestate; + +/* Define a generic object carrier; this serves + essentially the same role as the typical bison %union + declaration +*/ + + +extern int ceerror(DCEparsestate*,char*); +extern void ce_parse_error(DCEparsestate*,const char *fmt, ...); + +/* bison parse entry point */ +extern int dceparse(DCEparsestate*); + +extern int dceerror(DCEparsestate* state, char* msg); +extern void projections(DCEparsestate* state, Object list0); +extern void selections(DCEparsestate* state, Object list0); +extern Object projectionlist(DCEparsestate* state, Object list0, Object decl); +extern Object projection(DCEparsestate* state, Object segmentlist); +extern Object segmentlist(DCEparsestate* state, Object list0, Object decl); +extern Object segment(DCEparsestate* state, Object name, Object slices0); +extern Object array_indices(DCEparsestate* state, Object list0, Object decl); +extern Object range(DCEparsestate* state, Object, Object, Object); +extern Object selectionlist(DCEparsestate* state, Object list0, Object decl); +extern Object sel_clause(DCEparsestate* state, int selcase, Object path0, Object relop0, Object values); +extern Object selectionpath(DCEparsestate* state, Object list0, Object text); +extern Object arrayelement(DCEparsestate* state, Object name, Object index); +extern Object function(DCEparsestate* state, Object fcnname, Object args); +extern Object arg_list(DCEparsestate* state, Object list0, Object decl); +extern Object value_list(DCEparsestate* state, Object list0, Object decl); +extern Object value(DCEparsestate* state, Object value); +extern Object makeselectiontag(CEsort); +extern Object indexer(DCEparsestate* state, Object name, Object indices); +extern Object indexpath(DCEparsestate* state, Object list0, Object index); +extern Object var(DCEparsestate* state, Object indexpath); +extern Object constant(DCEparsestate* state, Object val, int tag); +extern Object clauselist(DCEparsestate* state, Object list0, Object decl); +extern Object range1(DCEparsestate* state, Object rangenumber); +extern Object rangelist(DCEparsestate* state, Object list0, Object decl); + +/* lexer interface */ +extern int dcelex(YYSTYPE*, DCEparsestate*); +extern void dcelexinit(char* input, DCElexstate** lexstatep); +extern void dcelexcleanup(DCElexstate** lexstatep); + +extern int dcedebug; + +#ifdef PARSEDEBUG +extern Object debugobject(Object); +#define checkobject(x) debugobject(x) +#else +#define checkobject(x) (x) +#endif + +extern int dapceparse(char* input, DCEconstraint*, char**); + +#endif /*DCEPARSELEX_H*/ + diff --git a/extern/src_netcdf4/dcetab.c b/extern/src_netcdf4/dcetab.c new file mode 100644 index 0000000000000000000000000000000000000000..d618a90b332448d503ef57e49f6dec090a96b5dd --- /dev/null +++ b/extern/src_netcdf4/dcetab.c @@ -0,0 +1,1997 @@ +/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse dceparse +#define yylex dcelex +#define yyerror dceerror +#define yylval dcelval +#define yychar dcechar +#define yydebug dcedebug +#define yynerrs dcenerrs + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 11 "dce.y" + +#include "config.h" +#include +#include "netcdf.h" +#include "ncbytes.h" +#include "nclist.h" +#include "dceconstraints.h" +#include "dceparselex.h" + + +/* Line 189 of yacc.c */ +#line 93 "dce.tab.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + SCAN_WORD = 258, + SCAN_STRINGCONST = 259, + SCAN_NUMBERCONST = 260 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 140 "dce.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 4 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 83 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 22 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 29 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 59 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 87 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 260 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 20, 2, 2, 2, 2, 14, 2, + 8, 9, 2, 2, 7, 2, 10, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 13, 2, + 19, 17, 18, 6, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 11, 2, 12, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 15, 2, 16, 21, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 6, 9, 13, 14, 16, 17, 19, + 21, 23, 27, 29, 31, 35, 40, 42, 46, 48, + 51, 53, 56, 60, 66, 74, 78, 80, 83, 90, + 95, 98, 100, 104, 106, 108, 110, 112, 114, 116, + 118, 122, 124, 127, 129, 132, 136, 141, 143, 147, + 149, 151, 153, 156, 159, 162, 165, 167, 169, 171 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 23, 0, -1, 24, 25, -1, 24, 26, -1, 24, + 25, 26, -1, -1, 6, -1, -1, 27, -1, 35, + -1, 28, -1, 27, 7, 28, -1, 30, -1, 29, + -1, 47, 8, 9, -1, 47, 8, 45, 9, -1, + 31, -1, 30, 10, 31, -1, 48, -1, 48, 32, + -1, 33, -1, 32, 33, -1, 11, 49, 12, -1, + 11, 49, 13, 49, 12, -1, 11, 49, 13, 49, + 13, 49, 12, -1, 11, 49, 12, -1, 36, -1, + 35, 36, -1, 14, 38, 46, 15, 37, 16, -1, + 14, 38, 46, 38, -1, 14, 44, -1, 38, -1, + 37, 7, 38, -1, 40, -1, 29, -1, 39, -1, + 49, -1, 50, -1, 41, -1, 42, -1, 41, 10, + 42, -1, 48, -1, 48, 43, -1, 34, -1, 43, + 34, -1, 47, 8, 9, -1, 47, 8, 45, 9, + -1, 38, -1, 37, 7, 38, -1, 17, -1, 18, + -1, 19, -1, 20, 17, -1, 18, 17, -1, 19, + 17, -1, 17, 21, -1, 48, -1, 3, -1, 5, + -1, 4, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 34, 34, 35, 36, 37, 40, 40, 43, 47, + 51, 53, 58, 60, 65, 67, 72, 74, 79, 81, + 86, 88, 93, 95, 97, 101, 107, 109, 114, 116, + 118, 123, 125, 130, 132, 134, 139, 141, 146, 151, + 153, 158, 160, 165, 167, 172, 174, 179, 181, 186, + 187, 188, 189, 190, 191, 192, 195, 199, 203, 207 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "SCAN_WORD", "SCAN_STRINGCONST", + "SCAN_NUMBERCONST", "'?'", "','", "'('", "')'", "'.'", "'['", "']'", + "':'", "'&'", "'{'", "'}'", "'='", "'>'", "'<'", "'!'", "'~'", "$accept", + "constraints", "optquestionmark", "projections", "selections", + "projectionlist", "projection", "function", "segmentlist", "segment", + "rangelist", "range", "range1", "clauselist", "sel_clause", "value_list", + "value", "constant", "var", "indexpath", "index", "array_indices", + "boolfunction", "arg_list", "rel_op", "ident", "word", "number", + "string", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 63, 44, 40, 41, + 46, 91, 93, 58, 38, 123, 125, 61, 62, 60, + 33, 126 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 22, 23, 23, 23, 23, 24, 24, 25, 26, + 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, + 32, 32, 33, 33, 33, 34, 35, 35, 36, 36, + 36, 37, 37, 38, 38, 38, 39, 39, 40, 41, + 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, + 46, 46, 46, 46, 46, 46, 47, 48, 49, 50 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 2, 2, 3, 0, 1, 0, 1, 1, + 1, 3, 1, 1, 3, 4, 1, 3, 1, 2, + 1, 2, 3, 5, 7, 3, 1, 2, 6, 4, + 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, + 3, 1, 2, 1, 2, 3, 4, 1, 3, 1, + 1, 1, 2, 2, 2, 2, 1, 1, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 7, 6, 0, 0, 1, 57, 0, 2, 3, 8, + 10, 13, 12, 16, 9, 26, 0, 18, 59, 58, + 34, 0, 35, 33, 38, 39, 30, 0, 41, 36, + 37, 4, 0, 0, 27, 0, 0, 19, 20, 49, + 50, 51, 0, 0, 0, 0, 0, 43, 42, 11, + 17, 18, 14, 0, 31, 0, 0, 21, 55, 53, + 54, 52, 0, 29, 40, 41, 14, 0, 0, 44, + 0, 15, 22, 0, 0, 31, 15, 25, 32, 0, + 0, 28, 23, 0, 32, 0, 24 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 2, 3, 7, 8, 9, 10, 20, 12, 13, + 37, 38, 47, 14, 15, 53, 54, 22, 23, 24, + 25, 48, 26, 55, 43, 16, 28, 29, 30 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -36 +static const yytype_int8 yypact[] = +{ + 10, -36, 8, 4, -36, -36, 46, 12, -36, 23, + -36, -36, 44, -36, 12, -36, 7, -2, -36, -36, + -36, 27, -36, -36, 45, -36, -36, 49, 17, -36, + -36, -36, 36, 36, -36, 18, 53, 48, -36, 39, + 50, 51, 52, 9, 36, 31, 53, -36, 54, -36, + -36, 48, -36, 55, 57, 61, 29, -36, -36, -36, + -36, -36, 46, -36, -36, 54, 3, 62, 60, -36, + 46, -36, -36, 53, 13, -36, 5, -36, 64, 40, + 46, -36, -36, 53, -36, 63, -36 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -36, -36, -36, -36, 56, -36, 47, 1, -36, 28, + -36, 41, 32, -36, 67, 14, -6, -36, -36, -36, + 33, -36, -36, 37, -36, 77, -1, -35, -36 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -57 +static const yytype_int8 yytable[] = +{ + 21, 56, 17, -45, 11, -46, -56, 5, 4, 36, + -5, 68, 5, 18, 19, 35, 1, -45, 6, -46, + 80, 5, 18, 19, 62, -56, 6, 52, 46, 81, + 32, 17, 51, 11, 5, 18, 19, 63, 79, 5, + 66, 72, 73, 65, 39, 40, 41, 42, 85, 5, + 18, 19, 82, 83, 33, 44, 75, 45, 19, 36, + 58, 50, 70, 31, 78, 46, -47, 59, 60, 61, + 71, 76, 77, -48, 84, 86, 74, 64, 57, 49, + 69, 34, 67, 27 +}; + +static const yytype_uint8 yycheck[] = +{ + 6, 36, 3, 0, 3, 0, 8, 3, 0, 11, + 0, 46, 3, 4, 5, 8, 6, 14, 14, 14, + 7, 3, 4, 5, 15, 8, 14, 9, 11, 16, + 7, 32, 33, 32, 3, 4, 5, 43, 73, 3, + 9, 12, 13, 44, 17, 18, 19, 20, 83, 3, + 4, 5, 12, 13, 10, 10, 62, 8, 5, 11, + 21, 33, 7, 7, 70, 11, 9, 17, 17, 17, + 9, 9, 12, 9, 80, 12, 62, 44, 37, 32, + 48, 14, 45, 6 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 6, 23, 24, 0, 3, 14, 25, 26, 27, + 28, 29, 30, 31, 35, 36, 47, 48, 4, 5, + 29, 38, 39, 40, 41, 42, 44, 47, 48, 49, + 50, 26, 7, 10, 36, 8, 11, 32, 33, 17, + 18, 19, 20, 46, 10, 8, 11, 34, 43, 28, + 31, 48, 9, 37, 38, 45, 49, 33, 21, 17, + 17, 17, 15, 38, 42, 48, 9, 45, 49, 34, + 7, 9, 12, 13, 37, 38, 9, 12, 38, 49, + 7, 16, 12, 13, 38, 49, 12 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (parsestate, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, parsestate) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, parsestate); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, DCEparsestate* parsestate) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, parsestate) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + DCEparsestate* parsestate; +#endif +{ + if (!yyvaluep) + return; + YYUSE (parsestate); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, DCEparsestate* parsestate) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, parsestate) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + DCEparsestate* parsestate; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, parsestate); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, DCEparsestate* parsestate) +#else +static void +yy_reduce_print (yyvsp, yyrule, parsestate) + YYSTYPE *yyvsp; + int yyrule; + DCEparsestate* parsestate; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , parsestate); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule, parsestate); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, DCEparsestate* parsestate) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, parsestate) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + DCEparsestate* parsestate; +#endif +{ + YYUSE (yyvaluep); + YYUSE (parsestate); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (DCEparsestate* parsestate); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (DCEparsestate* parsestate) +#else +int +yyparse (parsestate) + DCEparsestate* parsestate; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 8: + +/* Line 1464 of yacc.c */ +#line 43 "dce.y" + {projections(parsestate,(yyvsp[(1) - (1)]));;} + break; + + case 9: + +/* Line 1464 of yacc.c */ +#line 47 "dce.y" + {selections(parsestate,(yyvsp[(1) - (1)]));;} + break; + + case 10: + +/* Line 1464 of yacc.c */ +#line 52 "dce.y" + {(yyval)=projectionlist(parsestate,(Object)null,(yyvsp[(1) - (1)]));;} + break; + + case 11: + +/* Line 1464 of yacc.c */ +#line 54 "dce.y" + {(yyval)=projectionlist(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]));;} + break; + + case 12: + +/* Line 1464 of yacc.c */ +#line 59 "dce.y" + {(yyval)=projection(parsestate,(yyvsp[(1) - (1)]));;} + break; + + case 13: + +/* Line 1464 of yacc.c */ +#line 61 "dce.y" + {(yyval)=(yyvsp[(1) - (1)]);;} + break; + + case 14: + +/* Line 1464 of yacc.c */ +#line 66 "dce.y" + {(yyval)=function(parsestate,(yyvsp[(1) - (3)]),null);;} + break; + + case 15: + +/* Line 1464 of yacc.c */ +#line 68 "dce.y" + {(yyval)=function(parsestate,(yyvsp[(1) - (4)]),(yyvsp[(3) - (4)]));;} + break; + + case 16: + +/* Line 1464 of yacc.c */ +#line 73 "dce.y" + {(yyval)=segmentlist(parsestate,null,(yyvsp[(1) - (1)]));;} + break; + + case 17: + +/* Line 1464 of yacc.c */ +#line 75 "dce.y" + {(yyval)=segmentlist(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]));;} + break; + + case 18: + +/* Line 1464 of yacc.c */ +#line 80 "dce.y" + {(yyval)=segment(parsestate,(yyvsp[(1) - (1)]),null);;} + break; + + case 19: + +/* Line 1464 of yacc.c */ +#line 82 "dce.y" + {(yyval)=segment(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));;} + break; + + case 20: + +/* Line 1464 of yacc.c */ +#line 87 "dce.y" + {(yyval)=rangelist(parsestate,null,(yyvsp[(1) - (1)]));;} + break; + + case 21: + +/* Line 1464 of yacc.c */ +#line 89 "dce.y" + {(yyval)=rangelist(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));;} + break; + + case 22: + +/* Line 1464 of yacc.c */ +#line 94 "dce.y" + {(yyval)=range(parsestate,(yyvsp[(2) - (3)]),null,null);;} + break; + + case 23: + +/* Line 1464 of yacc.c */ +#line 96 "dce.y" + {(yyval)=range(parsestate,(yyvsp[(2) - (5)]),null,(yyvsp[(4) - (5)]));;} + break; + + case 24: + +/* Line 1464 of yacc.c */ +#line 98 "dce.y" + {(yyval)=range(parsestate,(yyvsp[(2) - (7)]),(yyvsp[(4) - (7)]),(yyvsp[(6) - (7)]));;} + break; + + case 25: + +/* Line 1464 of yacc.c */ +#line 102 "dce.y" + {(yyval) = range1(parsestate,(yyvsp[(2) - (3)]));;} + break; + + case 26: + +/* Line 1464 of yacc.c */ +#line 108 "dce.y" + {(yyval)=clauselist(parsestate,null,(yyvsp[(1) - (1)]));;} + break; + + case 27: + +/* Line 1464 of yacc.c */ +#line 110 "dce.y" + {(yyval)=clauselist(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));;} + break; + + case 28: + +/* Line 1464 of yacc.c */ +#line 115 "dce.y" + {(yyval)=sel_clause(parsestate,1,(yyvsp[(2) - (6)]),(yyvsp[(3) - (6)]),(yyvsp[(5) - (6)]));;} + break; + + case 29: + +/* Line 1464 of yacc.c */ +#line 117 "dce.y" + {(yyval)=sel_clause(parsestate,2,(yyvsp[(2) - (4)]),(yyvsp[(3) - (4)]),(yyvsp[(4) - (4)]));;} + break; + + case 30: + +/* Line 1464 of yacc.c */ +#line 119 "dce.y" + {(yyval)=(yyvsp[(1) - (2)]);;} + break; + + case 31: + +/* Line 1464 of yacc.c */ +#line 124 "dce.y" + {(yyval)=value_list(parsestate,null,(yyvsp[(1) - (1)]));;} + break; + + case 32: + +/* Line 1464 of yacc.c */ +#line 126 "dce.y" + {(yyval)=value_list(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]));;} + break; + + case 33: + +/* Line 1464 of yacc.c */ +#line 131 "dce.y" + {(yyval)=value(parsestate,(yyvsp[(1) - (1)]));;} + break; + + case 34: + +/* Line 1464 of yacc.c */ +#line 133 "dce.y" + {(yyval)=value(parsestate,(yyvsp[(1) - (1)]));;} + break; + + case 35: + +/* Line 1464 of yacc.c */ +#line 135 "dce.y" + {(yyval)=value(parsestate,(yyvsp[(1) - (1)]));;} + break; + + case 36: + +/* Line 1464 of yacc.c */ +#line 140 "dce.y" + {(yyval)=constant(parsestate,(yyvsp[(1) - (1)]),SCAN_NUMBERCONST);;} + break; + + case 37: + +/* Line 1464 of yacc.c */ +#line 142 "dce.y" + {(yyval)=constant(parsestate,(yyvsp[(1) - (1)]),SCAN_STRINGCONST);;} + break; + + case 38: + +/* Line 1464 of yacc.c */ +#line 147 "dce.y" + {(yyval)=var(parsestate,(yyvsp[(1) - (1)]));;} + break; + + case 39: + +/* Line 1464 of yacc.c */ +#line 152 "dce.y" + {(yyval)=indexpath(parsestate,null,(yyvsp[(1) - (1)]));;} + break; + + case 40: + +/* Line 1464 of yacc.c */ +#line 154 "dce.y" + {(yyval)=indexpath(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]));;} + break; + + case 41: + +/* Line 1464 of yacc.c */ +#line 159 "dce.y" + {(yyval)=indexer(parsestate,(yyvsp[(1) - (1)]),null);;} + break; + + case 42: + +/* Line 1464 of yacc.c */ +#line 161 "dce.y" + {(yyval)=indexer(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));;} + break; + + case 43: + +/* Line 1464 of yacc.c */ +#line 166 "dce.y" + {(yyval)=array_indices(parsestate,null,(yyvsp[(1) - (1)]));;} + break; + + case 44: + +/* Line 1464 of yacc.c */ +#line 168 "dce.y" + {(yyval)=array_indices(parsestate,(yyvsp[(1) - (2)]),(yyvsp[(2) - (2)]));;} + break; + + case 45: + +/* Line 1464 of yacc.c */ +#line 173 "dce.y" + {(yyval)=function(parsestate,(yyvsp[(1) - (3)]),null);;} + break; + + case 46: + +/* Line 1464 of yacc.c */ +#line 175 "dce.y" + {(yyval)=function(parsestate,(yyvsp[(1) - (4)]),(yyvsp[(3) - (4)]));;} + break; + + case 47: + +/* Line 1464 of yacc.c */ +#line 180 "dce.y" + {(yyval)=arg_list(parsestate,null,(yyvsp[(1) - (1)]));;} + break; + + case 48: + +/* Line 1464 of yacc.c */ +#line 182 "dce.y" + {(yyval)=arg_list(parsestate,(yyvsp[(1) - (3)]),(yyvsp[(3) - (3)]));;} + break; + + case 49: + +/* Line 1464 of yacc.c */ +#line 186 "dce.y" + {(yyval)=makeselectiontag(CEO_EQ);;} + break; + + case 50: + +/* Line 1464 of yacc.c */ +#line 187 "dce.y" + {(yyval)=makeselectiontag(CEO_GT);;} + break; + + case 51: + +/* Line 1464 of yacc.c */ +#line 188 "dce.y" + {(yyval)=makeselectiontag(CEO_LT);;} + break; + + case 52: + +/* Line 1464 of yacc.c */ +#line 189 "dce.y" + {(yyval)=makeselectiontag(CEO_NEQ);;} + break; + + case 53: + +/* Line 1464 of yacc.c */ +#line 190 "dce.y" + {(yyval)=makeselectiontag(CEO_GE);;} + break; + + case 54: + +/* Line 1464 of yacc.c */ +#line 191 "dce.y" + {(yyval)=makeselectiontag(CEO_LE);;} + break; + + case 55: + +/* Line 1464 of yacc.c */ +#line 192 "dce.y" + {(yyval)=makeselectiontag(CEO_RE);;} + break; + + case 56: + +/* Line 1464 of yacc.c */ +#line 196 "dce.y" + {(yyval) = (yyvsp[(1) - (1)]);;} + break; + + case 57: + +/* Line 1464 of yacc.c */ +#line 200 "dce.y" + {(yyval) = checkobject((yyvsp[(1) - (1)]));;} + break; + + case 58: + +/* Line 1464 of yacc.c */ +#line 204 "dce.y" + {(yyval) = checkobject((yyvsp[(1) - (1)]));;} + break; + + case 59: + +/* Line 1464 of yacc.c */ +#line 208 "dce.y" + {(yyval) = checkobject((yyvsp[(1) - (1)]));;} + break; + + + +/* Line 1464 of yacc.c */ +#line 1786 "dce.tab.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (parsestate, YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (parsestate, yymsg); + } + else + { + yyerror (parsestate, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, parsestate); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, parsestate); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (parsestate, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, parsestate); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, parsestate); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1684 of yacc.c */ +#line 211 "dce.y" + + diff --git a/extern/src_netcdf4/dcetab.h b/extern/src_netcdf4/dcetab.h new file mode 100644 index 0000000000000000000000000000000000000000..b7336bdc3253a7e5ba5bcd196787f350a670b26e --- /dev/null +++ b/extern/src_netcdf4/dcetab.h @@ -0,0 +1,58 @@ +/* A Bison parser, made by GNU Bison 2.4.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + SCAN_WORD = 258, + SCAN_STRINGCONST = 259, + SCAN_NUMBERCONST = 260 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + + diff --git a/extern/src_netcdf4/dcompound.c b/extern/src_netcdf4/dcompound.c new file mode 100644 index 0000000000000000000000000000000000000000..83385cd14bac06e5a5bfe2e8e08eead79f222991 --- /dev/null +++ b/extern/src_netcdf4/dcompound.c @@ -0,0 +1,489 @@ +/*! \file + Functions for Compound Types + + Copyright 2011 University Corporation for Atmospheric + Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \name Compound Types + Functions to create and learn about compound types. */ +/*! \{ */ /* All these functions are part of this named group... */ + + +/** \ingroup user_types + +Create a compound type. Provide an ncid, a name, and a total size (in +bytes) of one element of the completed compound type. + +After calling this function, fill out the type with repeated calls to +nc_insert_compound(). Call nc_insert_compound() once for each field +you wish to insert into the compound type. + +\param ncid \ref ncid +\param size The size, in bytes, of the compound type. +\param name \ref object_name of the created type. +\param typeidp The type ID of the new type is copied here. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENAMEINUSE That name is in use. +\returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME. +\returns ::NC_EBADNAME Name contains illegal characters. +\returns ::NC_ESTRICTNC3 Attempting a netCDF-4 operation on a netCDF-3 file. +\returns ::NC_ENOTNC4 This file was created with the strict netcdf-3 flag, therefore netcdf-4 operations are not allowed. (see nc_open). +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +\returns ::NC_EPERM Attempt to write to a read-only file. +\returns ::NC_ENOTINDEFINE Not in define mode. + +\section Example + +\code +struct s1 +{ +int i1; +int i2; +}; +struct s1 data[DIM_LEN], data_in[DIM_LEN]; + +if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR; +if (nc_def_compound(ncid, sizeof(struct s1), SVC_REC, &typeid)) ERR; +if (nc_insert_compound(ncid, typeid, BATTLES_WITH_KLINGONS, +HOFFSET(struct s1, i1), NC_INT)) ERR; +if (nc_insert_compound(ncid, typeid, DATES_WITH_ALIENS, +HOFFSET(struct s1, i2), NC_INT)) ERR; +if (nc_def_dim(ncid, STARDATE, DIM_LEN, &dimid)) ERR; +if (nc_def_var(ncid, SERVICE_RECORD, typeid, 1, dimids, &varid)) ERR; +if (nc_put_var(ncid, varid, data)) ERR; +if (nc_close(ncid)) ERR; +\endcode +*/ +int +nc_def_compound(int ncid, size_t size, const char *name, + nc_type *typeidp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_compound(ncid,size,name,typeidp); +} + +/** \ingroup user_types +Insert a named field into a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param name The \ref object_name of the new field. + +\param offset Offset in byte from the beginning of the compound type +for this field. + +\param field_typeid The type of the field to be inserted. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENAMEINUSE That name is in use. +\returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME. +\returns ::NC_EBADNAME Name contains illegal characters. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +\returns ::NC_EPERM Attempt to write to a read-only file. +\returns ::NC_ENOTINDEFINE Not in define mode. +*/ +int +nc_insert_compound(int ncid, nc_type xtype, const char *name, + size_t offset, nc_type field_typeid) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->insert_compound(ncid, xtype, name, + offset, field_typeid); +} + +/** \ingroup user_types +Insert a named array field into a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param name The \ref object_name of the new field. + +\param offset Offset in byte from the beginning of the compound type +for this field. + +\param field_typeid The type of the field to be inserted. + + \param ndims Number of dimensions in array. + + \param dim_sizes Array of dimension sizes. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENAMEINUSE That name is in use. +\returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME. +\returns ::NC_EBADNAME Name contains illegal characters. +\returns ::NC_ESTRICTNC3 Attempting a netCDF-4 operation on a netCDF-3 file. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +\returns ::NC_EPERM Attempt to write to a read-only file. +\returns ::NC_ENOTINDEFINE Not in define mode. +*/ +int +nc_insert_array_compound(int ncid, nc_type xtype, const char *name, + size_t offset, nc_type field_typeid, + int ndims, const int *dim_sizes) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->insert_array_compound(ncid,xtype,name,offset,field_typeid,ndims,dim_sizes); +} + +/** \ingroup user_types +Learn about a compound type. Get the number of fields, len, and +name of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param name Returned \ref object_name of compound type. \ref +ignored_if_null. + +\param sizep Returned size of compound type in bytes. \ref ignored_if_null. + +\param nfieldsp The number of fields in the compound type will be +placed here. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound(int ncid, nc_type xtype, char *name, + size_t *sizep, size_t *nfieldsp) +{ + int class = 0; + int stat = nc_inq_user_type(ncid,xtype,name,sizep,NULL,nfieldsp,&class); + if(stat != NC_NOERR) return stat; + if(class != NC_COMPOUND) stat = NC_EBADTYPE; + return stat; +} + +/** \ingroup user_types +Learn the name of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param name Returned \ref object_name of compound type. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_name(int ncid, nc_type xtype, char *name) +{ + return nc_inq_compound(ncid,xtype,name,NULL,NULL); +} + +/** \ingroup user_types +Learn the size of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param sizep Returned size of compound type in bytes. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_size(int ncid, nc_type xtype, size_t *sizep) +{ + return nc_inq_compound(ncid,xtype,NULL,sizep,NULL); +} + +/** \ingroup user_types +Learn the number of fields in a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param nfieldsp The number of fields in the compound type will be +placed here. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_nfields(int ncid, nc_type xtype, size_t *nfieldsp) +{ + return nc_inq_compound(ncid,xtype,NULL,NULL,nfieldsp); +} + +/** \ingroup user_types +Get information about one of the fields of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param fieldid A zero-based index number specifying a field in the +compound type. + +\param name Returned \ref object_name of the field. \ref +ignored_if_null. + +\param offsetp A pointer which will get the offset of the field. \ref +ignored_if_null. + +\param field_typeidp A pointer which will get the typeid of the +field. \ref ignored_if_null. + +\param ndimsp A pointer which will get the number of dimensions of the +field. \ref ignored_if_null. + +\param dim_sizesp A pointer which will get the dimension sizes of the +field. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_field(int ncid, nc_type xtype, int fieldid, + char *name, size_t *offsetp, + nc_type *field_typeidp, int *ndimsp, + int *dim_sizesp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_compound_field(ncid, xtype, fieldid, + name, offsetp, field_typeidp, + ndimsp, dim_sizesp); +} + +/** \ingroup user_types +Get information about one of the fields of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param fieldid A zero-based index number specifying a field in the +compound type. + +\param name Returned \ref object_name of the field. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_fieldname(int ncid, nc_type xtype, int fieldid, + char *name) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_compound_field(ncid, xtype, fieldid, + name, NULL, NULL, NULL, + NULL); +} + +/** \ingroup user_types +Get information about one of the fields of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param fieldid A zero-based index number specifying a field in the +compound type. + +\param offsetp A pointer which will get the offset of the field. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_fieldoffset(int ncid, nc_type xtype, int fieldid, + size_t *offsetp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_compound_field(ncid,xtype,fieldid,NULL,offsetp,NULL,NULL,NULL); +} + +/** \ingroup user_types +Get information about one of the fields of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param fieldid A zero-based index number specifying a field in the +compound type. + +\param field_typeidp A pointer which will get the typeid of the +field. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_fieldtype(int ncid, nc_type xtype, int fieldid, + nc_type *field_typeidp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_compound_field(ncid,xtype,fieldid,NULL,NULL,field_typeidp,NULL,NULL); +} + +/** \ingroup user_types +Get information about one of the fields of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param fieldid A zero-based index number specifying a field in the +compound type. + +\param ndimsp A pointer which will get the number of dimensions of the +field. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_fieldndims(int ncid, nc_type xtype, int fieldid, + int *ndimsp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_compound_field(ncid,xtype,fieldid,NULL,NULL,NULL,ndimsp,NULL); +} + +/** \ingroup user_types +Get information about one of the fields of a compound type. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param fieldid A zero-based index number specifying a field in the +compound type. + +\param dim_sizesp A pointer which will get the dimension sizes of the +field. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_fielddim_sizes(int ncid, nc_type xtype, int fieldid, + int *dim_sizesp) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_compound_field(ncid, xtype, fieldid, + NULL, NULL, NULL, NULL, + dim_sizesp); +} + +/** \ingroup user_types +Learn the Index of a Named Field in a Compound Type. Get the index + * of a field in a compound type from the name. + +\param ncid \ref ncid + +\param xtype The typeid for this compound type, as returned by +nc_def_compound(), or nc_inq_var(). + +\param name \ref object_name of the field. \ref ignored_if_null. + +\param fieldidp A pointer which will get the index of the named +field. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_compound_fieldindex(int ncid, nc_type xtype, const char *name, + int *fieldidp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_compound_fieldindex(ncid,xtype,name,fieldidp); +} +/*! \} */ /* End of named group ...*/ + + + + + + diff --git a/extern/src_netcdf4/dcopy.c b/extern/src_netcdf4/dcopy.c new file mode 100644 index 0000000000000000000000000000000000000000..5ca57805d6f58e1be1823870b56da7de217ee4f6 --- /dev/null +++ b/extern/src_netcdf4/dcopy.c @@ -0,0 +1,619 @@ +/* Copyright 2010 University Corporation for Atmospheric + Research/Unidata. See COPYRIGHT file for more info. + + This file has the var and att copy functions. + + "$Id: copy.c,v 1.1 2010/06/01 15:46:49 ed Exp $" +*/ + +#include "ncdispatch.h" +#include + +#ifdef USE_NETCDF4 +/* Compare two netcdf types for equality. Must have the ncids as well, + to find user-defined types. */ +static int +NC_compare_nc_types(int ncid1, int typeid1, int ncid2, int typeid2, + int *equalp) +{ + int ret = NC_NOERR; + + /* If you don't care about the answer, neither do I! */ + if(equalp == NULL) + return NC_NOERR; + + /* Assume the types are not equal. If we find any inequality, then + exit with NC_NOERR and we're done. */ + *equalp = 0; + + /* Atomic types are so easy! */ + if (typeid1 <= NC_MAX_ATOMIC_TYPE) + { + if (typeid2 != typeid1) + return NC_NOERR; + *equalp = 1; + } + else + { + int i, ret, equal1; + char name1[NC_MAX_NAME]; + char name2[NC_MAX_NAME]; + size_t size1, size2; + nc_type base1, base2; + size_t nelems1, nelems2; + int class1, class2; + void* value1 = NULL; + void* value2 = NULL; + size_t offset1, offset2; + nc_type ftype1, ftype2; + int ndims1, ndims2; + int dimsizes1[NC_MAX_VAR_DIMS]; + int dimsizes2[NC_MAX_VAR_DIMS]; + + /* Find out about the two types. */ + if ((ret = nc_inq_user_type(ncid1, typeid1, name1, &size1, + &base1, &nelems1, &class1))) + return ret; + if ((ret = nc_inq_user_type(ncid2, typeid2, name2, &size2, + &base2, &nelems2, &class2))) + return ret; + + /* Check the obvious. */ + if(size1 != size2 || class1 != class2 || strcmp(name1,name2)) + return NC_NOERR; + + /* Check user-defined types in detail. */ + switch(class1) + { + case NC_VLEN: + if((ret = NC_compare_nc_types(ncid1, base1, ncid2, + base1, &equal1))) + return ret; + if(!equal1) + return NC_NOERR; + break; + case NC_OPAQUE: + /* Already checked size above. */ + break; + case NC_ENUM: + if(base1 != base2 || nelems1 != nelems2) return NC_NOERR; + + if (!(value1 = malloc(size1))) + return NC_ENOMEM; + if (!(value2 = malloc(size2))) + return NC_ENOMEM; + + for(i = 0; i < nelems1; i++) + { + if ((ret = nc_inq_enum_member(ncid1, typeid1, i, name1, + value1)) || + (ret = nc_inq_enum_member(ncid2, typeid2, i, name2, + value2)) || + strcmp(name1, name2) || memcmp(value1, value2, size1)) + { + free(value1); + free(value2); + return ret; + } + } + free(value1); + free(value2); + break; + case NC_COMPOUND: + if(nelems1 != nelems2) + return NC_NOERR; + + /* Compare each field. Each must be equal! */ + for(i = 0; i < nelems1; i++) + { + int j; + if ((ret = nc_inq_compound_field(ncid1, typeid1, i, name1, &offset1, + &ftype1, &ndims1, dimsizes1))) + return ret; + if ((ret = nc_inq_compound_field(ncid2, typeid2, i, name2, &offset2, + &ftype2, &ndims2, dimsizes2))) + return ret; + if(ndims1 != ndims2) + return NC_NOERR; + for(j = 0; j < ndims1;j++) + if(dimsizes1[j] != dimsizes2[j]) + return NC_NOERR; + + /* Compare user-defined field types. */ + if((ret = NC_compare_nc_types(ncid1, ftype1, ncid2, ftype2, + &equal1))) + return ret; + if(!equal1) + return NC_NOERR; + } + break; + default: + return NC_EINVAL; + } + *equalp = 1; + } + return ret; +} + +/* Recursively hunt for a netCDF type id. (Code from nc4internal.c); + Return matching typeid or 0 if not found. */ +static int +NC_rec_find_nc_type(int ncid1, nc_type tid1, int ncid2, nc_type* tid2) +{ + int i,ret = NC_NOERR; + int nids; + int* ids = NULL; + + /* Get all types in grp ncid2 */ + if(tid2) + *tid2 = 0; + if ((ret = nc_inq_typeids(ncid2, &nids, NULL))) + return ret; + if (nids) + { + if (!(ids = (int *)malloc(nids * sizeof(int)))) + return NC_ENOMEM; + if ((ret = nc_inq_typeids(ncid2, &nids, ids))) + return ret; + for(i = 0; i < nids; i++) + { + int equal = 0; + if ((ret = NC_compare_nc_types(ncid1, tid1, ncid2, ids[i], &equal))) + return ret; + if(equal) + { + if(tid2) + *tid2 = ids[i]; + free(ids); + return NC_NOERR; + } + } + free(ids); + } + + /* recurse */ + if ((ret = nc_inq_grps(ncid1, &nids, NULL))) + return ret; + if (nids) + { + if (!(ids = (int *)malloc(nids * sizeof(int)))) + return NC_ENOMEM; + if ((ret = nc_inq_grps(ncid1, &nids, ids))) + { + free(ids); + return ret; + } + for (i = 0; i < nids; i++) + { + ret = NC_rec_find_nc_type(ncid1, tid1, ids[i], tid2); + if (ret && ret != NC_EBADTYPE) + break; + if (tid2 && *tid2 != 0) /* found */ + { + free(ids); + return NC_NOERR; + } + } + free(ids); + } + return NC_EBADTYPE; /* not found */ +} + +/* Given a type in one file, find its equal (if any) in another + * file. It sounds so simple, but it's a real pain! */ +static int +NC_find_equal_type(int ncid1, nc_type xtype1, int ncid2, nc_type *xtype2) +{ + int ret = NC_NOERR; + + /* Check input */ + if(xtype1 <= NC_NAT) + return NC_EINVAL; + + /* Handle atomic types. */ + if (xtype1 <= NC_MAX_ATOMIC_TYPE) + { + if(xtype2) + *xtype2 = xtype1; + return NC_NOERR; + } + + /* Recursively search group ncid2 and its children + to find a type that is equal (using compare_type) + to xtype1. */ + ret = NC_rec_find_nc_type(ncid1, xtype1 , ncid2, xtype2); + return ret; +} + +#endif /* USE_NETCDF4 */ + +/* This will copy a variable from one file to another, assuming + dimensions in output file are already defined and have same + dimension ids. + + This function must work even if the files are different formats, + (i.e. one old netcdf, the other hdf5-netcdf.) + + But if you're copying into a netcdf-3 file, from a netcdf-4 file, + you must be copying a var of one of the six netcdf-3 + types. Similarly for the attributes. */ +int +nc_copy_var(int ncid_in, int varid_in, int ncid_out) +{ + char name[NC_MAX_NAME + 1]; + char att_name[NC_MAX_NAME + 1]; + nc_type xtype; + int ndims, dimids[NC_MAX_VAR_DIMS], natts, real_ndims; + int varid_out; + int a, d; + void *data = NULL; + size_t *count = NULL, *start = NULL; + size_t reclen = 1; + size_t *dimlen = NULL; + int retval = NC_NOERR; + size_t type_size; + int src_format, dest_format; + char type_name[NC_MAX_NAME+1]; + + /* Learn about this var. */ + if ((retval = nc_inq_var(ncid_in, varid_in, name, &xtype, + &ndims, dimids, &natts))) + return retval; + +#ifdef USE_NETCDF4 + LOG((2, "nc_copy_var: ncid_in 0x%x varid_in %d ncid_out 0x%x", + ncid_in, varid_in, ncid_out)); +#endif + + /* Make sure we are not trying to write into a netcdf-3 file + * anything that won't fit in netcdf-3. */ + if ((retval = nc_inq_format(ncid_in, &src_format))) + return retval; + if ((retval = nc_inq_format(ncid_out, &dest_format))) + return retval; + if ((dest_format == NC_FORMAT_CLASSIC || dest_format == NC_FORMAT_64BIT) && + src_format == NC_FORMAT_NETCDF4 && xtype > NC_DOUBLE) + return NC_ENOTNC4; + + /* Later on, we will need to know the size of this type. */ + if ((retval = nc_inq_type(ncid_in, xtype, type_name, &type_size))) + return retval; +#ifdef USE_NETCDF4 + LOG((3, "type %s has size %d", type_name, type_size)); +#endif + + /* Switch back to define mode, and create the output var. */ + retval = nc_redef(ncid_out); + if (retval && retval != NC_EINDEFINE) + BAIL(retval); + if ((retval = nc_def_var(ncid_out, name, xtype, + ndims, dimids, &varid_out))) + BAIL(retval); + + /* Copy the attributes. */ + for (a=0; a + ... + int status, ncid, latid, recid; + ... + status = nc_create("foo.nc", NC_NOCLOBBER, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_def_dim(ncid, "lat", 18L, &latid); + if (status != NC_NOERR) handle_error(status); + status = nc_def_dim(ncid, "rec", NC_UNLIMITED, &recid); + if (status != NC_NOERR) handle_error(status); +\endcode + + */ +int +nc_def_dim(int ncid, const char *name, size_t len, int *idp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_dim(ncid, name, len, idp); +} + +/*! +Find the ID of a dimension from the name. + +The function nc_inq_dimid returns (as an argument) the ID of a netCDF +dimension, given the name of the dimension. If ndims is the number of +dimensions defined for a netCDF dataset, each dimension has an ID +between 0 and ndims-1. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param name Name of the dimension. + +\param idp Pointer where dimension ID will be stored. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Not a valid ID. +\returns ::NC_EBADDIM Invalid dimension ID or name. + */ +int +nc_inq_dimid(int ncid, const char *name, int *idp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_dimid(ncid,name,idp); +} + +/*! +Find the name and length of a dimension. + +The length for the unlimited dimension, if any, is the number of +records written so far. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param dimid Dimension ID, from a previous call to nc_inq_dimid() or +nc_def_dim(). + +\param name Returned dimension name. The caller must allocate space +for the returned name. The maximum possible length, in characters, of +a dimension name is given by the predefined constant +NC_MAX_NAME. (This doesn't include the null terminator, so declare +your array to be size NC_MAX_NAME+1). The returned character array +will be null-terminated. + +\param lenp Pointer to location for returned length of dimension. For +the unlimited dimension, this is the number of records written so far. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Not a valid ID. +\returns ::NC_EBADDIM Invalid dimension ID or name. + +\section Example + +Here is an example using nc_inq_dim() to determine the length of a +dimension named lat, and the name and current maximum length of the +unlimited dimension for an existing netCDF dataset named foo.nc: + +\code + #include + ... + int status, ncid, latid, recid; + size_t latlength, recs; + char recname[NC_MAX_NAME+1]; + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_unlimdim(ncid, &recid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_dimid(ncid, "lat", &latid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_dimlen(ncid, latid, &latlength); + if (status != NC_NOERR) handle_error(status); + + status = nc_inq_dim(ncid, recid, recname, &recs); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_inq_dim(int ncid, int dimid, char *name, size_t *lenp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_dim(ncid,dimid,name,lenp); +} + +/*! +Rename a dimension. + +This function renames an existing dimension in a netCDF dataset open +for writing. You cannot rename a dimension to have the same name as +another dimension. + +For netCDF classic and 64-bit offset files, if the new name is longer +than the old name, the netCDF dataset must be in define mode. + +For netCDF-4 files the dataset is switched to define more for the +rename, regardless of the name length. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param dimid Dimension ID, from a previous call to nc_inq_dimid() or +nc_def_dim(). + +\param name New name for dimension. Must be a null-terminated string +with length less than NC_MAX_NAME. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Not a valid ID. +\returns ::NC_EBADDIM Invalid dimension ID or name. +\returns ::NC_ENAMEINUSE String match to name in use +\returns ::NC_ENOMEM Memory allocation (malloc) failure +\returns ::NC_EPERM Write to read only +\section Example + +Here is an example using nc_rename_dim to rename the dimension lat to +latitude in an existing netCDF dataset named foo.nc: + +\code + #include + ... + int status, ncid, latid; + ... + status = nc_open("foo.nc", NC_WRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_redef(ncid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_dimid(ncid, "lat", &latid); + if (status != NC_NOERR) handle_error(status); + status = nc_rename_dim(ncid, latid, "latitude"); + if (status != NC_NOERR) handle_error(status); + status = nc_enddef(ncid); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_rename_dim(int ncid, int dimid, const char *name) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->rename_dim(ncid,dimid,name); +} + +/*! +Find the number of dimensions. + +In a classic model netCDF file, this funtion returns the number of +defined dimensions. In a netCDF-4/HDF5 file, this function returns the +number of dimensions available in the group specified by ncid, which +may be less than the total number of dimensions in a file. In a +netCDF-4/HDF5 file, dimensions are in all sub-groups, sub-sub-groups, +etc. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param ndimsp Pointer where number of dimensions will be +written. Ignored if NULL. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Not a valid ID. + + */ +int +nc_inq_ndims(int ncid, int *ndimsp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + if(ndimsp == NULL) return NC_NOERR; + return ncp->dispatch->inq(ncid,ndimsp,NULL,NULL,NULL); +} + +/*! +Find the ID of the unlimited dimension. + +This function finds the ID of the unlimited dimension. For +netCDF-4/HDF5 files (which may have more than one unlimited +dimension), the ID of the first unlimited dimesnion is returned. For +these files, nc_inq_unlimdims() will return all the unlimited dimension IDs. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param unlimdimidp Pointer where unlimited dimension ID will be +stored. If there is no unlimited dimension, -1 will be stored +here. Ignored if NULL. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Not a valid ID. + + */ +int +nc_inq_unlimdim(int ncid, int *unlimdimidp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_unlimdim(ncid,unlimdimidp); +} + +/*! +Find out the name of a dimension. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param dimid Dimension ID, from a previous call to nc_inq_dimid() or +nc_def_dim(). + +\param name Returned dimension name. The caller must allocate space +for the returned name. The maximum possible length, in characters, of +a dimension name is given by the predefined constant +NC_MAX_NAME. (This doesn't include the null terminator, so declare +your array to be size NC_MAX_NAME+1). The returned character array +will be null-terminated. Ignored if NULL. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Not a valid ID. +\returns ::NC_EBADDIM Invalid dimension ID or name. + +\section Example + +Here is an example using nc_inq_dim() to determine the length of a +dimension named lat, and the name and current maximum length of the +unlimited dimension for an existing netCDF dataset named foo.nc: + +\code + #include + ... + int status, ncid, latid, recid; + size_t latlength, recs; + char recname[NC_MAX_NAME+1]; + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_unlimdim(ncid, &recid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_dimid(ncid, "lat", &latid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_dimlen(ncid, latid, &latlength); + if (status != NC_NOERR) handle_error(status); + + status = nc_inq_dim(ncid, recid, recname, &recs); + if (status != NC_NOERR) handle_error(status); +\endcode + + */ +int +nc_inq_dimname(int ncid, int dimid, char *name) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + if(name == NULL) return NC_NOERR; + return ncp->dispatch->inq_dim(ncid,dimid,name,NULL); +} + +/*! +Find the length of a dimension. + +The length for the unlimited dimension, if any, is the number of +records written so far. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param dimid Dimension ID, from a previous call to nc_inq_dimid() or +nc_def_dim(). + +\param lenp Pointer where the length will be stored. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Not a valid ID. +\returns ::NC_EBADDIM Invalid dimension ID or name. + +\section Example + +Here is an example using nc_inq_dim() to determine the length of a +dimension named lat, and the name and current maximum length of the +unlimited dimension for an existing netCDF dataset named foo.nc: + +\code + #include + ... + int status, ncid, latid, recid; + size_t latlength, recs; + char recname[NC_MAX_NAME+1]; + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_unlimdim(ncid, &recid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_dimid(ncid, "lat", &latid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_dimlen(ncid, latid, &latlength); + if (status != NC_NOERR) handle_error(status); + + status = nc_inq_dim(ncid, recid, recname, &recs); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_inq_dimlen(int ncid, int dimid, size_t *lenp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + if(lenp == NULL) return NC_NOERR; + return ncp->dispatch->inq_dim(ncid,dimid,NULL,lenp); +} +/**@}*/ diff --git a/extern/src_netcdf4/ddispatch.c b/extern/src_netcdf4/ddispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..dcea514448dfac764e3ce6f135131eb6ea1785bf --- /dev/null +++ b/extern/src_netcdf4/ddispatch.c @@ -0,0 +1,213 @@ +#include "ncdispatch.h" +#include "nc_uri.h" + +extern int NCSUBSTRATE_intialize(void); + +/* Define vectors of zeros and ones for use with various nc_get_varX function*/ +size_t nc_sizevector0[NC_MAX_DIMS]; +size_t nc_sizevector1[NC_MAX_DIMS]; +ptrdiff_t nc_ptrdiffvector1[NC_MAX_DIMS]; + +/* Define the known protocols and their manipulations */ +static struct NCPROTOCOLLIST { + char* protocol; + char* substitute; + int modelflags; +} ncprotolist[] = { + {"http",NULL,0}, + {"https",NULL,0}, + {"file",NULL,NC_DISPATCH_NCD}, + {"dods","http",NC_DISPATCH_NCD}, + {"dodss","https",NC_DISPATCH_NCD}, + {"cdmr","http",NC_DISPATCH_NCR|NC_DISPATCH_NC4}, + {"cdmrs","https",NC_DISPATCH_NCR|NC_DISPATCH_NC4}, + {"cdmremote","http",NC_DISPATCH_NCR|NC_DISPATCH_NC4}, + {"cdmremotes","https",NC_DISPATCH_NCR|NC_DISPATCH_NC4}, + {NULL,NULL,0} /* Terminate search */ +}; + +/* Define the server to ping in order; + make the order attempt to optimize + against future changes. +*/ +static const char* servers[] = { +"http://motherlode.ucar.edu:8081", /* try this first */ +"http://remotetest.unidata.ucar.edu", +"http://remotetest.ucar.edu", +"http://motherlode.ucar.edu:8080", +"http://motherlode.ucar.edu", +"http://remotetests.unidata.ucar.edu", +"http://remotetests.ucar.edu", +NULL +}; + +/* +static nc_type longtype = (sizeof(long) == sizeof(int)?NC_INT:NC_INT64); +static nc_type ulongtype = (sizeof(unsigned long) == sizeof(unsigned int)?NC_UINT:NC_UINT64); +*/ + +/* Allow dispatch to do initialization */ +int +NCDISPATCH_initialize(void) +{ + extern int NCSUBSTRATE_initialize(void); + int i; + NCSUBSTRATE_initialize(); + for(i=0;iprotocol;protolist++) { + if(strcmp(tmpurl->protocol,protolist->protocol) == 0) { + isurl=1; + break; + } + } + nc_urifree(tmpurl); + return isurl; + } + return 0; +} + +/* +Return the OR of some of the NC_DISPATCH flags +Assumes that the path is known to be a url +*/ + +int +NC_urlmodel(const char* path) +{ + int model = 0; + NC_URI* tmpurl = NULL; + struct NCPROTOCOLLIST* protolist; + + if(!nc_uriparse(path,&tmpurl)) goto done; + + /* Look at any prefixed parameters */ + if(nc_urilookup(tmpurl,"netcdf4",NULL) + || nc_urilookup(tmpurl,"netcdf-4",NULL)) { + model = (NC_DISPATCH_NC4|NC_DISPATCH_NCD); + } else if(nc_urilookup(tmpurl,"netcdf3",NULL) + || nc_urilookup(tmpurl,"netcdf-3",NULL)) { + model = (NC_DISPATCH_NC3|NC_DISPATCH_NCD); + } else if(nc_urilookup(tmpurl,"cdmremote",NULL) + || nc_urilookup(tmpurl,"cdmr",NULL)) { + model = (NC_DISPATCH_NCR|NC_DISPATCH_NC4); + } + + if(model == 0) { + /* Now look at the protocol */ + for(protolist=ncprotolist;protolist->protocol;protolist++) { + if(strcmp(tmpurl->protocol,protolist->protocol) == 0) { + model |= protolist->modelflags; + if(protolist->substitute) { + if(tmpurl->protocol) free(tmpurl->protocol); + tmpurl->protocol = strdup(protolist->substitute); + } + break; + } + } + } + + /* Force NC_DISPATCH_NC3 if necessary */ + if((model & NC_DISPATCH_NC4) == 0) + model |= (NC_DISPATCH_NC3 | NC_DISPATCH_NCD); + +done: + nc_urifree(tmpurl); + return model; +} + +/* Override dispatch table management */ +static NC_Dispatch* NC_dispatch_override = NULL; + +/* Override dispatch table management */ +NC_Dispatch* +NC_get_dispatch_override(void) { + return NC_dispatch_override; +} + +void NC_set_dispatch_override(NC_Dispatch* d) +{ + NC_dispatch_override = d; +} + +/* Overlay by treating the tables as arrays of void*. + Overlay rules are: + overlay base merge + ------- ---- ----- + null null null + null y y + x null x + x y x +*/ + +int +NC_dispatch_overlay(const NC_Dispatch* overlay, const NC_Dispatch* base, NC_Dispatch* merge) +{ + void** voverlay = (void**)overlay; + void** vmerge; + int i, count = sizeof(NC_Dispatch) / sizeof(void*); + /* dispatch table must be exact multiple of sizeof(void*) */ + assert(count * sizeof(void*) == sizeof(NC_Dispatch)); + *merge = *base; + vmerge = (void**)merge; + for(i=0;imodel = overlay->model; + return NC_NOERR; +} diff --git a/extern/src_netcdf4/denum.c b/extern/src_netcdf4/denum.c new file mode 100644 index 0000000000000000000000000000000000000000..dc8a2b057f03c3840ab24167e04b2cce1c23bcc4 --- /dev/null +++ b/extern/src_netcdf4/denum.c @@ -0,0 +1,176 @@ +/*! \file + Functions for Enum Types + + Copyright 2011 University Corporation for Atmospheric + Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \name Enum Types + Functions to create and learn about enum types. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/** \ingroup user_types +Create an enum type. Provide an ncid, a name, and a base integer type. + +After calling this function, fill out the type with repeated calls to +nc_insert_enum(). Call nc_insert_enum() once for each value you wish +to make part of the enumeration. + +\param ncid \ref ncid + +\param base_typeid The base integer type for this enum. Must be one +of: ::NC_BYTE, ::NC_UBYTE, ::NC_SHORT, ::NC_USHORT, ::NC_INT, +::NC_UINT, ::NC_INT64, ::NC_UINT64. + +\param name \ref object_name of new type. + +\param typeidp A pointer to an nc_type. The typeid of the new type +will be placed there. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +\returns ::NC_ENAMEINUSE That name is in use. +\returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME. +\returns ::NC_EBADNAME Name contains illegal characters. +\returns ::NC_EPERM Attempt to write to a read-only file. +\returns ::NC_ENOTINDEFINE Not in define mode. + */ +int +nc_def_enum(int ncid, nc_type base_typeid, const char *name, nc_type *typeidp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_enum(ncid,base_typeid,name,typeidp); +} + +/** \ingroup user_types +Insert a named member into a enum type. + +\param ncid \ref ncid +\param xtype +\param name The identifier (\ref object_name) of the new member. +\param value The value that is to be associated with this member. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +\returns ::NC_ENAMEINUSE That name is in use. +\returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME. +\returns ::NC_EBADNAME Name contains illegal characters. +\returns ::NC_EPERM Attempt to write to a read-only file. +\returns ::NC_ENOTINDEFINE Not in define mode. + */ +int +nc_insert_enum(int ncid, nc_type xtype, const char *name, + const void *value) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->insert_enum(ncid, xtype, name, + value); +} + +/** \ingroup user_types +Learn about a user-define enumeration type. + +\param ncid \ref ncid + +\param xtype Typeid to inquire about. + +\param name \ref object_name of type will be copied here. \ref +ignored_if_null. + +\param base_nc_typep Typeid if the base type of the enum.\ref +ignored_if_null. + +\param base_sizep Pointer that will get the size in bytes of the base +type. \ref ignored_if_null. + +\param num_membersp Pointer that will get the number of members +defined for this enum type. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_enum(int ncid, nc_type xtype, char *name, nc_type *base_nc_typep, + size_t *base_sizep, size_t *num_membersp) +{ + int class = 0; + int stat = nc_inq_user_type(ncid, xtype, name, base_sizep, + base_nc_typep, num_membersp, &class); + if(stat != NC_NOERR) return stat; + if(class != NC_ENUM) stat = NC_EBADTYPE; + return stat; +} + +/** \ingroup user_types +Learn about a about a member of an enum type. + +\param ncid \ref ncid + +\param xtype Typeid of the enum type. + +\param idx Index to the member to inquire about. + +\param name The identifier (\ref object_name) of this member will be +copied here. \ref ignored_if_null. + +\param value The value of this member will be copied here. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_enum_member(int ncid, nc_type xtype, int idx, char *name, + void *value) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_enum_member(ncid, xtype, idx, name, value); +} + +/** \ingroup user_types +Get the name which is associated with an enum member value. + +\param ncid \ref ncid + +\param xtype Typeid of the enum type. + +\param value Value of interest. + +\param identifier The identifier (\ref object_name) of this value will +be copied here. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_enum_ident(int ncid, nc_type xtype, long long value, + char *identifier) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_enum_ident(ncid,xtype,value,identifier); +} +/*! \} */ /* End of named group ...*/ diff --git a/extern/src_netcdf4/derror.c b/extern/src_netcdf4/derror.c new file mode 100644 index 0000000000000000000000000000000000000000..a9c4e60f4b920a4b81529605e83f2f6f360e2e09 --- /dev/null +++ b/extern/src_netcdf4/derror.c @@ -0,0 +1,255 @@ +/** \file +Error messages and library version. + +These functions return the library version, and error messages. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See COPYRIGHT file for more info. +*/ + +#include "ncdispatch.h" + +/* Tell the user the version of netCDF. */ +static const char nc_libvers[] = PACKAGE_VERSION " of "__DATE__" "__TIME__" $"; + +/** \defgroup lib_version Library Version + +*/ + +/** +\ingroup lib_version +Return the library version. + +\returns short string that contains the version information for the +library. + */ +const char * +nc_inq_libvers(void) +{ + return nc_libvers; +} + +/** \defgroup error Error Handling +NetCDF functions non-zero status codes on error. + +Each netCDF function returns an integer status value. If the returned +status value indicates an error, you may handle it in any way desired, +from printing an associated error message and exiting to ignoring the +error indication and proceeding (not recommended!). For simplicity, +the examples in this guide check the error status and call a separate +function, handle_err(), to handle any errors. One possible definition +of handle_err() can be found within the documentation of +nc_strerror(). + +The nc_strerror() function is available to convert a returned integer +error status into an error message string. + +Occasionally, low-level I/O errors may occur in a layer below the +netCDF library. For example, if a write operation causes you to exceed +disk quotas or to attempt to write to a device that is no longer +available, you may get an error from a layer below the netCDF library, +but the resulting write error will still be reflected in the returned +status value. + + */ + +/** +\ingroup error + Given an error number, return an error message. + +This function returns a static reference to an error message string +corresponding to an integer netCDF error status or to a system error +number, presumably returned by a previous call to some other netCDF +function. The error codes are defined in netcdf.h. + +\param ncerr1 error number + +\returns short string containing error message. + +\section Example + +Here is an example of a simple error handling function that uses +nc_strerror to print the error message corresponding to the netCDF +error status returned from any netCDF function call and then exit: + +\code + #include + ... + void handle_error(int status) { + if (status != NC_NOERR) { + fprintf(stderr, "%s\n", nc_strerror(status)); + exit(-1); + } + } +\endcode +*/ +const char * +nc_strerror(int ncerr1) +{ + /* System error? */ + if(NC_ISSYSERR(ncerr1)) + { + const char *cp = (const char *) strerror(ncerr1); + if(cp == NULL) + return "Unknown Error"; + return cp; + } + + /* If we're here, this is a netcdf error code. */ + switch(ncerr1) + { + case NC_NOERR: + return "No error"; + case NC_EBADID: + return "NetCDF: Not a valid ID"; + case NC_ENFILE: + return "NetCDF: Too many files open"; + case NC_EEXIST: + return "NetCDF: File exists && NC_NOCLOBBER"; + case NC_EINVAL: + return "NetCDF: Invalid argument"; + case NC_EPERM: + return "NetCDF: Write to read only"; + case NC_ENOTINDEFINE: + return "NetCDF: Operation not allowed in data mode"; + case NC_EINDEFINE: + return "NetCDF: Operation not allowed in define mode"; + case NC_EINVALCOORDS: + return "NetCDF: Index exceeds dimension bound"; + case NC_EMAXDIMS: + return "NetCDF: NC_MAX_DIMS exceeded"; + case NC_ENAMEINUSE: + return "NetCDF: String match to name in use"; + case NC_ENOTATT: + return "NetCDF: Attribute not found"; + case NC_EMAXATTS: + return "NetCDF: NC_MAX_ATTRS exceeded"; + case NC_EBADTYPE: + return "NetCDF: Not a valid data type or _FillValue type mismatch"; + case NC_EBADDIM: + return "NetCDF: Invalid dimension ID or name"; + case NC_EUNLIMPOS: + return "NetCDF: NC_UNLIMITED in the wrong index"; + case NC_EMAXVARS: + return "NetCDF: NC_MAX_VARS exceeded"; + case NC_ENOTVAR: + return "NetCDF: Variable not found"; + case NC_EGLOBAL: + return "NetCDF: Action prohibited on NC_GLOBAL varid"; + case NC_ENOTNC: + return "NetCDF: Unknown file format"; + case NC_ESTS: + return "NetCDF: In Fortran, string too short"; + case NC_EMAXNAME: + return "NetCDF: NC_MAX_NAME exceeded"; + case NC_EUNLIMIT: + return "NetCDF: NC_UNLIMITED size already in use"; + case NC_ENORECVARS: + return "NetCDF: nc_rec op when there are no record vars"; + case NC_ECHAR: + return "NetCDF: Attempt to convert between text & numbers"; + case NC_EEDGE: + return "NetCDF: Start+count exceeds dimension bound"; + case NC_ESTRIDE: + return "NetCDF: Illegal stride"; + case NC_EBADNAME: + return "NetCDF: Name contains illegal characters"; + case NC_ERANGE: + return "NetCDF: Numeric conversion not representable"; + case NC_ENOMEM: + return "NetCDF: Memory allocation (malloc) failure"; + case NC_EVARSIZE: + return "NetCDF: One or more variable sizes violate format constraints"; + case NC_EDIMSIZE: + return "NetCDF: Invalid dimension size"; + case NC_ETRUNC: + return "NetCDF: File likely truncated or possibly corrupted"; + case NC_EAXISTYPE: + return "NetCDF: Illegal axis type"; + case NC_EDAP: + return "NetCDF: DAP failure"; + case NC_ECURL: + return "NetCDF: libcurl failure"; + case NC_EIO: + return "NetCDF: I/O failure"; + case NC_ENODATA: + return "NetCDF: Variable has no data in DAP request"; + case NC_EDAPSVC: + return "NetCDF: DAP server error"; + case NC_EDAS: + return "NetCDF: Malformed or inaccessible DAP DAS"; + case NC_EDDS: + return "NetCDF: Malformed or inaccessible DAP DDS"; + case NC_EDATADDS: + return "NetCDF: Malformed or inaccessible DAP DATADDS"; + case NC_EDAPURL: + return "NetCDF: Malformed URL"; + case NC_EDAPCONSTRAINT: + return "NetCDF: Malformed Constraint"; + case NC_ETRANSLATION: + return "NetCDF: Untranslatable construct"; + case NC_EHDFERR: + return "NetCDF: HDF error"; + case NC_ECANTREAD: + return "NetCDF: Can't read file"; + case NC_ECANTWRITE: + return "NetCDF: Can't write file"; + case NC_ECANTCREATE: + return "NetCDF: Can't create file"; + case NC_EFILEMETA: + return "NetCDF: Can't add HDF5 file metadata"; + case NC_EDIMMETA: + return "NetCDF: Can't define dimensional metadata"; + case NC_EATTMETA: + return "NetCDF: Can't open HDF5 attribute"; + case NC_EVARMETA: + return "NetCDF: Problem with variable metadata."; + case NC_ENOCOMPOUND: + return "NetCDF: Can't create HDF5 compound type"; + case NC_EATTEXISTS: + return "NetCDF: Attempt to create attribute that alread exists"; + case NC_ENOTNC4: + return "NetCDF: Attempting netcdf-4 operation on netcdf-3 file"; + case NC_ESTRICTNC3: + return "NetCDF: Attempting netcdf-4 operation on strict nc3 netcdf-4 file"; + case NC_ENOTNC3: + return "NetCDF: Attempting netcdf-3 operation on netcdf-4 file"; + case NC_ENOPAR: + return "NetCDF: Parallel operation on file opened for non-parallel access"; + case NC_EPARINIT: + return "NetCDF: Error initializing for parallel access"; + case NC_EBADGRPID: + return "NetCDF: Bad group ID"; + case NC_EBADTYPID: + return "NetCDF: Bad type ID"; + case NC_ETYPDEFINED: + return "NetCDF: Type has already been defined and may not be edited"; + case NC_EBADFIELD: + return "NetCDF: Bad field ID"; + case NC_EBADCLASS: + return "NetCDF: Bad class"; + case NC_EMAPTYPE: + return "NetCDF: Mapped access for atomic types only"; + case NC_ELATEFILL: + return "NetCDF: Attempt to define fill value when data already exists."; + case NC_ELATEDEF: + return "NetCDF: Attempt to define var properties, like deflate, after enddef."; + case NC_EDIMSCALE: + return "NetCDF: Probem with HDF5 dimscales."; + case NC_ENOGRP: + return "NetCDF: No group found."; + case NC_ESTORAGE: + return "NetCDF: Cannot specify both contiguous and chunking."; + case NC_EBADCHUNK: + return "NetCDF: Bad chunk sizes."; + case NC_ENOTBUILT: + return "NetCDF: Attempt to use feature that was not turned on " + "when netCDF was built."; + case NC_EDISKLESS: + return "NetCDF: Error in using diskless access"; + default: + return "Unknown Error"; + } +} + + diff --git a/extern/src_netcdf4/dfile.c b/extern/src_netcdf4/dfile.c new file mode 100644 index 0000000000000000000000000000000000000000..9b1a03f22591e3970f78b2e04fb2697315fb19ca --- /dev/null +++ b/extern/src_netcdf4/dfile.c @@ -0,0 +1,1650 @@ +/** \file +File create and open functions + +These functions end up calling functions in one of the dispatch layers +(netCDF-4, dap server, etc). + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See COPYRIGHT file for more info. +*/ + +#include "config.h" +#include +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#include "ncdispatch.h" + +static int nc_initialized = 0; + +/** \defgroup datasets NetCDF Files + +NetCDF opens datasets as files or remote access URLs. + +A netCDF dataset that has not yet been opened can only be referred to +by its dataset name. Once a netCDF dataset is opened, it is referred +to by a netCDF ID, which is a small non-negative integer returned when +you create or open the dataset. A netCDF ID is much like a file +descriptor in C or a logical unit number in FORTRAN. In any single +program, the netCDF IDs of distinct open netCDF datasets are +distinct. A single netCDF dataset may be opened multiple times and +will then have multiple distinct netCDF IDs; however at most one of +the open instances of a single netCDF dataset should permit +writing. When an open netCDF dataset is closed, the ID is no longer +associated with a netCDF dataset. + +Functions that deal with the netCDF library include: +- Get version of library. +- Get error message corresponding to a returned error code. + +The operations supported on a netCDF dataset as a single object are: +- Create, given dataset name and whether to overwrite or not. +- Open for access, given dataset name and read or write intent. +- Put into define mode, to add dimensions, variables, or attributes. +- Take out of define mode, checking consistency of additions. +- Close, writing to disk if required. +- Inquire about the number of dimensions, number of variables, +number of global attributes, and ID of the unlimited dimension, if +any. +- Synchronize to disk to make sure it is current. +- Set and unset nofill mode for optimized sequential writes. +- After a summary of conventions used in describing the netCDF +interfaces, the rest of this chapter presents a detailed description +of the interfaces for these operations. +*/ +/**@{*/ + +size_t* NC_coord_zero; +size_t* NC_coord_one; + +static void +nc_local_initialize(void) +{ + int i; + NC_coord_zero = (size_t*)malloc(sizeof(size_t)*NC_MAX_VAR_DIMS); + if(NC_coord_zero == NULL) abort(); + NC_coord_one = (size_t*)malloc(sizeof(size_t)*NC_MAX_VAR_DIMS); + if(NC_coord_one == NULL) abort(); + for(i=0;icomm; + info = ((NC_MPI_INFO*)mpi_info)->info; + } + if((retval = MPI_File_open(comm, (char *)path, MPI_MODE_RDONLY,info, + &fh)) != MPI_SUCCESS) + return NC_EPARINIT; + if((retval = MPI_File_read(fh, magic, MAGIC_NUMBER_LEN, MPI_CHAR, + &status)) != MPI_SUCCESS) + return NC_EPARINIT; + if((retval = MPI_File_close(&fh)) != MPI_SUCCESS) + return NC_EPARINIT; + } else +#endif /* USE_PARALLEL */ + { + FILE *fp; + int i; + + if(path == NULL || strlen(path)==0) + return NC_EINVAL; + + if (!(fp = fopen(path, "r"))) + return errno; + i = fread(magic, MAGIC_NUMBER_LEN, 1, fp); + fclose(fp); + if(i != 1) + return errno; + } + + /* Ignore the first byte for HDF */ + if(magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F') + *hdf = 5; + else if(magic[0] == '\016' && magic[1] == '\003' + && magic[2] == '\023' && magic[3] == '\001') + *hdf = 4; + else if(magic[0] == 'C' && magic[1] == 'D' && magic[2] == 'F') + { + if(magic[3] == '\001') + *cdf = 1; /* netcdf classic version 1 */ + else if(magic[3] == '\002') + *cdf = 2; /* netcdf classic version 2 */ + } + + return NC_NOERR; +} + +/** \ingroup datasets +Create a new netCDF file. + +This function creates a new netCDF dataset, returning a netCDF ID that +can subsequently be used to refer to the netCDF dataset in other +netCDF function calls. The new netCDF dataset opened for write access +and placed in define mode, ready for you to add dimensions, variables, +and attributes. + +\param path The file name of the new netCDF dataset. + +\param cmode The creation mode flag. The following flags are +available: NC_NOCLOBBER (do not overwrite existing file), NC_SHARE +(limit write caching - netcdf classic files onlt), NC_64BIT_OFFSET +(create 64-bit offset file), NC_NETCDF4 (create netCDF-4/HDF5 file), +NC_CLASSIC_MODEL (enforce netCDF classic mode on netCDF-4/HDF5 +files), NC_DISKLESS (store data only in memory), NC_MMAP (use MMAP +for NC_DISKLESS), and NC_WRITE. +See discussion below. + +\param ncidp Pointer to location where returned netCDF ID is to be +stored. + +

The cmode Flag

+ +The cmode flag is used to control the type of file created, and some +aspects of how it may be used. + +Setting NC_NOCLOBBER means you do not want to clobber (overwrite) an +existing dataset; an error (NC_EEXIST) is returned if the specified +dataset already exists. + +The NC_SHARE flag is appropriate when one process may be writing the +dataset and one or more other processes reading the dataset +concurrently; it means that dataset accesses are not buffered and +caching is limited. Since the buffering scheme is optimized for +sequential access, programs that do not access data sequentially may +see some performance improvement by setting the NC_SHARE flag. This +flag is ignored for netCDF-4 files. + +Setting NC_64BIT_OFFSET causes netCDF to create a 64-bit offset format +file, instead of a netCDF classic format file. The 64-bit offset +format imposes far fewer restrictions on very large (i.e. over 2 GB) +data files. See Large File Support. + +A zero value (defined for convenience as NC_CLOBBER) specifies the +default behavior: overwrite any existing dataset with the same file +name and buffer and cache accesses for efficiency. The dataset will be +in netCDF classic format. See NetCDF Classic Format Limitations. + +Setting NC_NETCDF4 causes netCDF to create a HDF5/NetCDF-4 file. + +Setting NC_CLASSIC_MODEL causes netCDF to enforce the classic data +model in this file. (This only has effect for netCDF-4/HDF5 files, as +classic and 64-bit offset files always use the classic model.) When +used with NC_NETCDF4, this flag ensures that the resulting +netCDF-4/HDF5 file may never contain any new constructs from the +enhanced data model. That is, it cannot contain groups, user defined +types, multiple unlimited dimensions, or new atomic types. The +advantage of this restriction is that such files are guaranteed to +work with existing netCDF software. + +Setting NC_DISKLESS causes netCDF to create the file only in memory. +This allows for the use of files that have no long term purpose. Note that +with one exception, the in-memory file is destroyed upon calling +nc_close. If, however, the flag combination (NC_DISKLESS|NC_WRITE) +is used, then at close, the contents of the memory file will be +made persistent in the file path that was specified in the nc_create +call. If NC_DISKLESS is going to be used for creating a large classic file, +it behooves one to use either nc__create or nc_create_mp and specify +an appropriately large value of the initialsz parameter to avoid +to many extensions to the in-memory space for the file. +This flag applies to files in classic format and to file in extended +format (netcdf-4). + +Normally, NC_DISKLESS allocates space in the heap for +storing the in-memory file. If, however, the ./configure +flags --enable-mmap is used, and the additional mode flag +NC_MMAP is specified, then the file will be created using +the operating system MMAP facility. +This flag only applies to files in classic format. Extended +format (netcdf-4) files will ignore the NC_MMAP flag. + +Using NC_MMAP for nc_create is +only included for completeness vis-a-vis nc_open. The +ability to use MMAP is of limited use for nc_create because +nc_create is going to create the file in memory anyway. +Closing a MMAP'd file will be slightly faster, but not significantly. + +Note that nc_create(path,cmode,ncidp) is equivalent to the invocation of +nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp). + +\returns ::NC_NOERR No error. + +\returns ::NC_ENOMEM System out of memory. + +\returns ::NC_EHDFERR HDF5 error (netCDF-4 files only). + +\returns ::NC_EFILEMETA Error writing netCDF-4 file-level metadata in +HDF5 file. (netCDF-4 files only). + +\returns ::NC_EDISKLESS if there was an error in creating the +in-memory file. + +\note When creating a netCDF-4 file HDF5 error reporting is turned +off, if it is on. This doesn't stop the HDF5 error stack from +recording the errors, it simply stops their display to the user +through stderr. + +

Examples

+ +In this example we create a netCDF dataset named foo.nc; we want the +dataset to be created in the current directory only if a dataset with +that name does not already exist: + +@code + #include + ... + int status = NC_NOERR; + int ncid; + ... + status = nc_create("foo.nc", NC_NOCLOBBER, &ncid); + if (status != NC_NOERR) handle_error(status); +@endcode + +In this example we create a netCDF dataset named foo_large.nc. It will +be in the 64-bit offset format. + +@code + #include + ... + int status = NC_NOERR; + int ncid; + ... + status = nc_create("foo_large.nc", NC_NOCLOBBER|NC_64BIT_OFFSET, &ncid); + if (status != NC_NOERR) handle_error(status); +@endcode + +In this example we create a netCDF dataset named foo_HDF5.nc. It will +be in the HDF5 format. + +@code + #include + ... + int status = NC_NOERR; + int ncid; + ... + status = nc_create("foo_HDF5.nc", NC_NOCLOBBER|NC_NETCDF4, &ncid); + if (status != NC_NOERR) handle_error(status); +@endcode + +In this example we create a netCDF dataset named +foo_HDF5_classic.nc. It will be in the HDF5 format, but will not allow +the use of any netCDF-4 advanced features. That is, it will conform to +the classic netCDF-3 data model. + +@code + #include + ... + int status = NC_NOERR; + int ncid; + ... + status = nc_create("foo_HDF5_classic.nc", NC_NOCLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid); + if (status != NC_NOERR) handle_error(status); +@endcode + +In this example we create a in-memory netCDF classic dataset named +diskless.nc whose content will be lost when nc_close() is called. + +@code + #include + ... + int status = NC_NOERR; + int ncid; + ... + status = nc_create("diskless.nc", NC_DISKLESS, &ncid); + if (status != NC_NOERR) handle_error(status); +@endcode + +In this example we create a in-memory netCDF classic dataset named +diskless.nc and specify that it should be made persistent +in a file named diskless.nc when nc_close() is called. + +@code + #include + ... + int status = NC_NOERR; + int ncid; + ... + status = nc_create("diskless.nc", NC_DISKLESS|NC_WRITE, &ncid); + if (status != NC_NOERR) handle_error(status); +@endcode + +A variant of nc_create(), nc__create() (note the double underscore) allows +users to specify two tuning parameters for the file that it is +creating. */ +int +nc_create(const char *path, int cmode, int *ncidp) +{ + return nc__create(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp); +} + +/*! +Create a netCDF file with some extra parameters controlling classic +file cacheing. + +Like nc_create(), this function creates a netCDF file. + +\param path The file name of the new netCDF dataset. + +\param cmode The creation mode flag, the same as in nc_create(). + +\param initialsz On some systems, and with custom I/O layers, it may +be advantageous to set the size of the output file at creation +time. This parameter sets the initial size of the file at creation +time. This only applies to classic and 64-bit offset files. +The special value NC_SIZEHINT_DEFAULT (which is the value 0), +lets the netcdf library choose a suitable initial size. + +\param chunksizehintp A pointer to the chunk size hint, +which controls a space versus time tradeoff, memory +allocated in the netcdf library versus number of system +calls. Because of internal requirements, the value may not +be set to exactly the value requested. The actual value +chosen is returned by reference. Using a NULL pointer or +having the pointer point to the value NC_SIZEHINT_DEFAULT +causes the library to choose a default. How the system +chooses the default depends on the system. On many systems, +the "preferred I/O block size" is available from the stat() +system call, struct stat member st_blksize. If this is +available it is used. Lacking that, twice the system +pagesize is used. Lacking a call to discover the system +pagesize, we just set default bufrsize to 8192. The bufrsize +is a property of a given open netcdf descriptor ncid, it is +not a persistent property of the netcdf dataset. This only +applies to classic and 64-bit offset files. + +\param ncidp Pointer to location where returned netCDF ID is to be +stored. + +\note This function uses the same return codes as the nc_create() +function. + +

Examples

+ +In this example we create a netCDF dataset named foo_large.nc; we want +the dataset to be created in the current directory only if a dataset +with that name does not already exist. We also specify that bufrsize +and initial size for the file. + +\code +#include + ... + int status = NC_NOERR; + int ncid; + int intialsz = 2048; + int *bufrsize; + ... + *bufrsize = 1024; + status = nc__create("foo.nc", NC_NOCLOBBER, initialsz, bufrsize, &ncid); + if (status != NC_NOERR) handle_error(status); +\endcode +*/ +int +nc__create(const char *path, int cmode, size_t initialsz, + size_t *chunksizehintp, int *ncidp) +{ + return NC_create(path, cmode, initialsz, 0, + chunksizehintp, 0, NULL, ncidp); + +} +/** +\internal + +\deprecated This function was used in the old days with the Cray at +NCAR. The Cray is long gone, and this call is supported only for +backward compatibility. + + */ +int +nc__create_mp(const char *path, int cmode, size_t initialsz, + int basepe, size_t *chunksizehintp, int *ncidp) +{ + return NC_create(path, cmode, initialsz, basepe, + chunksizehintp, 0, NULL, ncidp); +} + +/** +Open an existing netCDF file. + +This function opens an existing netCDF dataset for access. It +determines the underlying file format automatically. Use the same call +to open a netCDF classic, 64-bit offset, or netCDF-4 file. + +\param path File name for netCDF dataset to be opened. When DAP +support is enabled, then the path may be an OPeNDAP URL rather than a +file path. + +\param mode The mode flag may include NC_WRITE (for read/write +access) and NC_SHARE (see below) and NC_DISKLESS (see below). + +\param ncidp Pointer to location where returned netCDF ID is to be +stored. + +

Open Mode

+ +A zero value (or NC_NOWRITE) specifies the default behavior: open the +dataset with read-only access, buffering and caching accesses for +efficiency. + +Otherwise, the open mode is NC_WRITE, NC_SHARE, or +NC_WRITE|NC_SHARE. Setting the NC_WRITE flag opens the dataset with +read-write access. ("Writing" means any kind of change to the dataset, +including appending or changing data, adding or renaming dimensions, +variables, and attributes, or deleting attributes.) + +The NC_SHARE flag is only used for netCDF classic and 64-bit offset +files. It is appropriate when one process may be writing the dataset +and one or more other processes reading the dataset concurrently; it +means that dataset accesses are not buffered and caching is +limited. Since the buffering scheme is optimized for sequential +access, programs that do not access data sequentially may see some +performance improvement by setting the NC_SHARE flag. + +This procedure may also be invoked with the NC_DISKLESS flag +set in the mode argument if the file to be opened is a +classic format file. For nc_open(), this flag applies only +to files in classic format. If the file is of type +NC_NETCDF4, then the NC_DISKLESS flag will be ignored. + +If NC_DISKLESS is specified, then the whole file is read completely into +memory. In effect this creates an in-memory cache of the file. +If the mode flag also specifies NC_WRITE, then the in-memory cache +will be re-written to the disk file when nc_close() is called. +For some kinds of manipulations, having the in-memory cache can +speed up file processing. But in simple cases, non-cached +processing may actually be faster than using cached processing. +You will need to experiment to determine if the in-memory caching +is worthwhile for your application. + +Normally, NC_DISKLESS allocates space in the heap for +storing the in-memory file. If, however, the ./configure +flags --enable-mmap is used, and the additional mode flag +NC_MMAP is specified, then the file will be opened using +the operating system MMAP facility. +This flag only applies to files in classic format. Extended +format (netcdf-4) files will ignore the NC_MMAP flag. + +In most cases, using MMAP provides no advantage +for just NC_DISKLESS. The one case where using MMAP is an +advantage is when a file is to be opened and only a small portion +of its data is to be read and/or written. +In this scenario, MMAP will cause only the accessed data to be +retrieved from disk. Without MMAP, NC_DISKLESS will read the whole +file into memory on nc_open. Thus, MMAP will provide some performance +improvement in this case. + +It is not necessary to pass any information about the format of the +file being opened. The file type will be detected automatically by the +netCDF library. + +If a the path is a DAP URL, then the open mode is read-only. +Setting NC_WRITE will be ignored. + +\note When opening a netCDF-4 file HDF5 error reporting is turned off, +if it is on. This doesn't stop the HDF5 error stack from recording the +errors, it simply stops their display to the user through stderr. + +nc_open()returns the value NC_NOERR if no errors occurred. Otherwise, +the returned status indicates an error. Possible causes of errors +include: + +Note that nc_open(path,cmode,ncidp) is equivalent to the invocation of +nc__open(path,cmode,NC_SIZEHINT_DEFAULT,NULL,ncidp). + +\returns ::NC_NOERR No error. + +\returns ::NC_ENOMEM Out of memory. + +\returns ::NC_EHDFERR HDF5 error. (NetCDF-4 files only.) + +\returns ::NC_EDIMMETA Error in netCDF-4 dimension metadata. (NetCDF-4 files only.) + +

Examples

+ +Here is an example using nc_open()to open an existing netCDF dataset +named foo.nc for read-only, non-shared access: + +@code +#include + ... +int status = NC_NOERR; +int ncid; + ... +status = nc_open("foo.nc", 0, &ncid); +if (status != NC_NOERR) handle_error(status); +@endcode +*/ +int +nc_open(const char *path, int mode, int *ncidp) +{ + return NC_open(path, mode, 0, NULL, 0, NULL, ncidp); +} + +/** +Open a netCDF file with extra performance parameters for the classic +library. + +\param path File name for netCDF dataset to be opened. When DAP +support is enabled, then the path may be an OPeNDAP URL rather than a +file path. + +\param mode The mode flag may include NC_WRITE (for read/write +access) and NC_SHARE as in nc_open(). + +\param chunksizehintp A size hint for the classic library. Only +applies to classic and 64-bit offset files. See below for more +information. + +\param ncidp Pointer to location where returned netCDF ID is to be +stored. + +

The chunksizehintp Parameter

+ +The argument referenced by bufrsizehintp controls a space versus time +tradeoff, memory allocated in the netcdf library versus number of +system calls. + +Because of internal requirements, the value may not be set to exactly +the value requested. The actual value chosen is returned by reference. + +Using a NULL pointer or having the pointer point to the value +NC_SIZEHINT_DEFAULT causes the library to choose a default. +How the system chooses the default depends on the system. On +many systems, the "preferred I/O block size" is available from the +stat() system call, struct stat member st_blksize. If this is +available it is used. Lacking that, twice the system pagesize is used. + +Lacking a call to discover the system pagesize, we just set default +bufrsize to 8192. + +The bufrsize is a property of a given open netcdf descriptor ncid, it +is not a persistent property of the netcdf dataset. + + +\returns ::NC_NOERR No error. + +\returns ::NC_ENOMEM Out of memory. + +\returns ::NC_EHDFERR HDF5 error. (NetCDF-4 files only.) + +\returns ::NC_EDIMMETA Error in netCDF-4 dimension metadata. (NetCDF-4 +files only.) + +*/ +int +nc__open(const char *path, int mode, + size_t *chunksizehintp, int *ncidp) +{ + return NC_open(path, mode, 0, chunksizehintp, 0, + NULL, ncidp); +} + +/** +\internal + +\deprecated This function was used in the old days with the Cray at +NCAR. The Cray is long gone, and this call is supported only for +backward compatibility. + + */ +int +nc__open_mp(const char *path, int mode, int basepe, + size_t *chunksizehintp, int *ncidp) +{ + return NC_open(path, mode, basepe, chunksizehintp, + 0, NULL, ncidp); +} + +/** +Get the file pathname (or the opendap URL) which was used to +open/create the ncid's file. + +\param ncid NetCDF ID, from a previous call to nc_open() or +nc_create(). + +\param pathlen Pointer where length of path will be returned. Ignored +if NULL. + +\param path Pointer where path name will be copied. Space must already +be allocated. Ignored if NULL. + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Invalid ncid passed. +*/ +int +nc_inq_path(int ncid, size_t *pathlen, char *path) +{ + NC* ncp; + int stat = NC_NOERR; + if ((stat = NC_check_id(ncid, &ncp))) + return stat; + if(ncp->path == NULL) { + if(pathlen) *pathlen = 0; + if(path) path[0] = '\0'; + } else { + if (pathlen) *pathlen = strlen(ncp->path); + if (path) strcpy(path, ncp->path); + } + return stat; +} + +/** +Put open netcdf dataset into define mode + +The function nc_redef puts an open netCDF dataset into define mode, so +dimensions, variables, and attributes can be added or renamed and +attributes can be deleted. + +For netCDF-4 files (i.e. files created with NC_NETCDF4 in the cmode in +their call to nc_create()), it is not necessary to call nc_redef() +unless the file was also created with NC_STRICT_NC3. For straight-up +netCDF-4 files, nc_redef() is called automatically, as needed. + +For all netCDF-4 files, the root ncid must be used. This is the ncid +returned by nc_open() and nc_create(), and points to the root of the +hierarchy tree for netCDF-4 files. + +\param ncid NetCDF ID, from a previous call to nc_open() or +nc_create(). + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Bad ncid. + +\returns ::NC_EBADGRPID The ncid must refer to the root group of the +file, that is, the group returned by nc_open() or nc_create(). + +\returns ::NC_EINDEFINE Already in define mode. + +\returns ::NC_EPERM File is read-only. + +

Example

+ +Here is an example using nc_redef to open an existing netCDF dataset +named foo.nc and put it into define mode: + +\code +#include + ... +int status = NC_NOERR; +int ncid; + ... +status = nc_open("foo.nc", NC_WRITE, &ncid); +if (status != NC_NOERR) handle_error(status); + ... +status = nc_redef(ncid); +if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_redef(int ncid) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->redef(ncid); +} + +/** +Leave define mode + +The function nc_enddef() takes an open netCDF dataset out of define +mode. The changes made to the netCDF dataset while it was in define +mode are checked and committed to disk if no problems +occurred. Non-record variables may be initialized to a "fill value" as +well with nc_set_fill(). The netCDF dataset is then placed in data +mode, so variable data can be read or written. + +It's not necessary to call nc_enddef() for netCDF-4 files. With netCDF-4 +files, nc_enddef() is called when needed by the netcdf-4 library. User +calls to nc_enddef() for netCDF-4 files still flush the metadata to +disk. + +This call may involve copying data under some circumstances. For a +more extensive discussion see File Structure and Performance. + +For netCDF-4/HDF5 format files there are some variable settings (the +compression, endianness, fletcher32 error correction, and fill value) +which must be set (if they are going to be set at all) between the +nc_def_var() and the next nc_enddef(). Once the nc_enddef() is called, +these settings can no longer be changed for a variable. + +\param ncid NetCDF ID, from a previous call to nc_open() or +nc_create(). + +If you use a group id (in a netCDF-4/HDF5 file), the enddef +will apply to the entire file. That means the enddef will not just end +define mode in one group, but in the entire file. + +\returns ::NC_NOERR no error + +\returns ::NC_EBADID Invalid ncid passed. + +

Example

+ +Here is an example using nc_enddef() to finish the definitions of a new +netCDF dataset named foo.nc and put it into data mode: + +\code + #include + ... + int status = NC_NOERR; + int ncid; + ... + status = nc_create("foo.nc", NC_NOCLOBBER, &ncid); + if (status != NC_NOERR) handle_error(status); + + ... create dimensions, variables, attributes + + status = nc_enddef(ncid); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_enddef(int ncid) +{ + int status = NC_NOERR; + NC *ncp; + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) return status; + return ncp->dispatch->_enddef(ncid,0,1,0,1); +} + +/** +Leave define mode with performance tuning + +The function nc__enddef takes an open netCDF dataset out of define +mode. The changes made to the netCDF dataset while it was in define +mode are checked and committed to disk if no problems +occurred. Non-record variables may be initialized to a "fill value" as +well with nc_set_fill(). The netCDF dataset is then placed in data mode, +so variable data can be read or written. + +This call may involve copying data under some circumstances. For a +more extensive discussion see File Structure and Performance. + +\warning This function exposes internals of the netcdf version 1 file +format. Users should use nc_enddef() in most circumstances. This +function may not be available on future netcdf implementations. + +The classic netcdf file format has three sections, the "header" +section, the data section for fixed size variables, and the data +section for variables which have an unlimited dimension (record +variables). + +The header begins at the beginning of the file. The index (offset) of +the beginning of the other two sections is contained in the +header. Typically, there is no space between the sections. This causes +copying overhead to accrue if one wishes to change the size of the +sections, as may happen when changing names of things, text attribute +values, adding attributes or adding variables. Also, for buffered i/o, +there may be advantages to aligning sections in certain ways. + +The minfree parameters allow one to control costs of future calls to +nc_redef, nc_enddef() by requesting that minfree bytes be available at +the end of the section. + +The align parameters allow one to set the alignment of the beginning +of the corresponding sections. The beginning of the section is rounded +up to an index which is a multiple of the align parameter. The flag +value ALIGN_CHUNK tells the library to use the bufrsize (see above) as +the align parameter. It has nothing to do with the chunking +(multidimensional tiling) features of netCDF-4. + +The file format requires mod 4 alignment, so the align parameters are +silently rounded up to multiples of 4. The usual call, + +\code + nc_enddef(ncid); +\endcode + +is equivalent to + +\code + nc__enddef(ncid, 0, 4, 0, 4); +\endcode + +The file format does not contain a "record size" value, this is +calculated from the sizes of the record variables. This unfortunate +fact prevents us from providing minfree and alignment control of the +"records" in a netcdf file. If you add a variable which has an +unlimited dimension, the third section will always be copied with the +new variable added. + +\param ncid NetCDF ID, from a previous call to nc_open() or +nc_create(). + +\param h_minfree Sets the pad at the end of the "header" section. + +\param v_align Controls the alignment of the beginning of the data +section for fixed size variables. + +\param v_minfree Sets the pad at the end of the data section for fixed +size variables. + +\param r_align Controls the alignment of the beginning of the data +section for variables which have an unlimited dimension (record +variables). + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Invalid ncid passed. + + */ +int +nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, + size_t r_align) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align); +} + +/** +Synchronize an open netcdf dataset to disk + +The function nc_sync() offers a way to synchronize the disk copy of a +netCDF dataset with in-memory buffers. There are two reasons you might +want to synchronize after writes: +- To minimize data loss in case of abnormal termination, or +- To make data available to other processes for reading immediately + after it is written. But note that a process that already had the + dataset open for reading would not see the number of records + increase when the writing process calls nc_sync(); to accomplish this, + the reading process must call nc_sync. + +This function is backward-compatible with previous versions of the +netCDF library. The intent was to allow sharing of a netCDF dataset +among multiple readers and one writer, by having the writer call +nc_sync() after writing and the readers call nc_sync() before each +read. For a writer, this flushes buffers to disk. For a reader, it +makes sure that the next read will be from disk rather than from +previously cached buffers, so that the reader will see changes made by +the writing process (e.g., the number of records written) without +having to close and reopen the dataset. If you are only accessing a +small amount of data, it can be expensive in computer resources to +always synchronize to disk after every write, since you are giving up +the benefits of buffering. + +An easier way to accomplish sharing (and what is now recommended) is +to have the writer and readers open the dataset with the NC_SHARE +flag, and then it will not be necessary to call nc_sync() at +all. However, the nc_sync() function still provides finer granularity +than the NC_SHARE flag, if only a few netCDF accesses need to be +synchronized among processes. + +It is important to note that changes to the ancillary data, such as +attribute values, are not propagated automatically by use of the +NC_SHARE flag. Use of the nc_sync() function is still required for this +purpose. + +Sharing datasets when the writer enters define mode to change the data +schema requires extra care. In previous releases, after the writer +left define mode, the readers were left looking at an old copy of the +dataset, since the changes were made to a new copy. The only way +readers could see the changes was by closing and reopening the +dataset. Now the changes are made in place, but readers have no +knowledge that their internal tables are now inconsistent with the new +dataset schema. If netCDF datasets are shared across redefinition, +some mechanism external to the netCDF library must be provided that +prevents access by readers during redefinition and causes the readers +to call nc_sync before any subsequent access. + +When calling nc_sync(), the netCDF dataset must be in data mode. A +netCDF dataset in define mode is synchronized to disk only when +nc_enddef() is called. A process that is reading a netCDF dataset that +another process is writing may call nc_sync to get updated with the +changes made to the data by the writing process (e.g., the number of +records written), without having to close and reopen the dataset. + +Data is automatically synchronized to disk when a netCDF dataset is +closed, or whenever you leave define mode. + +\param ncid NetCDF ID, from a previous call to nc_open() or +nc_create(). + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Invalid ncid passed. + */ +int +nc_sync(int ncid) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->sync(ncid); +} + +/** +\internal + +Users no longer need to call this function, since it is called +automatically by nc_close() in case the dataset is in define mode and +something goes wrong with committing the changes. The function +nc_abort() just closes the netCDF dataset, if not in define mode. If +the dataset is being created and is still in define mode, the dataset +is deleted. If define mode was entered by a call to nc_redef(), the +netCDF dataset is restored to its state before definition mode was +entered and the dataset is closed. + +\param ncid NetCDF ID, from a previous call to nc_open() or +nc_create(). + +\returns ::NC_NOERR No error. + +

Example

+ +Here is an example using nc_abort to back out of redefinitions of a +dataset named foo.nc: + +\code + #include + ... + int ncid, status, latid; + ... + status = nc_open("foo.nc", NC_WRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_redef(ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_def_dim(ncid, "lat", 18L, &latid); + if (status != NC_NOERR) { + handle_error(status); + status = nc_abort(ncid); + if (status != NC_NOERR) handle_error(status); + } +\endcode + + */ +int +nc_abort(int ncid) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + if(ncp->path != NULL) free(ncp->path); + ncp->path = NULL; + return ncp->dispatch->abort(ncid); +} + +/** +Close an open netCDF dataset + +If the dataset in define mode, nc_enddef() will be called before +closing. (In this case, if nc_enddef() returns an error, nc_abort() will +automatically be called to restore the dataset to the consistent state +before define mode was last entered.) After an open netCDF dataset is +closed, its netCDF ID may be reassigned to the next netCDF dataset +that is opened or created. + +\param ncid NetCDF ID, from a previous call to nc_open() or nc_create(). + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Invalid id passed. + +\returns ::NC_EBADGRPID ncid did not contain the root group id of this +file. (NetCDF-4 only). + +

Example

+ +Here is an example using nc_close to finish the definitions of a new +netCDF dataset named foo.nc and release its netCDF ID: + +\code + #include + ... + int status = NC_NOERR; + int ncid; + ... + status = nc_create("foo.nc", NC_NOCLOBBER, &ncid); + if (status != NC_NOERR) handle_error(status); + + ... create dimensions, variables, attributes + + status = nc_close(ncid); + if (status != NC_NOERR) handle_error(status); +\endcode + + */ +int +nc_close(int ncid) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->close(ncid); +} + +/** +Change the fill-value mode to improve write performance. + +This function is intended for advanced usage, to optimize writes under +some circumstances described below. The function nc_set_fill() sets the +fill mode for a netCDF dataset open for writing and returns the +current fill mode in a return parameter. The fill mode can be +specified as either ::NC_FILL or ::NC_NOFILL. The default behavior +corresponding to ::NC_FILL is that data is pre-filled with fill values, +that is fill values are written when you create non-record variables +or when you write a value beyond data that has not yet been +written. This makes it possible to detect attempts to read data before +it was written. For more information on the use of fill values see +Fill Values. For information about how to define your own fill values +see Attribute Conventions. + +The behavior corresponding to ::NC_NOFILL overrides the default behavior +of prefilling data with fill values. This can be used to enhance +performance, because it avoids the duplicate writes that occur when +the netCDF library writes fill values that are later overwritten with +data. + +A value indicating which mode the netCDF dataset was already in is +returned. You can use this value to temporarily change the fill mode +of an open netCDF dataset and then restore it to the previous mode. + +After you turn on ::NC_NOFILL mode for an open netCDF dataset, you must +be certain to write valid data in all the positions that will later be +read. Note that nofill mode is only a transient property of a netCDF +dataset open for writing: if you close and reopen the dataset, it will +revert to the default behavior. You can also revert to the default +behavior by calling nc_set_fill() again to explicitly set the fill mode +to ::NC_FILL. + +There are three situations where it is advantageous to set nofill +mode: +- Creating and initializing a netCDF dataset. In this case, you should + set nofill mode before calling nc_enddef() and then write completely + all non-record variables and the initial records of all the record + variables you want to initialize. +- Extending an existing record-oriented netCDF dataset. Set nofill + mode after opening the dataset for writing, then append the + additional records to the dataset completely, leaving no intervening + unwritten records. +- Adding new variables that you are going to initialize to an existing + netCDF dataset. Set nofill mode before calling nc_enddef() then write + all the new variables completely. + +If the netCDF dataset has an unlimited dimension and the last record +was written while in nofill mode, then the dataset may be shorter than +if nofill mode was not set, but this will be completely transparent if +you access the data only through the netCDF interfaces. + +The use of this feature may not be available (or even needed) in +future releases. Programmers are cautioned against heavy reliance upon +this feature. + +\param ncid NetCDF ID, from a previous call to nc_open() or +nc_create(). + +\param fillmode Desired fill mode for the dataset, either ::NC_NOFILL or +::NC_FILL. + +\param old_modep Pointer to location for returned current fill mode of +the dataset before this call, either ::NC_NOFILL or ::NC_FILL. + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID The specified netCDF ID does not refer to an open +netCDF dataset. + +\returns ::NC_EPERM The specified netCDF ID refers to a dataset open for +read-only access. + +\returns ::NC_EINVAL The fill mode argument is neither ::NC_NOFILL nor +::NC_FILL. + +

Example

+ +Here is an example using nc_set_fill() to set nofill mode for subsequent +writes of a netCDF dataset named foo.nc: + +\code + #include + ... + int ncid, status, old_fill_mode; + ... + status = nc_open("foo.nc", NC_WRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + + ... write data with default prefilling behavior + + status = nc_set_fill(ncid, ::NC_NOFILL, &old_fill_mode); + if (status != NC_NOERR) handle_error(status); + + ... write data with no prefilling +\endcode + */ +int +nc_set_fill(int ncid, int fillmode, int *old_modep) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->set_fill(ncid,fillmode,old_modep); +} + +/** +\internal + +\deprecated This function was used in the old days with the Cray at +NCAR. The Cray is long gone, and this call is supported only for +backward compatibility. + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Invalid ncid passed. + */ +int +nc_inq_base_pe(int ncid, int *pe) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_base_pe(ncid,pe); +} + +/** +\internal + +\deprecated This function was used in the old days with the Cray at +NCAR. The Cray is long gone, and this call is supported only for +backward compatibility. + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Invalid ncid passed. + */ +int +nc_set_base_pe(int ncid, int pe) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->set_base_pe(ncid,pe); +} + +/** +Inquire about the binary format of a netCDF file. + +This function returns the (rarely needed) format version. + +\param ncid NetCDF ID, from a previous call to nc_open() or +nc_create(). + +\param formatp Pointer to location for returned format version, one of +NC_FORMAT_CLASSIC, NC_FORMAT_64BIT, NC_FORMAT_NETCDF4, +NC_FORMAT_NETCDF4_CLASSIC. + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Invalid ncid passed. + + */ +int +nc_inq_format(int ncid, int *formatp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_format(ncid,formatp); +} + +/** +Inquire about a file or group. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param ndimsp Pointer to location for returned number of dimensions +defined for this netCDF dataset. Ignored if NULL. + +\param nvarsp Pointer to location for returned number of variables +defined for this netCDF dataset. Ignored if NULL. + +\param nattsp Pointer to location for returned number of global +attributes defined for this netCDF dataset. Ignored if NULL. + +\param unlimdimidp Pointer to location for returned ID of the +unlimited dimension, if there is one for this netCDF dataset. If no +unlimited length dimension has been defined, -1 is returned. Ignored +if NULL. If there are multiple unlimited dimensions (possible only +for netCDF-4 files), only a pointer to the first is returned, for +backward compatibility. If you want them all, use nc_inq_unlimids(). + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADID Invalid ncid passed. + +

Example

+ +Here is an example using nc_inq to find out about a netCDF dataset +named foo.nc: + +\code + #include + ... + int status, ncid, ndims, nvars, ngatts, unlimdimid; + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp); +} + +int +nc_inq_nvars(int ncid, int *nvarsp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL); +} + +/** +Inquire about a type. + +Given an ncid and a typeid, get the information about a type. This +function will work on any type, including atomic and any user defined +type, whether compound, opaque, enumeration, or variable length array. + +For even more information about a user defined type nc_inq_user_type(). + +\param ncid The ncid for the group containing the type (ignored for +atomic types). + +\param xtype The typeid for this type, as returned by nc_def_compound, +nc_def_opaque, nc_def_enum, nc_def_vlen, or nc_inq_var, or as found in +netcdf.h in the list of atomic types (NC_CHAR, NC_INT, etc.). + +\param name If non-NULL, the name of the user defined type will be +copied here. It will be NC_MAX_NAME bytes or less. For atomic types, +the type name from CDL will be given. + +\param size If non-NULL, the (in-memory) size of the type in bytes +will be copied here. VLEN type size is the size of nc_vlen_t. String +size is returned as the size of a character pointer. The size may be +used to malloc space for the data, no matter what the type. + +\returns ::NC_NOERR No error. + +\returns ::NC_EBADTYPE Bad typeid. + +\returns ::NC_ENOTNC4 Seeking a user-defined type in a netCDF-3 file. + +\returns ::NC_ESTRICTNC3 Seeking a user-defined type in a netCDF-4 file +for which classic model has been turned on. + +\returns ::NC_EBADGRPID Bad group ID in ncid. + +\returns ::NC_EBADID Type ID not found. + +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + +

Example

+ +This example is from the test program tst_enums.c, and it uses all the +possible inquiry functions on an enum type. + +\code + if (nc_inq_user_type(ncid, typeids[0], name_in, &base_size_in, &base_nc_type_in, + &nfields_in, &class_in)) ERR; + if (strcmp(name_in, TYPE_NAME) || base_size_in != sizeof(int) || + base_nc_type_in != NC_INT || nfields_in != NUM_MEMBERS || class_in != NC_ENUM) ERR; + if (nc_inq_type(ncid, typeids[0], name_in, &base_size_in)) ERR; + if (strcmp(name_in, TYPE_NAME) || base_size_in != sizeof(int)) ERR; + if (nc_inq_enum(ncid, typeids[0], name_in, &base_nc_type, &base_size_in, &num_members)) ERR; + if (strcmp(name_in, TYPE_NAME) || base_nc_type != NC_INT || num_members != NUM_MEMBERS) ERR; + for (i = 0; i < NUM_MEMBERS; i++) + { + if (nc_inq_enum_member(ncid, typeid, i, name_in, &value_in)) ERR; + if (strcmp(name_in, member_name[i]) || value_in != member_value[i]) ERR; + if (nc_inq_enum_ident(ncid, typeid, member_value[i], name_in)) ERR; + if (strcmp(name_in, member_name[i])) ERR; + } + + if (nc_close(ncid)) ERR; +\endcode + */ +int +nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size) +{ + NC* ncp; + /* For compatibility, we need to allow inq about + atomic types, even if ncid is ill-defined */ + if(xtype <= ATOMICTYPEMAX) { + if(xtype <= NC_NAT) return NC_EBADTYPE; + if(name) strncpy(name,NC_atomictypename(xtype),NC_MAX_NAME); + if(size) *size = NC_atomictypelen(xtype); + return NC_NOERR; + } else { + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return NC_EBADTYPE; /* compatibility */ + return ncp->dispatch->inq_type(ncid,xtype,name,size); + } +} +/**@}*/ + +/** +\internal +\ingroup dispatch + +Create a file, calling the appropriate dispatch create call. + +For create, we have the following pieces of information to use to +determine the dispatch table: +- table specified by override +- path +- cmode + +\param path The file name of the new netCDF dataset. + +\param cmode The creation mode flag, the same as in nc_create(). + +\param initialsz This parameter sets the initial size of the file at creation +time. This only applies to classic and 64-bit offset files. + +\param basepe Deprecated parameter from the Cray days. + +\param chunksizehintp A pointer to the chunk size hint. This only +applies to classic and 64-bit offset files. + +\param useparallel Non-zero if parallel I/O is to be used on this +file. + +\param mpi_info Pointer to MPI comm and info. + +\param ncidp Pointer to location where returned netCDF ID is to be +stored. + +\returns ::NC_NOERR No error. +*/ +int +NC_create(const char *path, int cmode, size_t initialsz, + int basepe, size_t *chunksizehintp, int useparallel, + void* mpi_info, int *ncidp) +{ + int stat = NC_NOERR; + NC* ncp = NULL; + NC_Dispatch* dispatcher = NULL; + /* Need three pieces of information for now */ + int model = 0; /* one of the NC_DISPATCH_XXX values */ + int isurl = 0; /* dap or cdmremote or neither */ + int xcmode = 0; /* for implied cmode flags */ + extern int default_create_format; + + /* Initialize the dispatch table. The function pointers in the + * dispatch table will depend on how netCDF was built + * (with/without netCDF-4, DAP, CDMREMOTE). */ + if(!nc_initialized) + { + if ((stat = NC_initialize())) + return stat; + /* Do local initialization */ + nc_local_initialize(); + nc_initialized = 1; + } + + if((isurl = NC_testurl(path))) + model = NC_urlmodel(path); + + /* Look to the incoming cmode for hints */ + if(model == 0) { + if(cmode & NC_NETCDF4 || cmode & NC_PNETCDF) + model = NC_DISPATCH_NC4; + } + + if(model == 0) { + /* Check default format */ + int format = default_create_format; + switch (format) { +#ifdef USE_NETCDF4 + case NC_FORMAT_NETCDF4: + xcmode |= NC_NETCDF4; + model = NC_DISPATCH_NC4; + break; + case NC_FORMAT_NETCDF4_CLASSIC: + xcmode |= NC_CLASSIC_MODEL; + model = NC_DISPATCH_NC4; + break; +#endif + case NC_FORMAT_64BIT: + xcmode |= NC_64BIT_OFFSET; + /* fall thru */ + case NC_FORMAT_CLASSIC: + default: + model = NC_DISPATCH_NC3; + break; + } + } + + /* Add inferred flags */ + cmode |= xcmode; + +#ifdef USE_NETCDF4 + if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX)) + return NC_EINVAL; +#endif + + if (!(dispatcher = NC_get_dispatch_override())) + { + + /* Figure out what dispatcher to use */ +#ifdef USE_NETCDF4 +#ifdef USE_CDMREMOTE + if(model == (NC_DISPATCH_NC4 | NC_DISPATCH_NCR)) + dispatcher = NCCR_dispatch_table; + else +#endif + if(model == (NC_DISPATCH_NC4)) + dispatcher = NC4_dispatch_table; + else +#endif /*USE_NETCDF4*/ +#ifdef USE_DAP + if(model == (NC_DISPATCH_NC3 | NC_DISPATCH_NCD)) + dispatcher = NCD3_dispatch_table; + else +#endif + if(model == (NC_DISPATCH_NC3)) + dispatcher = NC3_dispatch_table; + else + return NC_ENOTNC; + } + + if ((stat = dispatcher->create(path, cmode, initialsz, basepe, chunksizehintp, + useparallel, mpi_info, dispatcher, &ncp))) + return stat; + + ncp->dispatch = dispatcher; + if(ncidp) + *ncidp = ncp->ext_ncid; + if (!(ncp->path = nulldup(path))) + return NC_ENOMEM; + return NC_NOERR; +} + +/** +\internal +\ingroup dispatch + +Open a netCDF file (or remote dataset) calling the appropriate +dispatch function. + +For open, we have the following pieces of information to use to determine the dispatch table. +- table specified by override +- path +- cmode +- the contents of the file (if it exists), basically checking its magic number. + +\returns ::NC_NOERR No error. +*/ +int +NC_open(const char *path, int cmode, + int basepe, size_t *chunksizehintp, + int useparallel, void* mpi_info, + int *ncidp) +{ + int stat = NC_NOERR; + NC* ncp = NULL; + NC_Dispatch* dispatcher = NULL; + /* Need two pieces of information for now */ + int model = 0; + int isurl = 0; + int cdfversion = 0; + int hdfversion = 0; + extern int default_create_format; + + if(!nc_initialized) { + stat = NC_initialize(); + if(stat) return stat; + /* Do local initialization */ + nc_local_initialize(); + nc_initialized = 1; + } + + isurl = NC_testurl(path); + if(isurl) + model = NC_urlmodel(path); + + if(!isurl) { + /* Look at the file if it exists */ + stat = NC_check_file_type(path,useparallel,mpi_info,&cdfversion,&hdfversion); + if(stat == NC_NOERR) { + if(hdfversion != 0) { + model = NC_DISPATCH_NC4; + } else if(cdfversion != 0) { + model = NC_DISPATCH_NC3; + } + } + /* else ignore the file */ + } + + /* Look to the incoming cmode for hints */ + if(model == 0) { + if(cmode & NC_NETCDF4 || cmode & NC_PNETCDF) model |= NC_DISPATCH_NC4; + } + + if(model == 0) model = NC_DISPATCH_NC3; /* final default */ + + /* Force flag consistentcy */ + if(model & NC_DISPATCH_NC4) + cmode |= NC_NETCDF4; + else if(model & NC_DISPATCH_NC3) { + cmode &= ~NC_NETCDF4; /* must be netcdf-3 */ + if(cdfversion == 2) cmode |= NC_64BIT_OFFSET; + } + + if((cmode & NC_MPIIO && cmode & NC_MPIPOSIX)) + return NC_EINVAL; + + /* override overrides any other table choice */ + dispatcher = NC_get_dispatch_override(); + if(dispatcher != NULL) goto havetable; + + /* Figure out what dispatcher to use */ +#if defined(USE_CDMREMOTE) + if(model == (NC_DISPATCH_NC4 | NC_DISPATCH_NCR)) + dispatcher = NCCR_dispatch_table; + else +#endif +#if defined(USE_DAP) + if(model == (NC_DISPATCH_NC3 | NC_DISPATCH_NCD)) + dispatcher = NCD3_dispatch_table; + else +#endif +#if defined(USE_NETCDF4) + if(model == (NC_DISPATCH_NC4)) + dispatcher = NC4_dispatch_table; + else +#endif + if(model == (NC_DISPATCH_NC3)) + dispatcher = NC3_dispatch_table; + else + return NC_ENOTNC; + + havetable: + stat = dispatcher->open(path, cmode, basepe, chunksizehintp, + useparallel, mpi_info, dispatcher, &ncp); + if(stat == NC_NOERR) { + ncp->dispatch = dispatcher; + if(ncidp) *ncidp = ncp->ext_ncid; + ncp->path = nulldup(path); + if(path == NULL) stat = NC_ENOMEM; + } + return stat; +} + +/*Provide an internal function for generating pseudo file descriptors + for systems that are not file based (e.g. dap, memio). +*/ + +/* Static counter for pseudo file descriptors (incremented) */ +static int pseudofd = 0; + +/* Create a pseudo file descriptor that does not + overlap real file descriptors +*/ +int +nc__pseudofd(void) +{ + if(pseudofd == 0) { + int maxfd = 32767; /* default */ +#ifdef HAVE_GETRLIMIT + struct rlimit rl; + if(getrlimit(RLIMIT_NOFILE,&rl) == 0) { + if(rl.rlim_max != RLIM_INFINITY) + maxfd = rl.rlim_max; + if(rl.rlim_cur != RLIM_INFINITY) + maxfd = rl.rlim_cur; + } + pseudofd = maxfd+1; +#endif + } + + return pseudofd++; +} + + diff --git a/extern/src_netcdf4/dgroup.c b/extern/src_netcdf4/dgroup.c new file mode 100644 index 0000000000000000000000000000000000000000..2e02a5cb9982cdc2013663db275e37e5b8120baf --- /dev/null +++ b/extern/src_netcdf4/dgroup.c @@ -0,0 +1,187 @@ +/*! \file +Functions for netCDF-4 features. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See \ref COPYRIGHT file for more info. */ + +#include "ncdispatch.h" + +/** \defgroup user_types User-Defined Types + +User defined types allow for more complex data structures. + +NetCDF-4 has added support for four different user defined data +types. User defined type may only be used in files created with the +::NC_NETCDF4 and without ::NC_CLASSIC_MODEL. +- compound type: like a C struct, a compound type is a collection of +types, including other user defined types, in one package. +- variable length array type: used to store ragged arrays. +- opaque type: This type has only a size per element, and no other + type information. +- enum type: Like an enumeration in C, this type lets you assign text + values to integer values, and store the integer values. + +Users may construct user defined type with the various nc_def_* +functions described in this section. They may learn about user defined +types by using the nc_inq_ functions defined in this section. + +Once types are constructed, define variables of the new type with +nc_def_var (see nc_def_var). Write to them with nc_put_var1, +nc_put_var, nc_put_vara, or nc_put_vars. Read data of user-defined +type with nc_get_var1, nc_get_var, nc_get_vara, or nc_get_vars (see +\ref variables). + +Create attributes of the new type with nc_put_att (see nc_put_att_ +type). Read attributes of the new type with nc_get_att (see +\ref attributes). +*/ +/** \{ */ + +/** \} */ + +/** \defgroup groups Groups + +NetCDF-4 added support for hierarchical groups within netCDF datasets. + +Groups are identified with a ncid, which identifies both the open +file, and the group within that file. When a file is opened with +nc_open or nc_create, the ncid for the root group of that file is +provided. Using that as a starting point, users can add new groups, or +list and navigate existing groups. + +All netCDF calls take a ncid which determines where the call will take +its action. For example, the nc_def_var function takes a ncid as its +first parameter. It will create a variable in whichever group its ncid +refers to. Use the root ncid provided by nc_create or nc_open to +create a variable in the root group. Or use nc_def_grp to create a +group and use its ncid to define a variable in the new group. + +Variable are only visible in the group in which they are defined. The +same applies to attributes. “Global” attributes are associated with +the group whose ncid is used. + +Dimensions are visible in their groups, and all child groups. + +Group operations are only permitted on netCDF-4 files - that is, files +created with the HDF5 flag in nc_create(). Groups are not compatible +with the netCDF classic data model, so files created with the +::NC_CLASSIC_MODEL file cannot contain groups (except the root group). + + */ +/** \{ */ +int +nc_inq_ncid(int ncid, const char *name, int *grp_ncid) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_ncid(ncid,name,grp_ncid); +} + +int +nc_inq_grps(int ncid, int *numgrps, int *ncids) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_grps(ncid,numgrps,ncids); +} + +int +nc_inq_grpname(int ncid, char *name) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_grpname(ncid,name); +} + +int +nc_inq_grpname_full(int ncid, size_t *lenp, char *full_name) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_grpname_full(ncid,lenp,full_name); +} + +int +nc_inq_grpname_len(int ncid, size_t *lenp) +{ + int stat = nc_inq_grpname_full(ncid,lenp,NULL); + return stat; +} + +int +nc_inq_grp_parent(int ncid, int *parent_ncid) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_grp_parent(ncid,parent_ncid); +} + +/* This has same semantics as nc_inq_ncid */ +int +nc_inq_grp_ncid(int ncid, const char *grp_name, int *grp_ncid) +{ + return nc_inq_ncid(ncid,grp_name,grp_ncid); +} + +int +nc_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_grp_full_ncid(ncid,full_name,grp_ncid); +} + +int +nc_inq_varids(int ncid, int *nvars, int *varids) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_varids(ncid,nvars,varids); +} + +int +nc_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_dimids(ncid,ndims,dimids,include_parents); +} + +int +nc_inq_typeids(int ncid, int *ntypes, int *typeids) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_typeids(ncid,ntypes,typeids); +} + +int +nc_def_grp(int parent_ncid, const char *name, int *new_ncid) +{ + NC* ncp; + int stat = NC_check_id(parent_ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_grp(parent_ncid,name,new_ncid); +} + + + +int +nc_show_metadata(int ncid) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->show_metadata(ncid); +} + +/** \} */ diff --git a/extern/src_netcdf4/dim.c b/extern/src_netcdf4/dim.c new file mode 100644 index 0000000000000000000000000000000000000000..aca6523b133fecef3e9eed8bb818a181af929564 --- /dev/null +++ b/extern/src_netcdf4/dim.c @@ -0,0 +1,497 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: dim.c,v 1.83 2010/05/25 17:54:15 dmh Exp $ */ + +#include "nc.h" +#include +#include +#include +#include "ncx.h" +#include "fbits.h" +#include "utf8proc.h" + +/* + * Free dim + * Formerly +NC_free_dim(dim) + */ +void +free_NC_dim(NC_dim *dimp) +{ + if(dimp == NULL) + return; + free_NC_string(dimp->name); + free(dimp); +} + + +NC_dim * +new_x_NC_dim(NC_string *name) +{ + NC_dim *dimp; + + dimp = (NC_dim *) malloc(sizeof(NC_dim)); + if(dimp == NULL) + return NULL; + + dimp->name = name; + dimp->hash = hash_fast(name->cp, strlen(name->cp)); + dimp->size = 0; + + return(dimp); +} + + +/* + * Formerly +NC_new_dim(const char *uname, long size) + */ +static NC_dim * +new_NC_dim(const char *uname, size_t size) +{ + NC_string *strp; + NC_dim *dimp; + + char *name = (char *)utf8proc_NFC((const unsigned char *)uname); + if(name == NULL) + return NULL; + strp = new_NC_string(strlen(name), name); + free(name); + if(strp == NULL) + return NULL; + + dimp = new_x_NC_dim(strp); + if(dimp == NULL) + { + free_NC_string(strp); + return NULL; + } + + dimp->size = size; + + return(dimp); +} + + +static NC_dim * +dup_NC_dim(const NC_dim *dimp) +{ + return new_NC_dim(dimp->name->cp, dimp->size); +} + +/* + * Step thru NC_DIMENSION array, seeking the UNLIMITED dimension. + * Return dimid or -1 on not found. + * *dimpp is set to the appropriate NC_dim. + * The loop structure is odd. In order to parallelize, + * we moved a clearer 'break' inside the loop body to the loop test. + */ +int +find_NC_Udim(const NC_dimarray *ncap, NC_dim **dimpp) +{ + assert(ncap != NULL); + + if(ncap->nelems == 0) + return -1; + + { + int dimid = 0; + NC_dim **loc = ncap->value; + + for(; (size_t) dimid < ncap->nelems + && (*loc)->size != NC_UNLIMITED; dimid++, loc++) + { + /*EMPTY*/ + } + if(dimid >= ncap->nelems) + return(-1); /* not found */ + /* else, normal return */ + if(dimpp != NULL) + *dimpp = *loc; + return dimid; + } +} + + +/* + * Step thru NC_DIMENSION array, seeking match on uname. + * Return dimid or -1 on not found. + * *dimpp is set to the appropriate NC_dim. + * The loop structure is odd. In order to parallelize, + * we moved a clearer 'break' inside the loop body to the loop test. + */ +static int +NC_finddim(const NC_dimarray *ncap, const char *uname, NC_dim **dimpp) +{ + + int dimid; + uint32_t shash; + NC_dim ** loc; + char *name; + + assert(ncap != NULL); + + if(ncap->nelems == 0) + return -1; + + { + dimid = 0; + loc = (NC_dim **) ncap->value; + /* normalized version of uname */ + name = (char *)utf8proc_NFC((const unsigned char *)uname); + if(name == NULL) + return NC_ENOMEM; + shash = hash_fast(name, strlen(name)); + + for(; (size_t) dimid < ncap->nelems + && ((*loc)->hash != shash + || strncmp((*loc)->name->cp, name, strlen(name)) != 0); + dimid++, loc++) + { + /*EMPTY*/ + } + free(name); + if(dimid >= ncap->nelems) + return(-1); /* not found */ + /* else, normal return */ + if(dimpp != NULL) + *dimpp = *loc; + return(dimid); + } +} + + +/* dimarray */ + + +/* + * Free the stuff "in" (referred to by) an NC_dimarray. + * Leaves the array itself allocated. + */ +void +free_NC_dimarrayV0(NC_dimarray *ncap) +{ + assert(ncap != NULL); + + if(ncap->nelems == 0) + return; + + assert(ncap->value != NULL); + + { + NC_dim **dpp = ncap->value; + NC_dim *const *const end = &dpp[ncap->nelems]; + for( /*NADA*/; dpp < end; dpp++) + { + free_NC_dim(*dpp); + *dpp = NULL; + } + } + ncap->nelems = 0; +} + + +/* + * Free NC_dimarray values. + * formerly +NC_free_array() + */ +void +free_NC_dimarrayV(NC_dimarray *ncap) +{ + assert(ncap != NULL); + + if(ncap->nalloc == 0) + return; + + assert(ncap->value != NULL); + + free_NC_dimarrayV0(ncap); + + free(ncap->value); + ncap->value = NULL; + ncap->nalloc = 0; +} + + +int +dup_NC_dimarrayV(NC_dimarray *ncap, const NC_dimarray *ref) +{ + int status = NC_NOERR; + + assert(ref != NULL); + assert(ncap != NULL); + + if(ref->nelems != 0) + { + const size_t sz = ref->nelems * sizeof(NC_dim *); + ncap->value = (NC_dim **) malloc(sz); + if(ncap->value == NULL) + return NC_ENOMEM; + (void) memset(ncap->value, 0, sz); + ncap->nalloc = ref->nelems; + } + + ncap->nelems = 0; + { + NC_dim **dpp = ncap->value; + const NC_dim **drpp = (const NC_dim **)ref->value; + NC_dim *const *const end = &dpp[ref->nelems]; + for( /*NADA*/; dpp < end; drpp++, dpp++, ncap->nelems++) + { + *dpp = dup_NC_dim(*drpp); + if(*dpp == NULL) + { + status = NC_ENOMEM; + break; + } + } + } + + if(status != NC_NOERR) + { + free_NC_dimarrayV(ncap); + return status; + } + + assert(ncap->nelems == ref->nelems); + + return NC_NOERR; +} + + +/* + * Add a new handle on the end of an array of handles + * Formerly +NC_incr_array(array, tail) + */ +static int +incr_NC_dimarray(NC_dimarray *ncap, NC_dim *newelemp) +{ + NC_dim **vp; + + assert(ncap != NULL); + + if(ncap->nalloc == 0) + { + assert(ncap->nelems == 0); + vp = (NC_dim **) malloc(NC_ARRAY_GROWBY * sizeof(NC_dim *)); + if(vp == NULL) + return NC_ENOMEM; + ncap->value = vp; + ncap->nalloc = NC_ARRAY_GROWBY; + } + else if(ncap->nelems +1 > ncap->nalloc) + { + vp = (NC_dim **) realloc(ncap->value, + (ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_dim *)); + if(vp == NULL) + return NC_ENOMEM; + ncap->value = vp; + ncap->nalloc += NC_ARRAY_GROWBY; + } + + if(newelemp != NULL) + { + ncap->value[ncap->nelems] = newelemp; + ncap->nelems++; + } + return NC_NOERR; +} + + +NC_dim * +elem_NC_dimarray(const NC_dimarray *ncap, size_t elem) +{ + assert(ncap != NULL); + /* cast needed for braindead systems with signed size_t */ + if(ncap->nelems == 0 || (unsigned long) elem >= ncap->nelems) + return NULL; + + assert(ncap->value != NULL); + + return ncap->value[elem]; +} + + +/* Public */ + +int +NC3_def_dim(int ncid, const char *name, size_t size, int *dimidp) +{ + int status; + NC *ncp; + int dimid; + NC_dim *dimp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(!NC_indef(ncp)) + return NC_ENOTINDEFINE; + + status = NC_check_name(name); + if(status != NC_NOERR) + return status; + + if ((ncp->flags & NC_64BIT_OFFSET) && sizeof(off_t) > 4) { + /* CDF2 format and LFS */ + if(size > X_UINT_MAX - 3) /* "- 3" handles rounded-up size */ + return NC_EDIMSIZE; + } else { + /* CDF1 format */ + if(size > X_INT_MAX - 3) + return NC_EDIMSIZE; + } + + if(size == NC_UNLIMITED) + { + dimid = find_NC_Udim(&ncp->dims, &dimp); + if(dimid != -1) + { + assert(dimid != -1); + return NC_EUNLIMIT; + } + } + + if(ncp->dims.nelems >= NC_MAX_DIMS) + return NC_EMAXDIMS; + + dimid = NC_finddim(&ncp->dims, name, &dimp); + if(dimid != -1) + return NC_ENAMEINUSE; + + dimp = new_NC_dim(name, size); + if(dimp == NULL) + return NC_ENOMEM; + status = incr_NC_dimarray(&ncp->dims, dimp); + if(status != NC_NOERR) + { + free_NC_dim(dimp); + return status; + } + + if(dimidp != NULL) + *dimidp = (int)ncp->dims.nelems -1; + return NC_NOERR; +} + + +int +NC3_inq_dimid(int ncid, const char *name, int *dimid_ptr) +{ + int status; + NC *ncp; + int dimid; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + dimid = NC_finddim(&ncp->dims, name, NULL); + + if(dimid == -1) + return NC_EBADDIM; + + if (dimid_ptr) + *dimid_ptr = dimid; + return NC_NOERR; +} + +int +NC3_inq_dim(int ncid, int dimid, char *name, size_t *sizep) +{ + int status; + NC *ncp; + NC_dim *dimp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid); + if(dimp == NULL) + return NC_EBADDIM; + + if(name != NULL) + { + (void)strncpy(name, dimp->name->cp, + dimp->name->nchars); + name[dimp->name->nchars] = 0; + } + if(sizep != NULL) + { + if(dimp->size == NC_UNLIMITED) + *sizep = NC_get_numrecs(ncp); + else + *sizep = dimp->size; + } + return NC_NOERR; +} + +int +NC3_rename_dim( int ncid, int dimid, const char *unewname) +{ + int status; + NC *ncp; + int existid; + NC_dim *dimp; + char *newname; /* normalized */ + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_readonly(ncp)) + return NC_EPERM; + + status = NC_check_name(unewname); + if(status != NC_NOERR) + return status; + + existid = NC_finddim(&ncp->dims, unewname, &dimp); + if(existid != -1) + return NC_ENAMEINUSE; + + dimp = elem_NC_dimarray(&ncp->dims, (size_t)dimid); + if(dimp == NULL) + return NC_EBADDIM; + + newname = (char *)utf8proc_NFC((const unsigned char *)unewname); + if(newname == NULL) + return NC_ENOMEM; + if(NC_indef(ncp)) + { + NC_string *old = dimp->name; + NC_string *newStr = new_NC_string(strlen(newname), newname); + free(newname); + if(newStr == NULL) + return NC_ENOMEM; + dimp->name = newStr; + dimp->hash = hash_fast(newStr->cp, strlen(newStr->cp)); + free_NC_string(old); + return NC_NOERR; + } + + /* else, not in define mode */ + + status = set_NC_string(dimp->name, newname); + dimp->hash = hash_fast(newname, strlen(newname)); + free(newname); + if(status != NC_NOERR) + return status; + + set_NC_hdirty(ncp); + + if(NC_doHsync(ncp)) + { + status = NC_sync(ncp); + if(status != NC_NOERR) + return status; + } + + return NC_NOERR; +} diff --git a/extern/src_netcdf4/dnclog.c b/extern/src_netcdf4/dnclog.c new file mode 100644 index 0000000000000000000000000000000000000000..a107b04de63535c307dcc974dfb8c5c877b7b840 --- /dev/null +++ b/extern/src_netcdf4/dnclog.c @@ -0,0 +1,166 @@ +/********************************************************************* + * Copyright 2010, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header$ + *********************************************************************/ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "nclog.h" + +#define PREFIXLEN 8 +#define MAXTAGS 256 +#define NCTAGDFALT "Log"; + +static int ncinitlog = 0; +static int nclogging = 0; +static int ncsystemfile = 0; +static char* nclogfile = NULL; +static FILE* nclogstream = NULL; + +static int nctagsize = 0; +static char** nctagset = NULL; +static char* nctagdfalt = NULL; +static char* nctagsetdfalt[] = {"Warning","Error","Note","Debug"}; +static char* nctagname(int tag); + +void +ncloginit(void) +{ + ncinitlog = 1; + ncsetlogging(0); + nclogfile = NULL; + nclogstream = NULL; + /* Use environment variables to preset nclogging state*/ + /* I hope this is portable*/ + if(getenv(ENVFLAG) != NULL) { + const char* file = getenv(ENVFLAG); + ncsetlogging(1); + nclogopen(file); + } + nctagdfalt = NCTAGDFALT; + nctagset = nctagsetdfalt; +} + +void +ncsetlogging(int tf) +{ + if(!ncinitlog) ncloginit(); + nclogging = tf; +} + +void +nclogopen(const char* file) +{ + if(!ncinitlog) ncloginit(); + nclogclose(); + if(file == NULL || strlen(file) == 0) { + /* use stderr*/ + nclogstream = stderr; + nclogfile = NULL; + ncsystemfile = 1; + } else if(strcmp(file,"stdout") == 0) { + /* use stdout*/ + nclogstream = stdout; + nclogfile = NULL; + ncsystemfile = 1; + } else if(strcmp(file,"stderr") == 0) { + /* use stderr*/ + nclogstream = stderr; + nclogfile = NULL; + ncsystemfile = 1; + } else { + int fd; + nclogfile = strdup(file); + nclogstream = NULL; + /* We need to deal with this file carefully + to avoid unauthorized access*/ + fd = open(nclogfile,O_WRONLY|O_APPEND|O_CREAT,0600); + if(fd >= 0) { + nclogstream = fdopen(fd,"a"); + } else { + free(nclogfile); + nclogfile = NULL; + nclogstream = NULL; + ncsetlogging(0); + } + ncsystemfile = 0; + } +} + +void +nclogclose(void) +{ + if(nclogstream != NULL && !ncsystemfile) { + fclose(nclogstream); + } + if(nclogfile != NULL) free(nclogfile); + nclogstream = NULL; + nclogfile = NULL; + ncsystemfile = 0; +} + +void +nclog(int tag, const char* fmt, ...) +{ + va_list args; + char* prefix; + if(!nclogging || nclogstream == NULL) return; + + prefix = nctagname(tag); + fprintf(nclogstream,"%s:",prefix); + + if(fmt != NULL) { + va_start(args, fmt); + vfprintf(nclogstream, fmt, args); + va_end( args ); + } + fprintf(nclogstream, "\n" ); + fflush(nclogstream); +} + +void +nclogtext(int tag, const char* text) +{ + nclogtextn(tag,text,strlen(text)); +} + +void +nclogtextn(int tag, const char* text, size_t count) +{ + if(!nclogging || nclogstream == NULL) return; + fwrite(text,1,count,nclogstream); + fflush(nclogstream); +} + +/* The tagset is null terminated */ +void +nclogsettags(char** tagset, char* dfalt) +{ + nctagdfalt = dfalt; + if(tagset == NULL) { + nctagsize = 0; + } else { + int i; + /* Find end of the tagset */ + for(i=0;i= nctagsize) { + return nctagdfalt; + } else { + return nctagset[tag]; + } +} diff --git a/extern/src_netcdf4/dopaque.c b/extern/src_netcdf4/dopaque.c new file mode 100644 index 0000000000000000000000000000000000000000..b9065afe52745bfddc0e8b6da54d77f66be65cd0 --- /dev/null +++ b/extern/src_netcdf4/dopaque.c @@ -0,0 +1,70 @@ +/*! \file + Functions for Opaque Types + + Copyright 2011 University Corporation for Atmospheric + Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \name Opaque Types + Functions to create and learn about opaque types. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/** \ingroup user_types +Create an opaque type. Provide a size and a name. + +\param ncid \ref ncid +\param size The size of each opaque object in bytes. +\param name \ref object_name of the new type. +\param xtypep Pointer where the new typeid for this type is returned. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +\returns ::NC_ENAMEINUSE That name is in use. +\returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME. +\returns ::NC_EBADNAME Name contains illegal characters. +\returns ::NC_EPERM Attempt to write to a read-only file. +\returns ::NC_ENOTINDEFINE Not in define mode. + */ +int +nc_def_opaque(int ncid, size_t size, const char *name, nc_type *xtypep) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_opaque(ncid,size,name,xtypep); +} + +/** \ingroup user_types +Learn about an opaque type. + +\param ncid \ref ncid + +\param xtype Typeid to inquire about. + +\param name The \ref object_name of this type will be +copied here. \ref ignored_if_null. + +\param sizep The size of the type will be copied here. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_opaque(int ncid, nc_type xtype, char *name, size_t *sizep) +{ + int class = 0; + int stat = nc_inq_user_type(ncid,xtype,name,sizep,NULL,NULL,&class); + if(stat != NC_NOERR) return stat; + if(class != NC_OPAQUE) stat = NC_EBADTYPE; + return stat; +} + +/*! \} */ /* End of named group ...*/ diff --git a/extern/src_netcdf4/dparallel.c b/extern/src_netcdf4/dparallel.c new file mode 100644 index 0000000000000000000000000000000000000000..cffb719318e360a3a58701e750355cbe941a046b --- /dev/null +++ b/extern/src_netcdf4/dparallel.c @@ -0,0 +1,130 @@ +/** \file +This file has the parallel I/O functions. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See COPYRIGHT file for more info. +*/ + +#include +#include +#include "ncdispatch.h" + +/* This function creates a file for use with parallel I/O. */ +int +nc_create_par(const char *path, int cmode, MPI_Comm comm, + MPI_Info info, int *ncidp) +{ +#ifndef USE_PARALLEL + return NC_ENOPAR; +#else + NC_MPI_INFO data; + MPI_Comm comm_c = 0; + MPI_Info info_c = 0; + + /* One of these two parallel IO modes must be chosen by the user, + * or else pnetcdf must be in use. */ + if (!(cmode & NC_MPIIO || cmode & NC_MPIPOSIX) && + !(cmode & NC_PNETCDF)) + return NC_EINVAL; + + comm_c = (MPI_Comm)comm; + info_c = (MPI_Info)info; + + data.comm = comm_c; + data.info = info_c; + return NC_create(path, cmode, 0, 0, NULL, 1, &data, ncidp); +#endif /* USE_PARALLEL */ +} + +/* This function opens a file for parallel I/O. */ +int +nc_open_par(const char *path, int mode, MPI_Comm comm, + MPI_Info info, int *ncidp) +{ +#ifndef USE_PARALLEL + return NC_ENOPAR; +#else + NC_MPI_INFO mpi_data; + + /* One of these two parallel IO modes must be chosen by the user, + * or else pnetcdf must be in use. */ + if (!(mode & NC_MPIIO || mode & NC_MPIPOSIX) && + !(mode & NC_PNETCDF)) + return NC_EINVAL; + + mpi_data.comm = comm; + mpi_data.info = info; + + return NC_open(path, mode, 0, NULL, 1, &mpi_data, ncidp); +#endif /* USE_PARALLEL */ +} + +/* Fortran needs to pass MPI comm/info as integers. */ +int +nc_open_par_fortran(const char *path, int mode, int comm, + int info, int *ncidp) +{ +#ifndef USE_PARALLEL + return NC_ENOPAR; +#else + + MPI_Comm comm_c = 0; + MPI_Info info_c = 0; + + /* Convert fortran comm and info to C comm and info, if there is a + * function to do so. Otherwise just pass them. */ +#ifdef HAVE_MPI_COMM_F2C + comm_c = MPI_Comm_f2c(comm); + info_c = MPI_Info_f2c(info); +#else + comm_c = (MPI_Comm)comm; + info_c = (MPI_Info)info; +#endif + + return nc_open_par(path, mode, comm_c, info_c, ncidp); +#endif +} + +/* This function will change the parallel access of a variable from + * independent to collective. */ +int +nc_var_par_access(int ncid, int varid, int par_access) +{ + NC* ncp; + int stat = NC_NOERR; + + if ((stat = NC_check_id(ncid, &ncp))) + return stat; + +#ifndef USE_PARALLEL + return NC_ENOPAR; +#else + return ncp->dispatch->var_par_access(ncid,varid,par_access); +#endif +} + +/* when calling from fortran: convert MPI_Comm and MPI_Info to C */ +int +nc_create_par_fortran(const char *path, int cmode, int comm, + int info, int *ncidp) +{ +#ifndef USE_PARALLEL + return NC_ENOPAR; +#else + MPI_Comm comm_c = 0; + MPI_Info info_c = 0; +#ifdef USE_PARALLEL +#ifdef HAVE_MPI_COMM_F2C + comm_c = MPI_Comm_f2c(comm); + info_c = MPI_Info_f2c(info); +#else + comm_c = (MPI_Comm)comm; + info_c = (MPI_Info)info; +#endif +#endif + return nc_create_par(path, cmode, comm_c, info_c, ncidp); +#endif +} + + + diff --git a/extern/src_netcdf4/dstring.c b/extern/src_netcdf4/dstring.c new file mode 100644 index 0000000000000000000000000000000000000000..e8bb00869d4ecdd07b76efde1936c2b0da7f0fe6 --- /dev/null +++ b/extern/src_netcdf4/dstring.c @@ -0,0 +1,302 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: string.c,v 1.76 2010/05/26 21:43:33 dmh Exp $ */ + +#include "config.h" +#include +#include +#include +#include +#include +#include "nc.h" +#include "rnd.h" +#include "utf8proc.h" + + +/* There are 3 levels of UTF8 checking: 1=> (exact)validating 2=>relaxed + and 3=>very relaxed +*/ +/* Use semi-relaxed check */ +#define UTF8_CHECK 2 + +/* + * Free string, and, if needed, its values. + * Formerly +NC_free_string() + */ +void +free_NC_string(NC_string *ncstrp) +{ + if(ncstrp==NULL) + return; + free(ncstrp); +} + + +int +nextUTF8(const char* cp) +{ + /* The goal here is to recognize the length of each + multibyte utf8 character sequence and skip it. + Again, we assume that every non-ascii character is legal. + We can define three possible tests of decreasing correctness + (in the sense that the least correct will allow some sequences that + are technically illegal UTF8). + As Regular expressions they are as follows: + 1. most correct: + UTF8 ([\xC2-\xDF][\x80-\xBF]) \ + | (\xE0[\xA0-\xBF][\x80-\xBF]) \ + | ([\xE1-\xEC][\x80-\xBF][\x80-\xBF]) \ + | (\xED[\x80-\x9F][\x80-\xBF]) \ + | ([\xEE-\xEF][\x80-\xBF][\x80-\xBF]) \ + | (\xF0[\x90-\xBF][\x80-\xBF][\x80-\xBF]) \ + | ([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]) \ + | (\xF4[\x80-\x8F][\x80-\xBF][\x80-\xBF]) \ + + 2. partially relaxed: + UTF8 ([\xC0-\xDF][\x80-\xBF]) + |([\xE0-\xEF][\x80-\xBF][\x80-\xBF]) + |([\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]) + + 3. The most relaxed version of UTF8: + UTF8 ([\xC0-\xD6].)|([\xE0-\xEF]..)|([\xF0-\xF7]...) + + We use #2 here. + + The tests are derived from the table at + http://www.w3.org/2005/03/23-lex-U + */ + +/* Define a test macro to test against a range */ +#define RANGE(c,lo,hi) (((uchar)c) >= lo && ((uchar)c) <= hi) +/* Define a common RANGE */ +#define RANGE0(c) RANGE(c,0x80,0xBF) + + int ch0; + + int skip = -1; /* assume failed */ + + ch0 = (uchar)*cp; + if(ch0 <= 0x7f) skip = 1; /* remove ascii case */ + else + +#if UTF8_CHECK == 2 + /* Do relaxed validation check */ + if(RANGE(ch0,0xC0,0XDF)) {/* 2-bytes, but check */ + if(cp[1] != 0 && RANGE0(cp[1])) + skip = 2; /* two bytes */ + } else if(RANGE(ch0,0xE0,0XEF)) {/* 3-bytes, but check */ + if(cp[1] != 0 && RANGE0(cp[1]) && cp[2] != 0 && RANGE0(cp[1])) + skip = 3; /* three bytes */ + } else if(RANGE(ch0,0xF0,0XF7)) {/* 3-bytes, but check */ + if(cp[1] != 0 && RANGE0(cp[1]) && cp[2] != 0 + && RANGE0(cp[1]) && cp[3] != 0 && RANGE0(cp[1])) + skip = 4; /* four bytes*/ + } +#elif UTF8_CHECK == 1 + /* Do exact validation check */ + if(RANGE(ch0,0xC2,0xDF)) {/* non-overlong 2-bytes */ + int ch1 = (uchar)cp[1]; + if(ch1 != 0 && RANGE0(ch1)) skip = 2; + } else if((ch0 == 0xE0)) {/* 3-bytes, not overlong */ + int ch1 = (uchar)cp[1]; + if(ch1 != 0 && RANGE(ch1,0xA0,0xBF)) { + int ch2 = (uchar)cp[2]; + if(ch2 != 0 && RANGE0(ch2)) skip = 3; + } else if((ch0 == 0xED)) {/* 3-bytes minus surrogates */ + int ch1 = (uchar)cp[1]; + if(ch1 != 0 && RANGE(ch1,0x80,0x9f)) { + int ch2 = (uchar)cp[2]; + if(ch2 != 0 && RANGE0(ch2)) skip = 3; + } else if(RANGE(ch0,0xE1,0xEC) || ch0 == 0xEE || ch0 == 0xEF) + int ch1 = (uchar)cp[1]; + if(ch1 != 0 && RANGE0(ch1)) { + int ch2 = (uchar)cp[2]; + if(ch2 != 0 && RANGE0(ch2)) skip = 3; + } + } else if((ch0 == 0xF0)) {/* planes 1-3 */ + int ch1 = (uchar)cp[1]; + if(ch1 != 0 && RANGE(ch1,0x90,0xBF) { + int ch2 = (uchar)cp[2]; + if(ch2 != 0 && RANGE0(ch2)) { + int ch3 = (uchar)cp[3]; + if(ch3 != 0 && RANGE0(ch3)) skip = 4; + } + } + } else if((ch0 == 0xF4)) {/* plane 16 */ + int ch1 = (uchar)cp[1]; + if(ch1 != 0 && RANGE0(ch1)) { + int ch2 = (uchar)cp[2]; + if(ch2 != 0 && RANGE0(ch2)) { + int ch3 = (uchar)cp[3]; + if(ch3 != 0 && RANGE0(ch3)) skip = 4; + } + } + } else if(RANGE(ch0,0xF1,0xF3) { /* planes 4-15 */ + int ch1 = (uchar)cp[1]; + if(ch1 != 0 && RANGE0(ch1)) { + int ch2 = (uchar)cp[2]; + if(ch2 != 0 && RANGE0(ch2)) { + int ch3 = (uchar)cp[3]; + if(ch3 != 0 && RANGE0(ch3)) skip = 4; + } + } + } +#else +#error "Must Define UTF8_CHECK as 1 or 2" +#endif + return skip; +} + + +/* + * Verify that a name string is valid syntax. The allowed name + * syntax (in RE form) is: + * + * ([a-zA-Z0-9_]|{UTF8})([^\x00-\x1F\x7F/]|{UTF8})* + * + * where UTF8 represents a multibyte UTF-8 encoding. Also, no + * trailing spaces are permitted in names. This definition + * must be consistent with the one in ncgen.l. We do not allow '/' + * because HDF5 does not permit slashes in names as slash is used as a + * group separator. If UTF-8 is supported, then a multi-byte UTF-8 + * character can occur anywhere within an identifier. We later + * normalize UTF-8 strings to NFC to facilitate matching and queries. + */ +int +NC_check_name(const char *name) +{ + int skip; + int ch; + const char *cp = name; + ssize_t utf8_stat; + + assert(name != NULL); + + if(*name == 0 /* empty names disallowed */ + || strchr(cp, '/')) /* '/' can't be in a name */ + goto fail; + + /* check validity of any UTF-8 */ + utf8_stat = utf8proc_check((const unsigned char *)name); + if (utf8_stat < 0) + goto fail; + + /* First char must be [a-z][A-Z][0-9]_ | UTF8 */ + ch = (uchar)*cp; + if(ch <= 0x7f) { + if( !('A' <= ch && ch <= 'Z') + && !('a' <= ch && ch <= 'z') + && !('0' <= ch && ch <= '9') + && ch != '_' ) + goto fail; + cp++; + } else { + if((skip = nextUTF8(cp)) < 0) + goto fail; + cp += skip; + } + + while(*cp != 0) { + ch = (uchar)*cp; + /* handle simple 0x00-0x7f characters here */ + if(ch <= 0x7f) { + if( ch < ' ' || ch > 0x7E) /* control char or DEL */ + goto fail; + cp++; + } else { + if((skip = nextUTF8(cp)) < 0) goto fail; + cp += skip; + } + if(cp - name > NC_MAX_NAME) + return NC_EMAXNAME; + } + if(ch <= 0x7f && isspace(ch)) /* trailing spaces disallowed */ + goto fail; + return NC_NOERR; +fail: + return NC_EBADNAME; +} + + +/* + * Allocate a NC_string structure large enough + * to hold slen characters. + * Formerly +NC_new_string(count, str) + */ +NC_string * +new_NC_string(size_t slen, const char *str) +{ + NC_string *ncstrp; + size_t sz = M_RNDUP(sizeof(NC_string)) + slen + 1; + +#if 0 + sz = _RNDUP(sz, X_ALIGN); +#endif + + ncstrp = (NC_string *)malloc(sz); + if( ncstrp == NULL ) + return NULL; + (void) memset(ncstrp, 0, sz); + + ncstrp->nchars = sz - M_RNDUP(sizeof(NC_string)) - 1; + assert(ncstrp->nchars + 1 > slen); + ncstrp->cp = (char *)ncstrp + M_RNDUP(sizeof(NC_string)); + + if(str != NULL && *str != 0) + { + (void) strncpy(ncstrp->cp, str, ncstrp->nchars +1); + ncstrp->cp[ncstrp->nchars] = 0; + } + + return(ncstrp); +} + + +/* + * If possible, change the value of an NC_string to 'str'. + * + * Formerly +NC_re_string() + */ +int +set_NC_string(NC_string *ncstrp, const char *str) +{ + size_t slen; + + assert(str != NULL && *str != 0); + + slen = strlen(str); + + if(ncstrp->nchars < slen) + return NC_ENOTINDEFINE; + + strncpy(ncstrp->cp, str, ncstrp->nchars); + /* Don't adjust ncstrp->nchars, it includes extra space in the + * header for potential later expansion of string. */ + + return NC_NOERR; +} + +/**************************************************/ +/* Provide local alternatives for unix functions + not available on all machines. Place here so that + all subsequence code modules can use it. +*/ + +#ifndef HAVE_STRDUP +char* +strdup(const char* s) +{ + char* dup; + if(s == NULL) return NULL; + dup = malloc(strlen(s)+1); + strcpy(dup,s); + return dup; +} +#endif + +/**************************************************/ diff --git a/extern/src_netcdf4/dsubstrate.c b/extern/src_netcdf4/dsubstrate.c new file mode 100644 index 0000000000000000000000000000000000000000..b79b9631ff9f30c06702747bda4fec360bfbeb52 --- /dev/null +++ b/extern/src_netcdf4/dsubstrate.c @@ -0,0 +1,915 @@ +/** \substrate +Define the substrate dispatch table and functions + +These functions end up calling functions in one of the dispatch layers +(netCDF-4, dap server, etc) using the substrate field of struct NC. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See COPYRIGHT file for more info. +*/ + +#include "netcdf.h" +#include "ncdispatch.h" + +/* forward */ +static NC_Dispatch NCSUBSTRATE_dispatch_base; + +/* +Note that because many of the signatures differ +from the netcdf API, we need to break +the abstraction and invoke the +substrate dispatch table directly. +*/ + + +int +NCSUBSTRATE_initialize(void) +{ + NCSUBSTRATE_dispatch_table = &NCSUBSTRATE_dispatch_base; + return NC_NOERR; +} + +static int +NCSUB_new_nc(NC** ncp) +{ + NC* nc; + /* Allocate memory for this info. */ + if (!(nc = calloc(1, sizeof(struct NC)))) + return NC_ENOMEM; + if(ncp) *ncp = nc; + return NC_NOERR; +} + +static int +NCSUB_redef(int ncid) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate,&ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->redef(nc->substrate); +} + +static int +NCSUB__enddef(int ncid, size_t a1, size_t a2, size_t a3, size_t a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->_enddef(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_sync(int ncid) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->sync(nc->substrate); +} + +static int +NCSUB_abort(int ncid) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->abort(nc->substrate); +} + +static int +NCSUB_close(int ncid) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->close(nc->substrate); +} + +static int +NCSUB_set_fill(int ncid, int a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->set_fill(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_base_pe(int ncid, int* a1) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_base_pe(nc->substrate,a1); +} + +static int +NCSUB_set_base_pe(int ncid, int a1) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->set_base_pe(nc->substrate,a1); +} + +static int +NCSUB_inq_format(int ncid, int* a1) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_format(nc->substrate,a1); +} + +static int +NCSUB_inq(int ncid, int* a1, int* a2, int* a3, int* a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_inq_type(int ncid, nc_type a1, char* a2, size_t* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_type(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_def_dim(int ncid, const char* a1, size_t a2, int* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_dim(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_inq_dimid(int ncid, const char* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_dimid(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_dim(int ncid, int a1, char* a2, size_t* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_dim(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_inq_unlimdim(int ncid, int* a1) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_unlimdim(nc->substrate,a1); +} + +static int +NCSUB_rename_dim(int ncid, int a1, const char* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->rename_dim(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_att(int ncid, int a1, const char* a2, nc_type* a3, size_t* a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_att(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_inq_attid(int ncid, int a1, const char* a2, int* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_attid(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_inq_attname(int ncid, int a1, int a2, char* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_attname(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_rename_att(int ncid, int a1, const char* a2, const char* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->rename_att(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_del_att(int ncid, int a1, const char* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->del_att(nc->substrate,a1,a2); +} + +static int +NCSUB_get_att(int ncid, int a1, const char* a2, void* a3, nc_type a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->get_att(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_put_att(int ncid, int a1, const char* a2, nc_type a3, size_t a4, const void* a5, nc_type a6) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->put_att(nc->substrate,a1,a2,a3,a4,a5,a6); +} + +static int +NCSUB_def_var(int ncid, const char* a1, nc_type a2, int a3, const int* a4, int* a5) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_var(nc->substrate,a1,a2,a3,a4,a5); +} + +static int +NCSUB_inq_varid(int ncid, const char* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_varid(nc->substrate,a1,a2); +} + +static int +NCSUB_rename_var(int ncid, int a1, const char* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->rename_var(nc->substrate,a1,a2); +} + +static int +NCSUB_get_vara(int ncid, int a1, const size_t* a2, const size_t* a3, void* a4, nc_type a5) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->get_vara(nc->substrate,a1,a2,a3,a4,a5); +} + +static int +NCSUB_put_vara(int ncid, int a1, const size_t* a2, const size_t* a3, const void* a4, nc_type a5) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->put_vara(nc->substrate,a1,a2,a3,a4,a5); +} + +/* Added to solve Ferret performance problem with Opendap */ +static int +NCSUB_get_vars(int ncid, int a1, const size_t* a2, const size_t* a3, const ptrdiff_t* a4, void* a5, nc_type a6) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->get_vars(nc->substrate,a1,a2,a3,a4,a5,a6); +} + +static int +NCSUB_put_vars(int ncid, int a1, const size_t* a2, const size_t* a3, const ptrdiff_t* a4, const void* a5, nc_type a6) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->put_vars(nc->substrate,a1,a2,a3,a4,a5,a6); +} + +static int +NCSUB_get_varm(int ncid, int a1, const size_t* a2, const size_t* a3, const ptrdiff_t* a4, const ptrdiff_t* a5, void* a6, nc_type a7) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->get_varm(nc->substrate,a1,a2,a3,a4,a5,a6,a7); +} + +static int +NCSUB_put_varm(int ncid, int a1, const size_t* a2, const size_t* a3, const ptrdiff_t* a4, const ptrdiff_t* a5, const void* a6, nc_type a7) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->put_varm(nc->substrate,a1,a2,a3,a4,a5,a6,a7); +} + + +static int +NCSUB_inq_var_all(int ncid, int varid, char* name, nc_type* xtypep, + int* ndimsp, int* dimidsp, int* nattsp, + int* shufflep, int* deflatep, int* deflate_levelp, + int* fletcher32p, int* contiguousp, size_t* chunksizesp, + int* no_fill, void* fill_valuep, int* endiannessp, + int* options_maskp, int* pixels_per_blockp) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_var_all(nc->substrate,varid,name,xtypep, + ndimsp,dimidsp,nattsp,shufflep, + deflatep,deflate_levelp,fletcher32p, + contiguousp,chunksizesp, + no_fill,fill_valuep, + endiannessp, + options_maskp,pixels_per_blockp); +} + +#ifdef USE_NETCDF4 + +static int +NCSUB_show_metadata(int ncid) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->show_metadata(nc->substrate); +} + +static int +NCSUB_inq_unlimdims(int ncid, int* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_unlimdims(nc->substrate,a1,a2); +} + +static int +NCSUB_var_par_access(int ncid, int a1, int a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->var_par_access(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_ncid(int ncid, const char* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_ncid(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_grps(int ncid, int* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_grps(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_grpname(int ncid, char* a1) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_grpname(nc->substrate,a1); +} + +static int +NCSUB_inq_grpname_full(int ncid, size_t* a1, char* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_grpname_full(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_grp_parent(int ncid, int* a1) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_grp_parent(nc->substrate,a1); +} + +static int +NCSUB_inq_grp_full_ncid(int ncid, const char* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_grp_full_ncid(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_varids(int ncid, int* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_varids(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_dimids(int ncid, int* a1, int* a2, int a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_dimids(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_inq_typeids(int ncid, int* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_typeids(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_type_equal(int ncid, nc_type a1, int a2, nc_type a3, int* a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_type_equal(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_def_grp(int ncid, const char* a1, int* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_grp(nc->substrate,a1,a2); +} + +static int +NCSUB_inq_user_type(int ncid, nc_type a1, char* a2, size_t* a3, nc_type* a4, size_t* a5, int* a6) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_user_type(nc->substrate,a1,a2,a3,a4,a5,a6); +} + +static int +NCSUB_inq_typeid(int ncid, const char* a1, nc_type* a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_typeid(nc->substrate,a1,a2); +} + +static int +NCSUB_def_compound(int ncid, size_t a1, const char* a2, nc_type* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_compound(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_insert_compound(int ncid, nc_type a1, const char* a2, size_t a3, nc_type a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->insert_compound(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_insert_array_compound(int ncid, nc_type a1, const char* a2, size_t a3, nc_type a4, int a5, const int* a6) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->insert_array_compound(nc->substrate,a1,a2,a3,a4,a5,a6); +} + +static int +NCSUB_inq_compound_field(int ncid, nc_type a1, int a2, char* a3, size_t* a4, nc_type* a5, int* a6, int* a7) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_compound_field(nc->substrate,a1,a2,a3,a4,a5,a6,a7); +} + +static int +NCSUB_inq_compound_fieldindex(int ncid, nc_type a1, const char* a2, int* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_compound_fieldindex(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_def_vlen(int ncid, const char* a1, nc_type a2, nc_type* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_vlen(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_put_vlen_element(int ncid, int a1, void* a2, size_t a3, const void* a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->put_vlen_element(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_get_vlen_element(int ncid, int a1, const void* a2, size_t* a3, void* a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->get_vlen_element(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_def_enum(int ncid, nc_type a1, const char* a2, nc_type* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_enum(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_insert_enum(int ncid, nc_type a1, const char* a2, const void* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->insert_enum(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_inq_enum_member(int ncid, nc_type a1, int a2, char* a3, void* a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_enum_member(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_inq_enum_ident(int ncid, nc_type a1, long long a2, char* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->inq_enum_ident(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_def_opaque(int ncid, size_t a1, const char* a2, nc_type* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_opaque(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_def_var_deflate(int ncid, int a1, int a2, int a3, int a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_var_deflate(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_def_var_fletcher32(int ncid, int a1, int a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_var_fletcher32(nc->substrate,a1,a2); +} + +static int +NCSUB_def_var_chunking(int ncid, int a1, int a2, const size_t* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_var_chunking(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_def_var_fill(int ncid, int a1, int a2, const void* a3) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_var_fill(nc->substrate,a1,a2,a3); +} + +static int +NCSUB_def_var_endian(int ncid, int a1, int a2) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->def_var_endian(nc->substrate,a1,a2); +} + +static int +NCSUB_set_var_chunk_cache(int ncid, int a1, size_t a2, size_t a3, float a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->set_var_chunk_cache(nc->substrate,a1,a2,a3,a4); +} + +static int +NCSUB_get_var_chunk_cache(int ncid, int a1, size_t* a2, size_t* a3, float* a4) +{ + NC *nc, *ncsub; + int ncstat = NC_check_id(ncid, &nc); + if(ncstat != NC_NOERR) return ncstat; + ncstat = NC_check_id(nc->substrate, &ncsub); + if(ncstat != NC_NOERR) return ncstat; + return ncsub->dispatch->get_var_chunk_cache(nc->substrate,a1,a2,a3,a4); +} + +#endif /*USE_NETCDF4*/ + +/* Declare here to avoid having a bunch of static forward declarations */ + +static NC_Dispatch NCSUBSTRATE_dispatch_base = { + +0, + +NCSUB_new_nc, + +NULL, /*NC_create*/ +NULL, /*NC_open*/ + +NCSUB_redef, +NCSUB__enddef, +NCSUB_sync, +NCSUB_abort, +NCSUB_close, +NCSUB_set_fill, +NCSUB_inq_base_pe, +NCSUB_set_base_pe, +NCSUB_inq_format, + +NCSUB_inq, +NCSUB_inq_type, + +NCSUB_def_dim, +NCSUB_inq_dimid, +NCSUB_inq_dim, +NCSUB_inq_unlimdim, +NCSUB_rename_dim, + +NCSUB_inq_att, +NCSUB_inq_attid, +NCSUB_inq_attname, +NCSUB_rename_att, +NCSUB_del_att, +NCSUB_get_att, +NCSUB_put_att, + +NCSUB_def_var, +NCSUB_inq_varid, +NCSUB_rename_var, + +NCSUB_get_vara, +NCSUB_put_vara, +NCSUB_get_vars, +NCSUB_put_vars, +NCSUB_get_varm, +NCSUB_put_varm, + +NCSUB_inq_var_all, + +#ifdef USE_NETCDF4 +NCSUB_show_metadata, +NCSUB_inq_unlimdims, + +NCSUB_var_par_access, + +NCSUB_inq_ncid, +NCSUB_inq_grps, +NCSUB_inq_grpname, +NCSUB_inq_grpname_full, +NCSUB_inq_grp_parent, +NCSUB_inq_grp_full_ncid, +NCSUB_inq_varids, +NCSUB_inq_dimids, +NCSUB_inq_typeids, +NCSUB_inq_type_equal, +NCSUB_def_grp, +NCSUB_inq_user_type, +NCSUB_inq_typeid, + +NCSUB_def_compound, +NCSUB_insert_compound, +NCSUB_insert_array_compound, +NCSUB_inq_compound_field, +NCSUB_inq_compound_fieldindex, +NCSUB_def_vlen, +NCSUB_put_vlen_element, +NCSUB_get_vlen_element, +NCSUB_def_enum, +NCSUB_insert_enum, +NCSUB_inq_enum_member, +NCSUB_inq_enum_ident, +NCSUB_def_opaque, +NCSUB_def_var_deflate, +NCSUB_def_var_fletcher32, +NCSUB_def_var_chunking, +NCSUB_def_var_fill, +NCSUB_def_var_endian, +NCSUB_set_var_chunk_cache, +NCSUB_get_var_chunk_cache + +#endif /*USE_NETCDF4*/ + +}; + +NC_Dispatch* NCSUBSTRATE_dispatch_table = NULL; /*Moved here from ddispatch.c*/ diff --git a/extern/src_netcdf4/dtype.c b/extern/src_netcdf4/dtype.c new file mode 100644 index 0000000000000000000000000000000000000000..3594867a33e7c007a038564257dcdef313507807 --- /dev/null +++ b/extern/src_netcdf4/dtype.c @@ -0,0 +1,111 @@ +/*! \file + Functions for User-Defined Types + + Copyright 2011 University Corporation for Atmospheric + Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \internal +\ingroup user_types +Learn if two types are equal + +\param ncid1 \ref ncid of first typeid. +\param typeid1 First typeid. +\param ncid2 \ref ncid of second typeid. +\param typeid2 Second typeid. +\param equal Pointer to int. A non-zero value will be copied here if +the two types are equal, a zero if they are not equal. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_type_equal(int ncid1, nc_type typeid1, int ncid2, + nc_type typeid2, int *equal) +{ + NC* ncp1; + int stat = NC_check_id(ncid1,&ncp1); + if(stat != NC_NOERR) return stat; + return ncp1->dispatch->inq_type_equal(ncid1,typeid1,ncid2,typeid2,equal); +} + +/** \name Learning about User-Defined Types + + Functions to learn about any kind of user-defined type. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/** \ingroup user_types + +Find a type by name. Given a group ID and a type name, find the ID of +the type. If the type is not found in the group, then the parents are +searched. If still not found, the entire file is searched. + +\param ncid \ref ncid +\param name \ref object_name of type to search for. +\param typeidp Typeid of named type will be copied here, if it is +found. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_typeid(int ncid, const char *name, nc_type *typeidp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_typeid(ncid,name,typeidp); +} + +/** \ingroup user_types +Learn about a user defined type. + +Given an ncid and a typeid, get the information about a user defined +type. This function will work on any user defined type, whether +compound, opaque, enumeration, or variable length array. + +\param ncid \ref ncid + +\param xtype The typeid + +\param name The \ref object_name will be copied here. \ref +ignored_if_null. + +\param size the (in-memory) size of the type in bytes will be copied +here. VLEN type size is the size of nc_vlen_t. String size is returned +as the size of a character pointer. The size may be used to malloc +space for the data, no matter what the type. \ref ignored_if_null. + +\param base_nc_typep The base type will be copied here for enum and +VLEN types. \ref ignored_if_null. + +\param nfieldsp The number of fields will be copied here for enum and +compound types. \ref ignored_if_null. + +\param classp Return the class of the user defined type, ::NC_VLEN, +::NC_OPAQUE, ::NC_ENUM, or ::NC_COMPOUND. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_user_type(int ncid, nc_type xtype, char *name, size_t *size, + nc_type *base_nc_typep, size_t *nfieldsp, int *classp) +{ + NC *ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_user_type(ncid, xtype, name, size, + base_nc_typep, nfieldsp, classp); +} +/*! \} */ /* End of named group ...*/ diff --git a/extern/src_netcdf4/dutf8proc.c b/extern/src_netcdf4/dutf8proc.c new file mode 100644 index 0000000000000000000000000000000000000000..d02169b6cc170b7ccd377a4b6025438de5b3a259 --- /dev/null +++ b/extern/src_netcdf4/dutf8proc.c @@ -0,0 +1,590 @@ +/* + * Copyright (c) 2006-2007 Jan Behrens, FlexiGuided GmbH, Berlin + * + * 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. + */ + +/* + * This library contains derived data from a modified version of the + * Unicode data files. + * + * The original data files are available at + * http://www.unicode.org/Public/UNIDATA/ + * + * Please notice the copyright statement in the file "utf8proc_data.c". + */ + + +/* + * File name: utf8proc.c + * Version: 1.1.1 + * Last changed: 2007-07-22 + * + * Description: + * Implementation of libutf8proc. + */ + + +#include "utf8proc.h" +#include "utf8proc_data.h" + +const int8_t utf8proc_utf8class[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 }; + +#define UTF8PROC_HANGUL_SBASE 0xAC00 +#define UTF8PROC_HANGUL_LBASE 0x1100 +#define UTF8PROC_HANGUL_VBASE 0x1161 +#define UTF8PROC_HANGUL_TBASE 0x11A7 +#define UTF8PROC_HANGUL_LCOUNT 19 +#define UTF8PROC_HANGUL_VCOUNT 21 +#define UTF8PROC_HANGUL_TCOUNT 28 +#define UTF8PROC_HANGUL_NCOUNT 588 +#define UTF8PROC_HANGUL_SCOUNT 11172 +/*// END is exclusive*/ +#define UTF8PROC_HANGUL_L_START 0x1100 +#define UTF8PROC_HANGUL_L_END 0x115A +#define UTF8PROC_HANGUL_L_FILLER 0x115F +#define UTF8PROC_HANGUL_V_START 0x1160 +#define UTF8PROC_HANGUL_V_END 0x11A3 +#define UTF8PROC_HANGUL_T_START 0x11A8 +#define UTF8PROC_HANGUL_T_END 0x11FA +#define UTF8PROC_HANGUL_S_START 0xAC00 +#define UTF8PROC_HANGUL_S_END 0xD7A4 + + +#define UTF8PROC_BOUNDCLASS_START 0 +#define UTF8PROC_BOUNDCLASS_OTHER 1 +#define UTF8PROC_BOUNDCLASS_CR 2 +#define UTF8PROC_BOUNDCLASS_LF 3 +#define UTF8PROC_BOUNDCLASS_CONTROL 4 +#define UTF8PROC_BOUNDCLASS_EXTEND 5 +#define UTF8PROC_BOUNDCLASS_L 6 +#define UTF8PROC_BOUNDCLASS_V 7 +#define UTF8PROC_BOUNDCLASS_T 8 +#define UTF8PROC_BOUNDCLASS_LV 9 +#define UTF8PROC_BOUNDCLASS_LVT 10 + + +const char *utf8proc_errmsg(ssize_t errcode) { + switch (errcode) { + case UTF8PROC_ERROR_NOMEM: + return "Memory for processing UTF-8 data could not be allocated."; + case UTF8PROC_ERROR_OVERFLOW: + return "UTF-8 string is too long to be processed."; + case UTF8PROC_ERROR_INVALIDUTF8: + return "Invalid UTF-8 string"; + case UTF8PROC_ERROR_NOTASSIGNED: + return "Unassigned Unicode code point found in UTF-8 string."; + case UTF8PROC_ERROR_INVALIDOPTS: + return "Invalid options for UTF-8 processing chosen."; + default: + return "An unknown error occured while processing UTF-8 data."; + } +} + +ssize_t utf8proc_iterate( + const uint8_t *str, ssize_t slen, int32_t *dst +) { + int length; + int i; + int32_t uc = -1; + *dst = -1; + if (!slen) return 0; + length = utf8proc_utf8class[str[0]]; + if (!length) return UTF8PROC_ERROR_INVALIDUTF8; + if (slen >= 0 && length > slen) return UTF8PROC_ERROR_INVALIDUTF8; + for (i=1; i= 0xD800 && uc < 0xE000) || + (uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1; + break; + case 4: + uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) + + ((str[2] & 0x3F) << 6) + (str[3] & 0x3F); + if (uc < 0x10000 || uc >= 0x110000) uc = -1; + break; + } + if (uc < 0 || ((uc & 0xFFFF) >= 0xFFFE)) + return UTF8PROC_ERROR_INVALIDUTF8; + *dst = uc; + return length; +} + +bool utf8proc_codepoint_valid(int32_t uc) { + if (uc < 0 || uc >= 0x110000 || + ((uc & 0xFFFF) >= 0xFFFE) || (uc >= 0xD800 && uc < 0xE000) || + (uc >= 0xFDD0 && uc < 0xFDF0)) return false; + else return true; +} + +ssize_t utf8proc_encode_char(int32_t uc, uint8_t *dst) { + if (uc < 0x00) { + return 0; + } else if (uc < 0x80) { + dst[0] = uc; + return 1; + } else if (uc < 0x800) { + dst[0] = 0xC0 + (uc >> 6); + dst[1] = 0x80 + (uc & 0x3F); + return 2; + } else if (uc == 0xFFFF) { + dst[0] = 0xFF; + return 1; + } else if (uc == 0xFFFE) { + dst[0] = 0xFE; + return 1; + } else if (uc < 0x10000) { + dst[0] = 0xE0 + (uc >> 12); + dst[1] = 0x80 + ((uc >> 6) & 0x3F); + dst[2] = 0x80 + (uc & 0x3F); + return 3; + } else if (uc < 0x110000) { + dst[0] = 0xF0 + (uc >> 18); + dst[1] = 0x80 + ((uc >> 12) & 0x3F); + dst[2] = 0x80 + ((uc >> 6) & 0x3F); + dst[3] = 0x80 + (uc & 0x3F); + return 4; + } else return 0; +} + +const utf8proc_property_t *utf8proc_get_property(int32_t uc) { + /* // ASSERT: uc >= 0 && uc < 0x110000*/ + return utf8proc_properties + ( + utf8proc_stage2table[ + utf8proc_stage1table[uc >> 8] + (uc & 0xFF) + ] + ); +} + +#define utf8proc_decompose_lump(replacement_uc) \ + return utf8proc_decompose_char((replacement_uc), dst, bufsize, \ + options & ~UTF8PROC_LUMP, last_boundclass) + +ssize_t utf8proc_decompose_char(int32_t uc, int32_t *dst, ssize_t bufsize, + int options, int *last_boundclass) { + /*// ASSERT: uc >= 0 && uc < 0x110000*/ + const utf8proc_property_t *property; + utf8proc_propval_t category; + int32_t hangul_sindex; + property = utf8proc_get_property(uc); + category = property->category; + hangul_sindex = uc - UTF8PROC_HANGUL_SBASE; + if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) { + if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT) { + int32_t hangul_tindex; + if (bufsize >= 1) { + dst[0] = UTF8PROC_HANGUL_LBASE + + hangul_sindex / UTF8PROC_HANGUL_NCOUNT; + if (bufsize >= 2) dst[1] = UTF8PROC_HANGUL_VBASE + + (hangul_sindex % UTF8PROC_HANGUL_NCOUNT) / UTF8PROC_HANGUL_TCOUNT; + } + hangul_tindex = hangul_sindex % UTF8PROC_HANGUL_TCOUNT; + if (!hangul_tindex) return 2; + if (bufsize >= 3) dst[2] = UTF8PROC_HANGUL_TBASE + hangul_tindex; + return 3; + } + } + if (options & UTF8PROC_REJECTNA) { + if (!category) return UTF8PROC_ERROR_NOTASSIGNED; + } + if (options & UTF8PROC_IGNORE) { + if (property->ignorable) return 0; + } + if (options & UTF8PROC_LUMP) { + if (category == UTF8PROC_CATEGORY_ZS) utf8proc_decompose_lump(0x0020); + if (uc == 0x2018 || uc == 0x2019 || uc == 0x02BC || uc == 0x02C8) + utf8proc_decompose_lump(0x0027); + if (category == UTF8PROC_CATEGORY_PD || uc == 0x2212) + utf8proc_decompose_lump(0x002D); + if (uc == 0x2044 || uc == 0x2215) utf8proc_decompose_lump(0x002F); + if (uc == 0x2236) utf8proc_decompose_lump(0x003A); + if (uc == 0x2039 || uc == 0x2329 || uc == 0x3008) + utf8proc_decompose_lump(0x003C); + if (uc == 0x203A || uc == 0x232A || uc == 0x3009) + utf8proc_decompose_lump(0x003E); + if (uc == 0x2216) utf8proc_decompose_lump(0x005C); + if (uc == 0x02C4 || uc == 0x02C6 || uc == 0x2038 || uc == 0x2303) + utf8proc_decompose_lump(0x005E); + if (category == UTF8PROC_CATEGORY_PC || uc == 0x02CD) + utf8proc_decompose_lump(0x005F); + if (uc == 0x02CB) utf8proc_decompose_lump(0x0060); + if (uc == 0x2223) utf8proc_decompose_lump(0x007C); + if (uc == 0x223C) utf8proc_decompose_lump(0x007E); + if ((options & UTF8PROC_NLF2LS) && (options & UTF8PROC_NLF2PS)) { + if (category == UTF8PROC_CATEGORY_ZL || + category == UTF8PROC_CATEGORY_ZP) + utf8proc_decompose_lump(0x000A); + } + } + if (options & UTF8PROC_STRIPMARK) { + if (category == UTF8PROC_CATEGORY_MN || + category == UTF8PROC_CATEGORY_MC || + category == UTF8PROC_CATEGORY_ME) return 0; + } + if (options & UTF8PROC_CASEFOLD) { + if (property->casefold_mapping) { + const int32_t *casefold_entry; + ssize_t written = 0; + for (casefold_entry = property->casefold_mapping; + *casefold_entry >= 0; casefold_entry++) { + written += utf8proc_decompose_char(*casefold_entry, dst+written, + (bufsize > written) ? (bufsize - written) : 0, options, + last_boundclass); + if (written < 0) return UTF8PROC_ERROR_OVERFLOW; + } + return written; + } + } + if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) { + if (property->decomp_mapping && + (!property->decomp_type || (options & UTF8PROC_COMPAT))) { + const int32_t *decomp_entry; + ssize_t written = 0; + for (decomp_entry = property->decomp_mapping; + *decomp_entry >= 0; decomp_entry++) { + written += utf8proc_decompose_char(*decomp_entry, dst+written, + (bufsize > written) ? (bufsize - written) : 0, options, + last_boundclass); + if (written < 0) return UTF8PROC_ERROR_OVERFLOW; + } + return written; + } + } + if (options & UTF8PROC_CHARBOUND) { + bool boundary; + int tbc, lbc; + tbc = + (uc == 0x000D) ? UTF8PROC_BOUNDCLASS_CR : + (uc == 0x000A) ? UTF8PROC_BOUNDCLASS_LF : + ((category == UTF8PROC_CATEGORY_ZL || + category == UTF8PROC_CATEGORY_ZP || + category == UTF8PROC_CATEGORY_CC || + category == UTF8PROC_CATEGORY_CF) && + !(uc == 0x200C || uc == 0x200D)) ? UTF8PROC_BOUNDCLASS_CONTROL : + property->extend ? UTF8PROC_BOUNDCLASS_EXTEND : + ((uc >= UTF8PROC_HANGUL_L_START && uc < UTF8PROC_HANGUL_L_END) || + uc == UTF8PROC_HANGUL_L_FILLER) ? UTF8PROC_BOUNDCLASS_L : + (uc >= UTF8PROC_HANGUL_V_START && uc < UTF8PROC_HANGUL_V_END) ? + UTF8PROC_BOUNDCLASS_V : + (uc >= UTF8PROC_HANGUL_T_START && uc < UTF8PROC_HANGUL_T_END) ? + UTF8PROC_BOUNDCLASS_T : + (uc >= UTF8PROC_HANGUL_S_START && uc < UTF8PROC_HANGUL_S_END) ? ( + ((uc-UTF8PROC_HANGUL_SBASE) % UTF8PROC_HANGUL_TCOUNT == 0) ? + UTF8PROC_BOUNDCLASS_LV : UTF8PROC_BOUNDCLASS_LVT + ) : + UTF8PROC_BOUNDCLASS_OTHER; + lbc = *last_boundclass; + boundary = + (tbc == UTF8PROC_BOUNDCLASS_EXTEND) ? false : + (lbc == UTF8PROC_BOUNDCLASS_START) ? true : + (lbc == UTF8PROC_BOUNDCLASS_CR && + tbc == UTF8PROC_BOUNDCLASS_LF) ? false : + (lbc == UTF8PROC_BOUNDCLASS_CONTROL) ? true : + (tbc == UTF8PROC_BOUNDCLASS_CONTROL) ? true : + (lbc == UTF8PROC_BOUNDCLASS_L && + (tbc == UTF8PROC_BOUNDCLASS_L || + tbc == UTF8PROC_BOUNDCLASS_V || + tbc == UTF8PROC_BOUNDCLASS_LV || + tbc == UTF8PROC_BOUNDCLASS_LVT)) ? false : + ((lbc == UTF8PROC_BOUNDCLASS_LV || + lbc == UTF8PROC_BOUNDCLASS_V) && + (tbc == UTF8PROC_BOUNDCLASS_V || + tbc == UTF8PROC_BOUNDCLASS_T)) ? false : + ((lbc == UTF8PROC_BOUNDCLASS_LVT || + lbc == UTF8PROC_BOUNDCLASS_T) && + tbc == UTF8PROC_BOUNDCLASS_T) ? false : + true; + *last_boundclass = tbc; + if (boundary) { + if (bufsize >= 1) dst[0] = 0xFFFF; + if (bufsize >= 2) dst[1] = uc; + return 2; + } + } + if (bufsize >= 1) *dst = uc; + return 1; +} + +ssize_t utf8proc_decompose( + const uint8_t *str, ssize_t slen, + int32_t *buffer, ssize_t bufsize, int options +) { + /*// slen will be ignored, if UTF8PROC_NULLTERM is set in options*/ + ssize_t wpos = 0; + if ((options & UTF8PROC_COMPOSE) && (options & UTF8PROC_DECOMPOSE)) + return UTF8PROC_ERROR_INVALIDOPTS; + if ((options & UTF8PROC_STRIPMARK) && + !(options & UTF8PROC_COMPOSE) && !(options & UTF8PROC_DECOMPOSE)) + return UTF8PROC_ERROR_INVALIDOPTS; + { + int32_t uc; + ssize_t rpos = 0; + ssize_t decomp_result; + int boundclass = UTF8PROC_BOUNDCLASS_START; + while (1) { + if (options & UTF8PROC_NULLTERM) { + rpos += utf8proc_iterate(str + rpos, -1, &uc); + /* checking of return value is not neccessary, + as 'uc' is < 0 in case of error. */ + if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8; + if (rpos < 0) return UTF8PROC_ERROR_OVERFLOW; + if (uc == 0) break; + } else { + if (rpos >= slen) break; + rpos += utf8proc_iterate(str + rpos, slen - rpos, &uc); + if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8; + } + decomp_result = utf8proc_decompose_char( + uc, buffer + wpos, (bufsize > wpos) ? (bufsize - wpos) : 0, options, + &boundclass + ); + if (decomp_result < 0) return decomp_result; + wpos += decomp_result; + /* // prohibiting integer overflows due to too long strings:*/ + if (wpos < 0 || wpos > SSIZE_MAX/sizeof(int32_t)/2) + return UTF8PROC_ERROR_OVERFLOW; + } + } + if ((options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) && bufsize >= wpos) { + ssize_t pos = 0; + while (pos < wpos-1) { + int32_t uc1, uc2; + const utf8proc_property_t *property1, *property2; + uc1 = buffer[pos]; + uc2 = buffer[pos+1]; + property1 = utf8proc_get_property(uc1); + property2 = utf8proc_get_property(uc2); + if (property1->combining_class > property2->combining_class && + property2->combining_class > 0) { + buffer[pos] = uc2; + buffer[pos+1] = uc1; + if (pos > 0) pos--; else pos++; + } else { + pos++; + } + } + } + return wpos; +} + +ssize_t utf8proc_reencode(int32_t *buffer, ssize_t length, int options) { + /* UTF8PROC_NULLTERM option will be ignored, 'length' is never ignored + ASSERT: 'buffer' has one spare byte of free space at the end! */ + if (options & (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS | UTF8PROC_STRIPCC)) { + ssize_t rpos; + ssize_t wpos = 0; + int32_t uc; + for (rpos = 0; rpos < length; rpos++) { + uc = buffer[rpos]; + if (uc == 0x000D && rpos < length-1 && buffer[rpos+1] == 0x000A) rpos++; + if (uc == 0x000A || uc == 0x000D || uc == 0x0085 || + ((options & UTF8PROC_STRIPCC) && (uc == 0x000B || uc == 0x000C))) { + if (options & UTF8PROC_NLF2LS) { + if (options & UTF8PROC_NLF2PS) { + buffer[wpos++] = 0x000A; + } else { + buffer[wpos++] = 0x2028; + } + } else { + if (options & UTF8PROC_NLF2PS) { + buffer[wpos++] = 0x2029; + } else { + buffer[wpos++] = 0x0020; + } + } + } else if ((options & UTF8PROC_STRIPCC) && + (uc < 0x0020 || (uc >= 0x007F && uc < 0x00A0))) { + if (uc == 0x0009) buffer[wpos++] = 0x0020; + } else { + buffer[wpos++] = uc; + } + } + length = wpos; + } + if (options & UTF8PROC_COMPOSE) { + int32_t *starter = NULL; + int32_t current_char; + const utf8proc_property_t *starter_property = NULL, *current_property; + utf8proc_propval_t max_combining_class = -1; + ssize_t rpos; + ssize_t wpos = 0; + int32_t composition; + for (rpos = 0; rpos < length; rpos++) { + current_char = buffer[rpos]; + current_property = utf8proc_get_property(current_char); + if (starter && current_property->combining_class > max_combining_class) { + /* // combination perhaps possible*/ + int32_t hangul_lindex; + int32_t hangul_sindex; + hangul_lindex = *starter - UTF8PROC_HANGUL_LBASE; + if (hangul_lindex >= 0 && hangul_lindex < UTF8PROC_HANGUL_LCOUNT) { + int32_t hangul_vindex; + hangul_vindex = current_char - UTF8PROC_HANGUL_VBASE; + if (hangul_vindex >= 0 && hangul_vindex < UTF8PROC_HANGUL_VCOUNT) { + *starter = UTF8PROC_HANGUL_SBASE + + (hangul_lindex * UTF8PROC_HANGUL_VCOUNT + hangul_vindex) * + UTF8PROC_HANGUL_TCOUNT; + starter_property = NULL; + continue; + } + } + hangul_sindex = *starter - UTF8PROC_HANGUL_SBASE; + if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT && + (hangul_sindex % UTF8PROC_HANGUL_TCOUNT) == 0) { + int32_t hangul_tindex; + hangul_tindex = current_char - UTF8PROC_HANGUL_TBASE; + if (hangul_tindex >= 0 && hangul_tindex < UTF8PROC_HANGUL_TCOUNT) { + *starter += hangul_tindex; + starter_property = NULL; + continue; + } + } + if (!starter_property) { + starter_property = utf8proc_get_property(*starter); + } + if (starter_property->comb1st_index >= 0 && + current_property->comb2nd_index >= 0) { + composition = utf8proc_combinations[ + starter_property->comb1st_index + + current_property->comb2nd_index + ]; + if (composition >= 0 && (!(options & UTF8PROC_STABLE) || + !(utf8proc_get_property(composition)->comp_exclusion))) { + *starter = composition; + starter_property = NULL; + continue; + } + } + } + buffer[wpos] = current_char; + if (current_property->combining_class) { + if (current_property->combining_class > max_combining_class) { + max_combining_class = current_property->combining_class; + } + } else { + starter = buffer + wpos; + starter_property = NULL; + max_combining_class = -1; + } + wpos++; + } + length = wpos; + } + { + ssize_t rpos, wpos = 0; + int32_t uc; + for (rpos = 0; rpos < length; rpos++) { + uc = buffer[rpos]; + wpos += utf8proc_encode_char(uc, ((uint8_t *)buffer) + wpos); + } + ((uint8_t *)buffer)[wpos] = 0; + return wpos; + } +} + +ssize_t utf8proc_map( + const uint8_t *str, ssize_t slen, uint8_t **dstptr, int options +) { + int32_t *buffer; + ssize_t result; + *dstptr = NULL; + result = utf8proc_decompose(str, slen, NULL, 0, options); + if (result < 0) return result; + buffer = malloc(result * sizeof(int32_t) + 1); + if (!buffer) return UTF8PROC_ERROR_NOMEM; + result = utf8proc_decompose(str, slen, buffer, result, options); + if (result < 0) { + free(buffer); + return result; + } + result = utf8proc_reencode(buffer, result, options); + if (result < 0) { + free(buffer); + return result; + } + { + int32_t *newptr; + newptr = realloc(buffer, result+1); + if (newptr) buffer = newptr; + } + *dstptr = (uint8_t *)buffer; + return result; +} + +uint8_t *utf8proc_NFD(const uint8_t *str) { + uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_DECOMPOSE); + return retval; +} + +uint8_t *utf8proc_NFC(const uint8_t *str) { + uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_COMPOSE); + return retval; +} + +uint8_t *utf8proc_NFKD(const uint8_t *str) { + uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_DECOMPOSE | UTF8PROC_COMPAT); + return retval; +} + +uint8_t *utf8proc_NFKC(const uint8_t *str) { + uint8_t *retval; + utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE | + UTF8PROC_COMPOSE | UTF8PROC_COMPAT); + return retval; +} + +ssize_t utf8proc_check(const uint8_t *str) { + ssize_t result; + result = utf8proc_decompose(str, 0, NULL, 0, + UTF8PROC_NULLTERM | UTF8PROC_STABLE); + return result; +} diff --git a/extern/src_netcdf4/dv2i.c b/extern/src_netcdf4/dv2i.c new file mode 100644 index 0000000000000000000000000000000000000000..01d3267a0da7eb5a852e6b9ecc7b060b2a34249d --- /dev/null +++ b/extern/src_netcdf4/dv2i.c @@ -0,0 +1,1160 @@ +/** \file +The V2 API Funtions. + +Copyright 1996, University Corporation for Atmospheric Research +See \ref copyright file for copying and redistribution conditions. + */ + +#ifndef NO_NETCDF_2 + +#include +#include +#include +#include +#include "netcdf.h" + +/* The subroutines in error.c emit no messages unless NC_VERBOSE bit + * is on. They call exit() when NC_FATAL bit is on. */ +int ncopts = (NC_FATAL | NC_VERBOSE) ; +int ncerr = NC_NOERR ; + +#if SIZEOF_LONG == SIZEOF_SIZE_T +/* + * We don't have to copy the arguments to switch from 'long' + * to 'size_t' or 'ptrdiff_t'. Use dummy macros. + */ + +# define NDIMS_DECL +# define A_DECL(name, type, ndims, rhs) \ + const type *const name = ((const type *)(rhs)) + +# define A_FREE(name) + +# define A_INIT(lhs, type, ndims, rhs) + +#else +/* + * We do have to copy the arguments to switch from 'long' + * to 'size_t' or 'ptrdiff_t'. In my tests on an SGI, + * any additional cost was lost in measurement variation. + * + * This stanza is true on Windows with MinGW-64 + */ + +# include "onstack.h" + +static size_t +nvdims(int ncid, int varid) +{ + int ndims=-1, status; + + if ((status = nc_inq_varndims(ncid, varid, &ndims))) + { + nc_advise("ncvdims", status, "ncid %d", ncid); + return -1; + } + return ndims; +} + +#define NDIMS_DECL const size_t ndims = nvdims(ncid, varid); + +# define A_DECL(name, type, ndims, rhs) \ + ALLOC_ONSTACK(name, type, ndims) + +# define A_FREE(name) \ + FREE_ONSTACK(name) + +# define A_INIT(lhs, type, ndims, rhs) \ + { \ + const long *lp = rhs; \ + type *tp = lhs; \ + type *const end = lhs + ndims; \ + while(tp < end) \ + { \ + *tp++ = (type) *lp++; \ + } \ + } + + +#endif + +typedef signed char schar; + +/* + * Computes number of record variables in an open netCDF file, and an array of + * the record variable ids, if the array parameter is non-null. + */ +static int +numrecvars(int ncid, int *nrecvarsp, int *recvarids) +{ + int status = NC_NOERR; + int nvars = 0; + int ndims = 0; + int nrecvars = 0; + int varid; + int recdimid; + int dimids[MAX_NC_DIMS]; + + status = nc_inq_nvars(ncid, &nvars); + if(status != NC_NOERR) + return status; + + status = nc_inq_unlimdim(ncid, &recdimid); + if(status != NC_NOERR) + return status; + + if (recdimid == -1) { + *nrecvarsp = 0; + return NC_NOERR; + } + nrecvars = 0; + for (varid = 0; varid < nvars; varid++) { + status = nc_inq_varndims(ncid, varid, &ndims); + if(status != NC_NOERR) + return status; + status = nc_inq_vardimid(ncid, varid, dimids); + if(status != NC_NOERR) + return status; + if (ndims > 0 && dimids[0] == recdimid) { + if (recvarids != NULL) + recvarids[nrecvars] = varid; + nrecvars++; + } + } + *nrecvarsp = nrecvars; + return NC_NOERR; +} + + +/* + * Computes record size (in bytes) of the record variable with a specified + * variable id. Returns size as 0 if not a record variable. + */ +static int +ncrecsize(int ncid, int varid, size_t *recsizep) +{ + int status = NC_NOERR; + int recdimid; + nc_type type; + int ndims; + int dimids[MAX_NC_DIMS]; + int id; + size_t size; + + *recsizep = 0; + status = nc_inq_unlimdim(ncid, &recdimid); + if(status != NC_NOERR) + return status; + status = nc_inq_vartype(ncid, varid, &type); + if(status != NC_NOERR) + return status; + status = nc_inq_varndims(ncid, varid, &ndims); + if(status != NC_NOERR) + return status; + status = nc_inq_vardimid(ncid, varid, dimids); + if(status != NC_NOERR) + return status; + if (ndims == 0 || dimids[0] != recdimid) { + return NC_NOERR; + } + size = nctypelen(type); + for (id = 1; id < ndims; id++) { + size_t len; + status = nc_inq_dimlen(ncid, dimids[id], &len); + if(status != NC_NOERR) + return status; + size *= len; + } + *recsizep = size; + return NC_NOERR; +} + + +/* + * Retrieves the dimension sizes of a variable with a specified variable id in + * an open netCDF file. Returns -1 on error. + */ +static int +dimsizes(int ncid, int varid, size_t *sizes) +{ + int status = NC_NOERR; + int ndims; + int id; + int dimids[MAX_NC_DIMS]; + + status = nc_inq_varndims(ncid, varid, &ndims); + if(status != NC_NOERR) + return status; + status = nc_inq_vardimid(ncid, varid, dimids); + if(status != NC_NOERR) + return status; + if (ndims == 0 || sizes == NULL) + return NC_NOERR; + for (id = 0; id < ndims; id++) { + size_t len; + status = nc_inq_dimlen(ncid, dimids[id], &len); + if(status != NC_NOERR) + return status; + sizes[id] = len; + } + return NC_NOERR; +} + + +/* + * Retrieves the number of record variables, the record variable ids, and the + * record size of each record variable. If any pointer to info to be returned + * is null, the associated information is not returned. Returns -1 on error. + */ +int +nc_inq_rec( + int ncid, + size_t *nrecvarsp, + int *recvarids, + size_t *recsizes) +{ + int status = NC_NOERR; + int nvars = 0; + int recdimid; + int varid; + int rvarids[MAX_NC_VARS]; + int nrvars = 0; + + status = nc_inq_nvars(ncid, &nvars); + if(status != NC_NOERR) + return status; + + status = nc_inq_unlimdim(ncid, &recdimid); + if(status != NC_NOERR) + return status; + + *nrecvarsp = 0; + if (recdimid == -1) + return NC_NOERR; + + status = numrecvars(ncid, &nrvars, rvarids); + if(status != NC_NOERR) + return status; + + if (nrecvarsp != NULL) + *nrecvarsp = nrvars; + if (recvarids != NULL) + for (varid = 0; varid < nrvars; varid++) + recvarids[varid] = rvarids[varid]; + + if (recsizes != NULL) + for (varid = 0; varid < nrvars; varid++) { + size_t rsize; + status = ncrecsize(ncid, rvarids[varid], &rsize); + if (status != NC_NOERR) + return status; + recsizes[varid] = rsize; + } + return NC_NOERR; +} + + +/* + * Write one record's worth of data, except don't write to variables for which + * the address of the data to be written is NULL. Return -1 on error. This is + * the same as the ncrecput() in the library, except that can handle errors + * better. + */ +int +nc_put_rec( + int ncid, + size_t recnum, + void* const* datap) +{ + int status = NC_NOERR; + int varid; + int rvarids[MAX_NC_VARS]; + int nrvars; + size_t start[MAX_NC_DIMS]; + size_t edges[MAX_NC_DIMS]; + + status = numrecvars(ncid, &nrvars, rvarids); + if(status != NC_NOERR) + return status; + + if (nrvars == 0) + return NC_NOERR; + + start[0] = recnum; + for (varid = 1; varid < nrvars; varid++) + start[varid] = 0; + + for (varid = 0; varid < nrvars; varid++) { + if (datap[varid] != NULL) { + status = dimsizes(ncid, rvarids[varid], edges); + if(status != NC_NOERR) + return status; + + edges[0] = 1; /* only 1 record's worth */ + status = nc_put_vara(ncid, rvarids[varid], start, edges, datap[varid]); + if(status != NC_NOERR) + return status; + } + } + return 0; +} + + +/* + * Read one record's worth of data, except don't read from variables for which + * the address of the data to be read is null. Return -1 on error. This is + * the same as the ncrecget() in the library, except that can handle errors + * better. + */ +int +nc_get_rec( + int ncid, + size_t recnum, + void **datap) +{ + int status = NC_NOERR; + int varid; + int rvarids[MAX_NC_VARS]; + int nrvars; + size_t start[MAX_NC_DIMS]; + size_t edges[MAX_NC_DIMS]; + + status = numrecvars(ncid, &nrvars, rvarids); + if(status != NC_NOERR) + return status; + + if (nrvars == 0) + return NC_NOERR; + + start[0] = recnum; + for (varid = 1; varid < nrvars; varid++) + start[varid] = 0; + + for (varid = 0; varid < nrvars; varid++) { + if (datap[varid] != NULL) { + status = dimsizes(ncid, rvarids[varid], edges); + if(status != NC_NOERR) + return status; + edges[0] = 1; /* only 1 record's worth */ + status = nc_get_vara(ncid, rvarids[varid], start, edges, datap[varid]); + if(status != NC_NOERR) + return status; + } + } + return 0; +} + +/* + */ +void +nc_advise(const char *routine_name, int err, const char *fmt,...) +{ + va_list args; + + if(NC_ISSYSERR(err)) + ncerr = NC_SYSERR; + else + ncerr = err; + + if( ncopts & NC_VERBOSE ) + { + (void) fprintf(stderr,"%s: ", routine_name); + va_start(args ,fmt); + (void) vfprintf(stderr,fmt,args); + va_end(args); + if(err != NC_NOERR) + { + (void) fprintf(stderr,": %s", + nc_strerror(err)); + } + (void) fputc('\n',stderr); + (void) fflush(stderr); /* to ensure log files are current */ + } + + if( (ncopts & NC_FATAL) && err != NC_NOERR ) + { + exit(ncopts); + } +} + +/* End error handling */ + +int +nccreate(const char* path, int cmode) +{ + int ncid; + const int status = nc_create(path, cmode, &ncid); + if(status != NC_NOERR) + { + nc_advise("nccreate", status, "filename \"%s\"", path); + return -1; + } + return ncid; +} + + +int +ncopen(const char *path, int mode) +{ + int ncid; + const int status = nc_open(path, mode, &ncid); + if(status != NC_NOERR) + { + nc_advise("ncopen", status, "filename \"%s\"", path); + return -1; + } + return ncid; +} + + +int +ncredef(int ncid) +{ + const int status = nc_redef(ncid); + if(status != NC_NOERR) + { + nc_advise("ncredef", status, "ncid %d", ncid); + return -1; + } + return 0; +} + + +int +ncendef(int ncid) +{ + const int status = nc_enddef(ncid); + if(status != NC_NOERR) + { + nc_advise("ncendef", status, "ncid %d", ncid); + return -1; + } + return 0; +} + + +int +ncclose(int ncid) +{ + const int status = nc_close(ncid); + if(status != NC_NOERR) + { + nc_advise("ncclose", status, "ncid %d", ncid); + return -1; + + } + return 0; +} + + +int +ncinquire( + int ncid, + int* ndims, + int* nvars, + int* natts, + int* recdim +) +{ + int nd, nv, na; + const int status = nc_inq(ncid, &nd, &nv, &na, recdim); + + if(status != NC_NOERR) + { + nc_advise("ncinquire", status, "ncid %d", ncid); + return -1; + } + /* else */ + + if(ndims != NULL) + *ndims = (int) nd; + + if(nvars != NULL) + *nvars = (int) nv; + + if(natts != NULL) + *natts = (int) na; + + return ncid; +} + + +int +ncsync(int ncid) +{ + const int status = nc_sync(ncid); + if(status != NC_NOERR) + { + nc_advise("ncsync", status, "ncid %d", ncid); + return -1; + + } + return 0; +} + + +int +ncabort(int ncid) +{ + const int status = nc_abort(ncid); + if(status != NC_NOERR) + { + nc_advise("ncabort", status, "ncid %d", ncid); + return -1; + } + return 0; +} + + +int +ncdimdef( + int ncid, + const char* name, + long length +) +{ + int dimid; + int status = NC_NOERR; + if(length < 0) { + status = NC_EDIMSIZE; + nc_advise("ncdimdef", status, "ncid %d", ncid); + return -1; + } + status = nc_def_dim(ncid, name, (size_t)length, &dimid); + if(status != NC_NOERR) + { + nc_advise("ncdimdef", status, "ncid %d", ncid); + return -1; + } + return dimid; +} + + +int +ncdimid(int ncid, const char* name) +{ + int dimid; + const int status = nc_inq_dimid(ncid, name, &dimid); + if(status != NC_NOERR) + { + nc_advise("ncdimid", status, "ncid %d", ncid); + return -1; + } + return dimid; +} + + +int +ncdiminq( + int ncid, + int dimid, + char* name, + long* length +) +{ + size_t ll; + const int status = nc_inq_dim(ncid, dimid, name, &ll); + + if(status != NC_NOERR) + { + nc_advise("ncdiminq", status, "ncid %d", ncid); + return -1; + } + /* else */ + + if(length != NULL) + *length = (int) ll; + + return dimid; +} + + +int +ncdimrename( + int ncid, + int dimid, + const char* name +) +{ + const int status = nc_rename_dim(ncid, dimid, name); + if(status != NC_NOERR) + { + nc_advise("ncdimrename", status, "ncid %d", ncid); + return -1; + } + return dimid; +} + + +int +ncvardef( + int ncid, + const char* name, + nc_type datatype, + int ndims, + const int* dim +) +{ + int varid = -1; + const int status = nc_def_var(ncid, name, datatype, ndims, dim, &varid); + if(status != NC_NOERR) + { + nc_advise("ncvardef", status, "ncid %d", ncid); + return -1; + } + return varid; +} + + +int +ncvarid( + int ncid, + const char* name +) +{ + int varid = -1; + const int status = nc_inq_varid(ncid, name, &varid); + if(status != NC_NOERR) + { + nc_advise("ncvarid", status, "ncid %d", ncid); + return -1; + } + return varid; +} + + +int +ncvarinq( + int ncid, + int varid, + char* name, + nc_type* datatype, + int* ndims, + int* dim, + int* natts +) +{ + int nd, na; + const int status = nc_inq_var(ncid, varid, name, datatype, + &nd, dim, &na); + + if(status != NC_NOERR) + { + nc_advise("ncvarinq", status, "ncid %d", ncid); + return -1; + } + /* else */ + + if(ndims != NULL) + *ndims = (int) nd; + + if(natts != NULL) + *natts = (int) na; + + return varid; +} + + +int +ncvarput1( + int ncid, + int varid, + const long* index, + const void* value +) +{ + NDIMS_DECL + A_DECL(coordp, size_t, ndims, index); + A_INIT(coordp, size_t, ndims, index); + { + const int status = nc_put_var1(ncid, varid, coordp, value); + A_FREE(coordp); + if(status != NC_NOERR) + { + nc_advise("ncvarput1", status, "ncid %d", ncid); + return -1; + } + } + return 0; +} + + +int +ncvarget1( + int ncid, + int varid, + const long* index, + void* value +) +{ + NDIMS_DECL + A_DECL(coordp, size_t, ndims, index); + A_INIT(coordp, size_t, ndims, index); + { + const int status = nc_get_var1(ncid, varid, coordp, value); + A_FREE(coordp); + if(status != NC_NOERR) + { + nc_advise("ncdimid", status, "ncid %d", ncid); + return -1; + } + } + return 0; +} + + +int +ncvarput( + int ncid, + int varid, + const long* start, + const long* count, + const void* value +) +{ + NDIMS_DECL + A_DECL(stp, size_t, ndims, start); + A_DECL(cntp, size_t, ndims, count); + A_INIT(stp, size_t, ndims, start); + A_INIT(cntp, size_t, ndims, count); + { + const int status = nc_put_vara(ncid, varid, stp, cntp, value); + A_FREE(cntp); + A_FREE(stp); + if(status != NC_NOERR) + { + nc_advise("ncvarput", status, "ncid %d", ncid); + return -1; + } + } + return 0; +} + + +int +ncvarget( + int ncid, + int varid, + const long* start, + const long* count, + void* value +) +{ + NDIMS_DECL + A_DECL(stp, size_t, ndims, start); + A_DECL(cntp, size_t, ndims, count); + A_INIT(stp, size_t, ndims, start); + A_INIT(cntp, size_t, ndims, count); + { + const int status = nc_get_vara(ncid, varid, stp, cntp, value); + A_FREE(cntp); + A_FREE(stp); + if(status != NC_NOERR) + { + nc_advise("ncvarget", status, "ncid %d; varid %d", ncid, varid); + return -1; + } + } + return 0; +} + + +int +ncvarputs( + int ncid, + int varid, + const long* start, + const long* count, + const long* stride, + const void* value +) +{ + if(stride == NULL) + return ncvarput(ncid, varid, start, count, value); + /* else */ + { + NDIMS_DECL + A_DECL(stp, size_t, ndims, start); + A_DECL(cntp, size_t, ndims, count); + A_DECL(strdp, ptrdiff_t, ndims, stride); + A_INIT(stp, size_t, ndims, start); + A_INIT(cntp, size_t, ndims, count); + A_INIT(strdp, ptrdiff_t, ndims, stride); + { + const int status = nc_put_vars(ncid, varid, stp, cntp, strdp, value); + A_FREE(strdp); + A_FREE(cntp); + A_FREE(stp); + if(status != NC_NOERR) + { + nc_advise("ncvarputs", status, "ncid %d", ncid); + return -1; + } + } + return 0; + } +} + + +int +ncvargets( + int ncid, + int varid, + const long* start, + const long* count, + const long* stride, + void* value +) +{ + if(stride == NULL) + return ncvarget(ncid, varid, start, count, value); + /* else */ + { + NDIMS_DECL + A_DECL(stp, size_t, ndims, start); + A_DECL(cntp, size_t, ndims, count); + A_DECL(strdp, ptrdiff_t, ndims, stride); + A_INIT(stp, size_t, ndims, start); + A_INIT(cntp, size_t, ndims, count); + A_INIT(strdp, ptrdiff_t, ndims, stride); + { + const int status = nc_get_vars(ncid, varid, stp, cntp, strdp, value); + A_FREE(strdp); + A_FREE(cntp); + A_FREE(stp); + if(status != NC_NOERR) + { + nc_advise("ncvargets", status, "ncid %d", ncid); + return -1; + } + } + return 0; + } +} + + +int +ncvarputg( + int ncid, + int varid, + const long* start, + const long* count, + const long* stride, + const long* map, + const void* value +) +{ + if(map == NULL) + return ncvarputs(ncid, varid, start, count, stride, value); + /* else */ + { + NDIMS_DECL + A_DECL(stp, size_t, ndims, start); + A_DECL(cntp, size_t, ndims, count); + A_DECL(strdp, ptrdiff_t, ndims, stride); + A_DECL(imp, ptrdiff_t, ndims, map); + A_INIT(stp, size_t, ndims, start); + A_INIT(cntp, size_t, ndims, count); + A_INIT(strdp, ptrdiff_t, ndims, stride); + A_INIT(imp, ptrdiff_t, ndims, map); + { + const int status = nc_put_varm(ncid, varid, + stp, cntp, strdp, imp, value); + A_FREE(imp); + A_FREE(strdp); + A_FREE(cntp); + A_FREE(stp); + if(status != NC_NOERR) + { + nc_advise("ncvarputg", status, "ncid %d", ncid); + return -1; + } + } + return 0; + } +} + + +int +ncvargetg( + int ncid, + int varid, + const long* start, + const long* count, + const long* stride, + const long* map, + void* value +) +{ + if(map == NULL) + return ncvargets(ncid, varid, start, count, stride, value); + /* else */ + { + NDIMS_DECL + A_DECL(stp, size_t, ndims, start); + A_DECL(cntp, size_t, ndims, count); + A_DECL(strdp, ptrdiff_t, ndims, stride); + A_DECL(imp, ptrdiff_t, ndims, map); + A_INIT(stp, size_t, ndims, start); + A_INIT(cntp, size_t, ndims, count); + A_INIT(strdp, ptrdiff_t, ndims, stride); + A_INIT(imp, ptrdiff_t, ndims, map); + { + const int status = nc_get_varm(ncid, varid, + stp, cntp, strdp, imp, value); + A_FREE(imp); + A_FREE(strdp); + A_FREE(cntp); + A_FREE(stp); + if(status != NC_NOERR) + { + nc_advise("ncvargetg", status, "ncid %d", ncid); + return -1; + } + } + return 0; + } +} + + +int +ncvarrename( + int ncid, + int varid, + const char* name +) +{ + const int status = nc_rename_var(ncid, varid, name); + if(status != NC_NOERR) + { + nc_advise("ncvarrename", status, "ncid %d", ncid); + return -1; + } + return varid; +} + + +int +ncattput( + int ncid, + int varid, + const char* name, + nc_type datatype, + int len, + const void* value +) +{ + const int status = nc_put_att(ncid, varid, name, datatype, len, value); + if(status != NC_NOERR) + { + nc_advise("ncattput", status, "ncid %d", ncid); + return -1; + } + return 0; +} + + +int +ncattinq( + int ncid, + int varid, + const char* name, + nc_type* datatype, + int* len +) +{ + size_t ll; + const int status = nc_inq_att(ncid, varid, name, datatype, &ll); + if(status != NC_NOERR) + { + nc_advise("ncattinq", status, + "ncid %d; varid %d; attname \"%s\"", + ncid, varid, name); + return -1; + } + + if(len != NULL) + *len = (int) ll; + + return 1; + +} + + +int +ncattget( + int ncid, + int varid, + const char* name, + void* value +) +{ + const int status = nc_get_att(ncid, varid, name, value); + if(status != NC_NOERR) + { + nc_advise("ncattget", status, "ncid %d", ncid); + return -1; + } + return 1; +} + + +int +ncattcopy( + int ncid_in, + int varid_in, + const char* name, + int ncid_out, + int varid_out +) +{ + const int status = nc_copy_att(ncid_in, varid_in, name, ncid_out, varid_out); + if(status != NC_NOERR) + { + nc_advise("ncattcopy", status, "%s", name); + return -1; + } + return 0; +} + + +int +ncattname( + int ncid, + int varid, + int attnum, + char* name +) +{ + const int status = nc_inq_attname(ncid, varid, attnum, name); + if(status != NC_NOERR) + { + nc_advise("ncattname", status, "ncid %d", ncid); + return -1; + } + return attnum; +} + + +int +ncattrename( + int ncid, + int varid, + const char* name, + const char* newname +) +{ + const int status = nc_rename_att(ncid, varid, name, newname); + if(status != NC_NOERR) + { + nc_advise("ncattrename", status, "ncid %d", ncid); + return -1; + } + return 1; +} + + +int +ncattdel( + int ncid, + int varid, + const char* name +) +{ + const int status = nc_del_att(ncid, varid, name); + if(status != NC_NOERR) + { + nc_advise("ncattdel", status, "ncid %d", ncid); + return -1; + } + return 1; +} + +#endif /* NO_NETCDF_2 */ + +#ifndef NO_NETCDF_2 + +int +ncsetfill( + int ncid, + int fillmode +) +{ + int oldmode = -1; + const int status = nc_set_fill(ncid, fillmode, &oldmode); + if(status != NC_NOERR) + { + nc_advise("ncsetfill", status, "ncid %d", ncid); + return -1; + } + return oldmode; +} + + +int +ncrecinq( + int ncid, + int* nrecvars, + int* recvarids, + long* recsizes +) +{ + size_t nrv = 0; + size_t rs[NC_MAX_VARS]; /* TODO */ + const int status = nc_inq_rec(ncid, &nrv, recvarids, rs); + if(status != NC_NOERR) + { + nc_advise("ncrecinq", status, "ncid %d", ncid); + return -1; + } + + if(nrecvars != NULL) + *nrecvars = (int) nrv; + + if(recsizes != NULL) + { + size_t ii; + for(ii = 0; ii < nrv; ii++) + { + recsizes[ii] = (long) rs[ii]; + } + } + + return (int) nrv; +} + + +int +ncrecget( + int ncid, + long recnum, + void** datap +) +{ + const int status = nc_get_rec(ncid, (size_t)recnum, datap); + if(status != NC_NOERR) + { + nc_advise("ncrecget", status, "ncid %d", ncid); + return -1; + } + return 0; +} + + +int +ncrecput( + int ncid, + long recnum, + void* const* datap +) +{ + const int status = nc_put_rec(ncid, (size_t)recnum, datap); + if(status != NC_NOERR) + { + nc_advise("ncrecput", status, "ncid %d", ncid); + return -1; + } + return 0; +} + +#endif /* NO_NETCDF_2 */ diff --git a/extern/src_netcdf4/dvar.c b/extern/src_netcdf4/dvar.c new file mode 100644 index 0000000000000000000000000000000000000000..842da9dd2fafe4b6d0b5abd82a824f8180fe7aad --- /dev/null +++ b/extern/src_netcdf4/dvar.c @@ -0,0 +1,585 @@ +/*! \file +Functions for defining and inquiring about variables. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See COPYRIGHT file for more info. +*/ + +#include "ncdispatch.h" +#include "netcdf_f.h" + +/** \defgroup variables Variables + +Variables hold multi-dimensional arrays of data. + +Variables for a netCDF dataset are defined when the dataset is +created, while the netCDF dataset is in define mode. Other variables +may be added later by reentering define mode. A netCDF variable has a +name, a type, and a shape, which are specified when it is defined. A +variable may also have values, which are established later in data +mode. + +Ordinarily, the name, type, and shape are fixed when the variable is +first defined. The name may be changed, but the type and shape of a +variable cannot be changed. However, a variable defined in terms of +the unlimited dimension can grow without bound in that dimension. + +A netCDF variable in an open netCDF dataset is referred to by a small +integer called a variable ID. + +Variable IDs reflect the order in which variables were defined within +a netCDF dataset. Variable IDs are 0, 1, 2,..., in the order in which +the variables were defined. A function is available for getting the +variable ID from the variable name and vice-versa. + +Attributes (see Attributes) may be associated with a variable to +specify such properties as units. + +Operations supported on variables are: +- Create a variable, given its name, data type, and shape. +- Get a variable ID from its name. +- Get a variable's name, data type, shape, and number of attributes + from its ID. +- Put a data value into a variable, given variable ID, indices, and value. +- Put an array of values into a variable, given variable ID, corner + indices, edge lengths, and a block of values. +- Put a subsampled or mapped array-section of values into a variable, + given variable ID, corner indices, edge lengths, stride vector, + index mapping vector, and a block of values. +- Get a data value from a variable, given variable ID and indices. +- Get an array of values from a variable, given variable ID, corner + indices, and edge lengths. +- Get a subsampled or mapped array-section of values from a variable, + given variable ID, corner indices, edge lengths, stride vector, and + index mapping vector. +- Rename a variable. + +\section language_types Language Types Corresponding to netCDF +External Data Types + +NetCDF supported six atomic data types through version 3.6.0 (char, +byte, short, int, float, and double). Starting with version 4.0, many +new atomic and user defined data types are supported (unsigned int +types, strings, compound types, variable length arrays, enums, +opaque). + +The additional data types are only supported in netCDF-4/HDF5 +files. To create netCDF-4/HDF5 files, use the HDF5 flag in +nc_create. (see nc_create). + +\section classic_types NetCDF-3 Classic and 64-Bit Offset Data Types + +NetCDF-3 classic and 64-bit offset files support 6 atomic data types, +and none of the user defined datatype introduced in NetCDF-4. + +The following table gives the netCDF-3 external data types and the +corresponding type constants for defining variables in the C +interface: + + + + + + + + + +
TypeC defineBits
byteNC_BYTE8
charNC_CHAR8
shortNC_SHORT16
intNC_INT32
floatNC_FLOAT32
doubleNC_DOUBLE64
+ +The first column gives the netCDF external data type, which is the +same as the CDL data type. The next column gives the corresponding C +pre-processor macro for use in netCDF functions (the pre-processor +macros are defined in the netCDF C header-file netcdf.h). The last +column gives the number of bits used in the external representation of +values of the corresponding type. + +\section netcdf_4_atomic NetCDF-4 Atomic Types + +NetCDF-4 files support all of the atomic data types from netCDF-3, +plus additional unsigned integer types, 64-bit integer types, and a +string type. + + + + + + + + + + + + + + +
TypeC defineBits + +
byteNC_BYTE8
unsigned byte NC_UBYTE^ 8
char NC_CHAR 8
short NC_SHORT 16
unsigned short NC_USHORT^ 16
int NC_INT 32
unsigned int NC_UINT^ 32
unsigned long long NC_UINT64^ 64
long long NC_INT64^ 64
float NC_FLOAT 32
double NC_DOUBLE 64
char ** NC_STRING^ string length + 1
+ +^This type was introduced in netCDF-4, and is not supported in netCDF +classic or 64-bit offset format files, or in netCDF-4 files if they +are created with the NC_CLASSIC_MODEL flags. + */ + +/** \name Defining Variables + +Use these functions to define variables. + */ +/*! \{ */ + +/** +\ingroup variables +Define a new variable. + +This function adds a new variable to an open netCDF dataset or group. +It returns (as an argument) a variable ID, given the netCDF ID, +the variable name, the variable type, the number of dimensions, and a +list of the dimension IDs. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param name Variable \ref object_name. + +\param xtype \ref data_type of the variable. + +\param ndims Number of dimensions for the variable. For example, 2 +specifies a matrix, 1 specifies a vector, and 0 means the variable is +a scalar with no dimensions. Must not be negative or greater than the +predefined constant ::NC_MAX_VAR_DIMS. + +\param dimidsp Vector of ndims dimension IDs corresponding to the +variable dimensions. For classic model netCDF files, if the ID of the +unlimited dimension is included, it must be first. This argument is +ignored if ndims is 0. For expanded model netCDF4/HDF5 files, there +may be any number of unlimited dimensions, and they may be used in any +element of the dimids array. + +\param varidp Pointer to location for the returned variable ID. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTINDEFINE Not in define mode. +\returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file. +\returns ::NC_EMAXVARS NC_MAX_VARS exceeded +\returns ::NC_EBADTYPE Bad type. +\returns ::NC_EINVAL Invalid input. +\returns ::NC_ENAMEINUSE Name already in use. +\returns ::NC_EPERM Attempt to create object in read-only file. + +\section Example + +Here is an example using nc_def_var to create a variable named rh of +type double with three dimensions, time, lat, and lon in a new netCDF +dataset named foo.nc: + +\code + #include + ... + int status; + int ncid; + int lat_dim, lon_dim, time_dim; + int rh_id; + int rh_dimids[3]; + ... + status = nc_create("foo.nc", NC_NOCLOBBER, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + + status = nc_def_dim(ncid, "lat", 5L, &lat_dim); + if (status != NC_NOERR) handle_error(status); + status = nc_def_dim(ncid, "lon", 10L, &lon_dim); + if (status != NC_NOERR) handle_error(status); + status = nc_def_dim(ncid, "time", NC_UNLIMITED, &time_dim); + if (status != NC_NOERR) handle_error(status); + ... + + rh_dimids[0] = time_dim; + rh_dimids[1] = lat_dim; + rh_dimids[2] = lon_dim; + status = nc_def_var (ncid, "rh", NC_DOUBLE, 3, rh_dimids, &rh_id); + if (status != NC_NOERR) handle_error(status); +\endcode + + */ +int +nc_def_var(int ncid, const char *name, nc_type xtype, + int ndims, const int *dimidsp, int *varidp) +{ + NC* ncp; + int stat = NC_NOERR; + + if ((stat = NC_check_id(ncid, &ncp))) + return stat; + return ncp->dispatch->def_var(ncid, name, xtype, ndims, + dimidsp, varidp); +} +/*! \} */ + +/** \name Rename a Variable + +Rename a variable. + */ +/*! \{ */ + +/** Rename a variable. +\ingroup variables + +This function changes the name of a netCDF variable in an open netCDF +file or group. You cannot rename a variable to have the name of any existing +variable. + +For classic format, 64-bit offset format, and netCDF-4/HDF5 with +classic mode, if the new name is longer than the old name, the netCDF +dataset must be in define mode. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param name New name of the variable. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. +\returns ::NC_EBADNAME Bad name. +\returns ::NC_EMAXNAME Name is too long. +\returns ::NC_ENAMEINUSE Name in use. +\returns ::NC_ENOMEM Out of memory. + +\section Example + +Here is an example using nc_rename_var to rename the variable rh to +rel_hum in an existing netCDF dataset named foo.nc: + +\code + #include + ... + int status; + int ncid; + int rh_id; + ... + status = nc_open("foo.nc", NC_WRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_redef(ncid); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + status = nc_rename_var (ncid, rh_id, "rel_hum"); + if (status != NC_NOERR) handle_error(status); + status = nc_enddef(ncid); + if (status != NC_NOERR) handle_error(status); +\endcode + +*/ +int +nc_rename_var(int ncid, int varid, const char *name) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->rename_var(ncid, varid, name); +} +/*! \} */ + +/** \internal +\ingroup variables + */ +int +NC_is_recvar(int ncid, int varid, size_t* nrecs) +{ + int status = NC_NOERR; + int unlimid; + int ndims; + int dimset[NC_MAX_VAR_DIMS]; + + status = nc_inq_unlimdim(ncid,&unlimid); + if(status != NC_NOERR) return 0; /* no unlimited defined */ + status = nc_inq_varndims(ncid,varid,&ndims); + if(status != NC_NOERR) return 0; /* no unlimited defined */ + if(ndims == 0) return 0; /* scalar */ + status = nc_inq_vardimid(ncid,varid,dimset); + if(status != NC_NOERR) return 0; /* no unlimited defined */ + status = nc_inq_dim(ncid,dimset[0],NULL,nrecs); + if(status != NC_NOERR) return 0; + return (dimset[0] == unlimid ? 1: 0); +} + +/* Ok to use NC pointers because + all IOSP's will use that structure, + but not ok to use e.g. NC_Var pointers + because they may be different structure + entirely. +*/ + +/** \internal +\ingroup variables +Find the length of a type. This is how much space is required by the user, as in +\code +vals = malloc(nel * nctypelen(var.type)); +ncvarget(cdfid, varid, cor, edg, vals); +\endcode + */ +int +nctypelen(nc_type type) +{ + switch(type){ + case NC_CHAR : + return((int)sizeof(char)); + case NC_BYTE : + return((int)sizeof(signed char)); + case NC_SHORT : + return(int)(sizeof(short)); + case NC_INT : + return((int)sizeof(int)); + case NC_FLOAT : + return((int)sizeof(float)); + case NC_DOUBLE : + return((int)sizeof(double)); + + /* These can occur in netcdf-3 code */ + case NC_UBYTE : + return((int)sizeof(unsigned char)); + case NC_USHORT : + return((int)(sizeof(unsigned short))); + case NC_UINT : + return((int)sizeof(unsigned int)); + case NC_INT64 : + return((int)sizeof(signed long long)); + case NC_UINT64 : + return((int)sizeof(unsigned long long)); +#ifdef USE_NETCDF4 + case NC_STRING : + return((int)sizeof(char*)); +#endif /*USE_NETCDF4*/ + + default: + return -1; + } +} + +/** \internal +\ingroup variables +Find the length of a type. Redunant over nctypelen() above. */ +int +NC_atomictypelen(nc_type xtype) +{ + int sz = 0; + switch(xtype) { + case NC_NAT: sz = 0; break; + case NC_BYTE: sz = sizeof(signed char); break; + case NC_CHAR: sz = sizeof(char); break; + case NC_SHORT: sz = sizeof(short); break; + case NC_INT: sz = sizeof(int); break; + case NC_FLOAT: sz = sizeof(float); break; + case NC_DOUBLE: sz = sizeof(double); break; + case NC_INT64: sz = sizeof(signed long long); break; + case NC_UBYTE: sz = sizeof(unsigned char); break; + case NC_USHORT: sz = sizeof(unsigned short); break; + case NC_UINT: sz = sizeof(unsigned int); break; + case NC_UINT64: sz = sizeof(unsigned long long); break; +#ifdef USE_NETCDF4 + case NC_STRING: sz = sizeof(char*); break; +#endif + default: break; + } + return sz; +} + +/** \internal +\ingroup variables + Get the type name. */ +char * +NC_atomictypename(nc_type xtype) +{ + char* nm = NULL; + switch(xtype) { + case NC_NAT: nm = "undefined"; break; + case NC_BYTE: nm = "byte"; break; + case NC_CHAR: nm = "char"; break; + case NC_SHORT: nm = "short"; break; + case NC_INT: nm = "int"; break; + case NC_FLOAT: nm = "float"; break; + case NC_DOUBLE: nm = "double"; break; + case NC_INT64: nm = "int64"; break; + case NC_UBYTE: nm = "ubyte"; break; + case NC_USHORT: nm = "ushort"; break; + case NC_UINT: nm = "uint"; break; + case NC_UINT64: nm = "uint64"; break; +#ifdef USE_NETCDF4 + case NC_STRING: nm = "string"; break; +#endif + default: break; + } + return nm; +} + +/** \internal +\ingroup variables +Get the shape of a variable. + */ +int +NC_getshape(int ncid, int varid, int ndims, size_t* shape) +{ + int dimids[NC_MAX_VAR_DIMS]; + int i; + int status = NC_NOERR; + + if ((status = nc_inq_vardimid(ncid, varid, dimids))) + return status; + for(i = 0; i < ndims; i++) + if ((status = nc_inq_dimlen(ncid, dimids[i], &shape[i]))) + break; + + return status; +} + +#ifdef USE_NETCDF4 +/** \ingroup variables + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param size The total size of the raw data chunk cache, in bytes. + +\param nelems The number of chunk slots in the raw data chunk cache. + +\param preemption The preemption, a value between 0 and 1 inclusive +that indicates how much chunks that have been fully read are favored +for preemption. A value of zero means fully read chunks are treated no +differently than other chunks (the preemption is strictly LRU) while a +value of one means fully read chunks are always preempted before other +chunks. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. +\returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file. +\returns ::NC_EINVAL Invalid input + */ +int +nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, + float preemption) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->set_var_chunk_cache(ncid, varid, size, + nelems, preemption); +} + +/** \ingroup variables + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param sizep The total size of the raw data chunk cache, in bytes, +will be put here. \ref ignored_if_null. + +\param nelemsp The number of chunk slots in the raw data chunk cache +hash table will be put here. \ref ignored_if_null. + +\param preemptionp The preemption will be put here. The preemtion +value is between 0 and 1 inclusive and indicates how much chunks that +have been fully read are favored for preemption. A value of zero means +fully read chunks are treated no differently than other chunks (the +preemption is strictly LRU) while a value of one means fully read +chunks are always preempted before other chunks. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. +\returns ::NC_ESTRICTNC3 Attempting netcdf-4 operation on strict nc3 netcdf-4 file. +\returns ::NC_EINVAL Invalid input +*/ +int +nc_get_var_chunk_cache(int ncid, int varid, size_t *sizep, size_t *nelemsp, + float *preemptionp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_var_chunk_cache(ncid, varid, sizep, + nelemsp, preemptionp); +} + +/** \ingroup variables +Free string space allocated by the library. + +When you read string type the library will allocate the storage space +for the data. This storage space must be freed, so pass the pointer +back to this function, when you're done with the data, and it will +free the string memory. + +\param len The number of character arrays in the array. +\param data The pointer to the data array. + +\returns ::NC_NOERR No error. +*/ +int +nc_free_string(size_t len, char **data) +{ + int i; + for (i = 0; i < len; i++) + free(data[i]); + return NC_NOERR; +} + +int +nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, int deflate_level) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_var_deflate(ncid,varid,shuffle,deflate,deflate_level); +} + +int +nc_def_var_fletcher32(int ncid, int varid, int fletcher32) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_var_fletcher32(ncid,varid,fletcher32); +} + +int +nc_def_var_chunking(int ncid, int varid, int storage, + const size_t *chunksizesp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_var_chunking(ncid, varid, storage, + chunksizesp); +} + +int +nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_var_fill(ncid,varid,no_fill,fill_value); +} + +int +nc_def_var_endian(int ncid, int varid, int endian) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_var_endian(ncid,varid,endian); +} + +#endif /* USE_NETCDF4 */ diff --git a/extern/src_netcdf4/dvarget.c b/extern/src_netcdf4/dvarget.c new file mode 100644 index 0000000000000000000000000000000000000000..3d86f1f450b756e4c7aedfe4e4628475dc87fad3 --- /dev/null +++ b/extern/src_netcdf4/dvarget.c @@ -0,0 +1,1432 @@ +/*! \file +Functions for getting data from variables. + +Copyright 2011 University Corporation for Atmospheric +Research/Unidata. See \ref COPYRIGHT file for more info. */ + +#include "ncdispatch.h" + + +/** \internal +\ingroup variables + + */ +int +NC_get_vara(int ncid, int varid, + const size_t *start, const size_t *edges, + void *value, nc_type memtype) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; +#ifdef USE_NETCDF4 + if(memtype >= NC_FIRSTUSERTYPEID) memtype = NC_NAT; +#endif + if(edges == NULL) { + size_t shape[NC_MAX_VAR_DIMS]; + int ndims; + stat = nc_inq_varndims(ncid, varid, &ndims); + if(stat != NC_NOERR) return stat; + stat = NC_getshape(ncid,varid,ndims,shape); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_vara(ncid,varid,start,shape,value,memtype); + } else + return ncp->dispatch->get_vara(ncid,varid,start,edges,value,memtype); +} + +/** \ingroup variables +\internal + */ +static int +NC_get_var(int ncid, int varid, void *value, nc_type memtype) +{ + int ndims; + size_t shape[NC_MAX_VAR_DIMS]; + int stat = nc_inq_varndims(ncid,varid, &ndims); + if(stat) return stat; + stat = NC_getshape(ncid,varid, ndims, shape); + if(stat) return stat; + return NC_get_vara(ncid, varid, NC_coord_zero, shape, value, memtype); +} + +/** \internal +\ingroup variables + Most dispatch tables will use the default procedures +*/ +int +NCDEFAULT_get_vars(int ncid, int varid, const size_t * start, + const size_t * edges, const ptrdiff_t * stride, + void *value, nc_type memtype) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,NULL,value,memtype); +} + +/** \internal +\ingroup variables + */ +static int +NC_get_var1(int ncid, int varid, const size_t *coord, void* value, + nc_type memtype) +{ + return NC_get_vara(ncid, varid, coord, NC_coord_one, value, memtype); +} + +/** \internal +\ingroup variables + */ +int +NCDEFAULT_get_varm(int ncid, int varid, const size_t *start, + const size_t *edges, const ptrdiff_t *stride, + const ptrdiff_t *imapp, void *value0, nc_type memtype) +{ + int status = NC_NOERR; + nc_type vartype = NC_NAT; + int varndims,maxidim; + NC* ncp; + size_t memtypelen; + ptrdiff_t cvtmap[NC_MAX_VAR_DIMS]; + char* value = (char*)value0; + + status = NC_check_id (ncid, &ncp); + if(status != NC_NOERR) return status; + +/* + if(NC_indef(ncp)) return NC_EINDEFINE; +*/ + + status = nc_inq_vartype(ncid, varid, &vartype); + if(status != NC_NOERR) return status; + /* Check that this is an atomic type */ + if(vartype >= NC_MAX_ATOMIC_TYPE) + return NC_EMAPTYPE; + + status = nc_inq_varndims(ncid, varid, &varndims); + if(status != NC_NOERR) return status; + + if(memtype == NC_NAT) { + if(imapp != NULL && varndims != 0) { + /* + * convert map units from bytes to units of sizeof(type) + */ + size_t ii; + const ptrdiff_t szof = (ptrdiff_t) nctypelen(vartype); + for(ii = 0; ii < varndims; ii++) { + if(imapp[ii] % szof != 0) { + /*free(cvtmap);*/ + return NC_EINVAL; + } + cvtmap[ii] = imapp[ii] / szof; + } + imapp = cvtmap; + } + memtype = vartype; + } + + if(memtype == NC_CHAR && vartype != NC_CHAR) + return NC_ECHAR; + else if(memtype != NC_CHAR && vartype == NC_CHAR) + return NC_ECHAR; + + memtypelen = nctypelen(memtype); + + maxidim = (int) varndims - 1; + + if (maxidim < 0) + { + /* + * The variable is a scalar; consequently, + * there s only one thing to get and only one place to put it. + * (Why was I called?) + */ + size_t edge1[1] = {1}; + return NC_get_vara(ncid, varid, start, edge1, value, memtype); + } + + /* + * else + * The variable is an array. + */ + { + int idim; + size_t *mystart = NULL; + size_t *myedges; + size_t *iocount; /* count vector */ + size_t *stop; /* stop indexes */ + size_t *length; /* edge lengths in bytes */ + ptrdiff_t *mystride; + ptrdiff_t *mymap; + size_t varshape[NC_MAX_VAR_DIMS]; + int isrecvar; + size_t numrecs; + + /* Compute some dimension related values */ + isrecvar = NC_is_recvar(ncid,varid,&numrecs); + NC_getshape(ncid,varid,varndims,varshape); + + /* + * Verify stride argument; also see if stride is all ones + */ + if(stride != NULL) { + int stride1 = 1; + for (idim = 0; idim <= maxidim; ++idim) + { + if (stride[idim] == 0 + /* cast needed for braindead systems with signed size_t */ + || ((unsigned long) stride[idim] >= X_INT_MAX)) + { + return NC_ESTRIDE; + } + if(stride[idim] != 1) stride1 = 0; + } + /* If stride1 is true, and there is no imap + then call get_vara directly. + */ + if(stride1 && imapp == NULL) { + return NC_get_vara(ncid, varid, start, edges, value, memtype); + } + } + + /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ + /* Allocate space for mystart,mystride,mymap etc.all at once */ + mystart = (size_t *)calloc(varndims * 7, sizeof(ptrdiff_t)); + if(mystart == NULL) return NC_ENOMEM; + myedges = mystart + varndims; + iocount = myedges + varndims; + stop = iocount + varndims; + length = stop + varndims; + mystride = (ptrdiff_t *)(length + varndims); + mymap = mystride + varndims; + + /* + * Initialize I/O parameters. + */ + for (idim = maxidim; idim >= 0; --idim) + { + mystart[idim] = start != NULL + ? start[idim] + : 0; + + if (edges != NULL && edges[idim] == 0) + { + status = NC_NOERR; /* read/write no data */ + goto done; + } + +#ifdef COMPLEX + myedges[idim] = edges != NULL + ? edges[idim] + : idim == 0 && isrecvar + ? numrecs - mystart[idim] + : varshape[idim] - mystart[idim]; +#else + if(edges != NULL) + myedges[idim] = edges[idim]; + else if (idim == 0 && isrecvar) + myedges[idim] = numrecs - mystart[idim]; + else + myedges[idim] = varshape[idim] - mystart[idim]; +#endif + + mystride[idim] = stride != NULL + ? stride[idim] + : 1; + + /* Remember: imapp is byte oriented, not index oriented */ +#ifdef COMPLEX + mymap[idim] = (imapp != NULL + ? imapp[idim] + : (idim == maxidim ? 1 + : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1])); +#else + if(imapp != NULL) + mymap[idim] = imapp[idim]; + else if (idim == maxidim) + mymap[idim] = 1; + else + mymap[idim] = + mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; +#endif + iocount[idim] = 1; + length[idim] = mymap[idim] * myedges[idim]; + stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; + } + + /* + * Check start, edges + */ + for (idim = maxidim; idim >= 0; --idim) + { + size_t dimlen = + idim == 0 && isrecvar + ? numrecs + : varshape[idim]; + if (mystart[idim] >= dimlen) + { + status = NC_EINVALCOORDS; + goto done; + } + + if (mystart[idim] + myedges[idim] > dimlen) + { + status = NC_EEDGE; + goto done; + } + + } + + + /* Lower body */ + /* + * As an optimization, adjust I/O parameters when the fastest + * dimension has unity stride both externally and internally. + * In this case, the user could have called a simpler routine + * (i.e. ncvar$1() + */ + if (mystride[maxidim] == 1 + && mymap[maxidim] == 1) + { + iocount[maxidim] = myedges[maxidim]; + mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; + mymap[maxidim] = (ptrdiff_t) length[maxidim]; + } + + /* + * Perform I/O. Exit when done. + */ + for (;;) + { + /* TODO: */ + int lstatus = NC_get_vara(ncid, varid, mystart, iocount, + value, memtype); + if (lstatus != NC_NOERR) { + if(status == NC_NOERR || lstatus != NC_ERANGE) + status = lstatus; + } + /* + * The following code permutes through the variable s + * external start-index space and it s internal address + * space. At the UPC, this algorithm is commonly + * called "odometer code". + */ + idim = maxidim; + carry: + value += (mymap[idim] * memtypelen); + mystart[idim] += mystride[idim]; + if (mystart[idim] == stop[idim]) + { + mystart[idim] = start[idim]; + value -= (length[idim] * memtypelen); + if (--idim < 0) + break; /* normal return */ + goto carry; + } + } /* I/O loop */ + done: + free(mystart); + } /* variable is array */ + return status; +} + +/** \ingroup variables +\internal +Called by externally visible nc_get_vars_xxx routines */ +static int +NC_get_vars(int ncid, int varid, const size_t *start, + const size_t *edges, const ptrdiff_t *stride, void *value, + nc_type memtype) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + + if(stat != NC_NOERR) return stat; +#ifdef USE_NETCDF4 + if(memtype >= NC_FIRSTUSERTYPEID) memtype = NC_NAT; +#endif + return ncp->dispatch->get_vars(ncid,varid,start,edges,stride,value,memtype); +} + +/** \ingroup variables +\internal +Called by externally visible nc_get_varm_xxx routines + */ +static int +NC_get_varm(int ncid, int varid, const size_t *start, + const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t* map, + void *value, nc_type memtype) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + + if(stat != NC_NOERR) return stat; +#ifdef USE_NETCDF4 + if(memtype >= NC_FIRSTUSERTYPEID) memtype = NC_NAT; +#endif + return ncp->dispatch->get_varm(ncid,varid,start,edges,stride,map,value,memtype); +} + +/** \name Reading Data from Variables + +Functions to read data from variables. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/** \ingroup variables +Read an array of values from a variable. + +The array to be read is specified by giving a corner and a vector of +edge lengths to \ref specify_hyperslab. + +The data values are read into consecutive locations with the last +dimension varying fastest. The netCDF dataset must be in data mode +(for netCDF-4/HDF5 files, the switch to data mode will happen +automatically, unless the classic model is used). + +The nc_get_vara() function will read a variable of any type, +including user defined type. For this function, the type of the data +in memory must match the type of the variable - no data conversion is +done. + +Other nc_get_vara_ functions will convert data to the desired output +type as needed. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param startp Start vector with one element for each dimension to \ref +specify_hyperslab. + +\param countp Count vector with one element for each dimension to \ref +specify_hyperslab. + +\param ip Pointer where the data will be copied. Memory must be +allocated by the user before this function is called. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_EEDGE Start+count exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. + +\section Example + +Here is an example using nc_get_vara_double() to read all the values of +the variable named rh from an existing netCDF dataset named +foo.nc. For simplicity in this example, we assume that we know that rh +is dimensioned with time, lat, and lon, and that there are three time +values, five lat values, and ten lon values. + +\code + #include + ... + #define TIMES 3 + #define LATS 5 + #define LONS 10 + int status; + int ncid; + int rh_id; + static size_t start[] = {0, 0, 0}; + static size_t count[] = {TIMES, LATS, LONS}; + double rh_vals[TIMES*LATS*LONS]; + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_get_vara_double(ncid, rh_id, start, count, rh_vals); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +/**@{*/ +int +nc_get_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, void *ip) +{ + NC* ncp = NULL; + nc_type xtype = NC_NAT; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + stat = nc_inq_vartype(ncid, varid, &xtype); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid, varid, startp, countp, ip, xtype); +} + +int +nc_get_vara_text(int ncid, int varid, const size_t *startp, + const size_t *countp, char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid, varid, startp, countp, + (void *)ip, NC_CHAR); +} + +int +nc_get_vara_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, signed char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid, varid, startp, countp, + (void *)ip, NC_BYTE); +} + +int +nc_get_vara_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid, varid, startp, countp, + (void *)ip, T_uchar); +} + +int +nc_get_vara_short(int ncid, int varid, const size_t *startp, + const size_t *countp, short *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid, varid, startp, countp, + (void *)ip, NC_SHORT); +} + +int +nc_get_vara_int(int ncid, int varid, + const size_t *startp, const size_t *countp, int *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_INT); +} + +int +nc_get_vara_long(int ncid, int varid, + const size_t *startp, const size_t *countp, long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_long); +} + +int +nc_get_vara_float(int ncid, int varid, + const size_t *startp, const size_t *countp, float *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_float); +} + + +int +nc_get_vara_double(int ncid, int varid, const size_t *startp, + const size_t *countp, double *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_double); +} + +int +nc_get_vara_ubyte(int ncid, int varid, + const size_t *startp, const size_t *countp, unsigned char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_ubyte); +} + +int +nc_get_vara_ushort(int ncid, int varid, + const size_t *startp, const size_t *countp, unsigned short *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_ushort); +} + +int +nc_get_vara_uint(int ncid, int varid, + const size_t *startp, const size_t *countp, unsigned int *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_uint); +} + +int +nc_get_vara_longlong(int ncid, int varid, + const size_t *startp, const size_t *countp, long long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,T_longlong); +} + +int +nc_get_vara_ulonglong(int ncid, int varid, + const size_t *startp, const size_t *countp, unsigned long long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_get_vara_string(int ncid, int varid, + const size_t *startp, const size_t *countp, char* *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vara(ncid,varid,startp,countp, (void *)ip,NC_STRING); +} + +#endif /*USE_NETCDF4*/ +/**@}*/ + +/** \ingroup variables +Read a single datum from a variable. + +Inputs are the netCDF ID, the variable ID, a multidimensional index +that specifies which value to get, and the address of a location into +which the data value will be read. The value is converted from the +external data type of the variable, if necessary. + +The nc_get_var1() function will read a variable of any type, including +user defined type. For this function, the type of the data in memory +must match the type of the variable - no data conversion is done. + +Other nc_get_var1_ functions will convert data to the desired output +type as needed. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param indexp Index vector with one element for each dimension. + +\param ip Pointer where the data will be copied. Memory must be +allocated by the user before this function is called. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. +*/ +/** \{ */ +int +nc_get_var1(int ncid, int varid, const size_t *indexp, void *ip) +{ + return NC_get_var1(ncid, varid, indexp, ip, NC_NAT); +} + +int +nc_get_var1_text(int ncid, int varid, const size_t *indexp, char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_CHAR); +} + +int +nc_get_var1_schar(int ncid, int varid, const size_t *indexp, signed char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_BYTE); +} + +int +nc_get_var1_uchar(int ncid, int varid, const size_t *indexp, unsigned char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UBYTE); +} + +int +nc_get_var1_short(int ncid, int varid, const size_t *indexp, short *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_SHORT); +} + +int +nc_get_var1_int(int ncid, int varid, const size_t *indexp, int *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_INT); +} + +int +nc_get_var1_long(int ncid, int varid, const size_t *indexp, + long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, longtype); +} + +int +nc_get_var1_float(int ncid, int varid, const size_t *indexp, + float *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_FLOAT); +} + +int +nc_get_var1_double(int ncid, int varid, const size_t *indexp, + double *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_DOUBLE); +} + +int +nc_get_var1_ubyte(int ncid, int varid, const size_t *indexp, + unsigned char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UBYTE); +} + +int +nc_get_var1_ushort(int ncid, int varid, const size_t *indexp, + unsigned short *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_USHORT); +} + +int +nc_get_var1_uint(int ncid, int varid, const size_t *indexp, + unsigned int *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_INT); +} + +int +nc_get_var1_longlong(int ncid, int varid, const size_t *indexp, + long long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_INT64); +} + +int +nc_get_var1_ulonglong(int ncid, int varid, const size_t *indexp, + unsigned long long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_get_var1_string(int ncid, int varid, const size_t *indexp, char* *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var1(ncid, varid, indexp, (void *)ip, NC_STRING); +} +#endif /*USE_NETCDF4*/ +/** \} */ + +/** \ingroup variables +Read an entire variable in one call. + +This function will read all the values from a netCDF variable of an +open netCDF dataset. + +This is the simplest interface to use for reading the value of a +scalar variable or when all the values of a multidimensional variable +can be read at once. The values are read into consecutive locations +with the last dimension varying fastest. The netCDF dataset must be in +data mode. + +Take care when using this function with record variables (variables +that use the ::NC_UNLIMITED dimension). If you try to read all the +values of a record variable into an array but there are more records +in the file than you assume, more data will be read than you expect, +which may cause a segmentation violation. To avoid such problems, it +is better to use the nc_get_vara interfaces for variables that use the +::NC_UNLIMITED dimension. + +The functions for types ubyte, ushort, uint, longlong, ulonglong, and +string are only available for netCDF-4/HDF5 files. + +The nc_get_var() function will read a variable of any type, including +user defined type. For this function, the type of the data in memory +must match the type of the variable - no data conversion is done. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param ip Pointer where the data will be copied. Memory must be +allocated by the user before this function is called. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. +*/ +/** \{ */ +int +nc_get_var(int ncid, int varid, void *ip) +{ + return NC_get_var(ncid, varid, ip, NC_NAT); +} + +int +nc_get_var_text(int ncid, int varid, char *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid, varid, (void *)ip, NC_CHAR); +} + +int +nc_get_var_schar(int ncid, int varid, signed char *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid, varid, (void *)ip, NC_BYTE); +} + +int +nc_get_var_uchar(int ncid, int varid, unsigned char *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, NC_UBYTE); +} + +int +nc_get_var_short(int ncid, int varid, short *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid, varid, (void *)ip, NC_SHORT); +} + +int +nc_get_var_int(int ncid, int varid, int *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, NC_INT); +} + +int +nc_get_var_long(int ncid, int varid, long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, longtype); +} + +int +nc_get_var_float(int ncid, int varid, float *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, NC_FLOAT); +} + +int +nc_get_var_double(int ncid, int varid, double *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, NC_DOUBLE); +} + +int +nc_get_var_ubyte(int ncid, int varid, unsigned char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, NC_UBYTE); +} + +int +nc_get_var_ushort(int ncid, int varid, unsigned short *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, NC_USHORT); +} + +int +nc_get_var_uint(int ncid, int varid, unsigned int *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, NC_UINT); +} + +int +nc_get_var_longlong(int ncid, int varid, long long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip, NC_INT64); +} + +int +nc_get_var_ulonglong(int ncid, int varid, unsigned long long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip,NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_get_var_string(int ncid, int varid, char* *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_var(ncid,varid, (void *)ip,NC_STRING); +} +#endif /*USE_NETCDF4*/ +/** \} */ + +/** \ingroup variables +Read a strided array from a variable. + +This function reads a subsampled (strided) array section of values +from a netCDF variable of an open netCDF dataset. The subsampled array +section is specified by giving a corner, a vector of edge lengths, and +a stride vector. The values are read with the last dimension of the +netCDF variable varying fastest. The netCDF dataset must be in data +mode. + +The nc_get_vars() function will read a variable of any type, including +user defined type. For this function, the type of the data in memory +must match the type of the variable - no data conversion is done. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param startp Start vector with one element for each dimension to \ref +specify_hyperslab. + +\param countp Count vector with one element for each dimension to \ref +specify_hyperslab. + +\param stridep Stride vector with one element for each dimension to +\ref specify_hyperslab. + +\param ip Pointer where the data will be copied. Memory must be +allocated by the user before this function is called. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. +*/ +/** \{ */ +int +nc_get_vars (int ncid, int varid, const size_t * startp, + const size_t * countp, const ptrdiff_t * stridep, + void *ip) +{ + NC* ncp; + int stat = NC_NOERR; + + if ((stat = NC_check_id(ncid, &ncp))) + return stat; + return ncp->dispatch->get_vars(ncid, varid, startp, countp, stridep, + ip, NC_NAT); +} + +int +nc_get_vars_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, NC_CHAR); +} + +int +nc_get_vars_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + signed char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, NC_BYTE); +} + +int +nc_get_vars_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + unsigned char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, T_uchar); +} + +int +nc_get_vars_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + short *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, NC_SHORT); +} + +int +nc_get_vars_int(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + int *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, NC_INT); +} + +int +nc_get_vars_long(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, T_long); +} + +int +nc_get_vars_float(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + float *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, T_float); +} + +int +nc_get_vars_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + double *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, T_double); +} + +int +nc_get_vars_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + unsigned char *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid, startp, countp, stridep, + (void *)ip, T_ubyte); +} + +int +nc_get_vars_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + unsigned short *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp,countp, stridep, + (void *)ip, T_ushort); +} + +int +nc_get_vars_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + unsigned int *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid,varid,startp, countp, stridep, + (void *)ip, T_uint); +} + +int +nc_get_vars_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + long long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid, varid, startp, countp, stridep, + (void *)ip, T_longlong); +} + +int +nc_get_vars_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t * stridep, + unsigned long long *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid, varid, startp, countp, stridep, + (void *)ip, NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_get_vars_string(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t * stridep, + char* *ip) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_vars(ncid, varid, startp, countp, stridep, + (void *)ip, NC_STRING); +} +#endif /*USE_NETCDF4*/ +/** \} */ + +/** \ingroup variables +Read a mapped array from a variable. + +The nc_get_varm_ type family of functions reads a mapped array section +of values from a netCDF variable of an open netCDF dataset. The mapped +array section is specified by giving a corner, a vector of edge +lengths, a stride vector, and an index mapping vector. The index +mapping vector is a vector of integers that specifies the mapping +between the dimensions of a netCDF variable and the in-memory +structure of the internal data array. No assumptions are made about +the ordering or length of the dimensions of the data array. The netCDF +dataset must be in data mode. + +The functions for types ubyte, ushort, uint, longlong, ulonglong, and +string are only available for netCDF-4/HDF5 files. + +The nc_get_varm() function will read a variable of any type, including +user defined type. For this function, the type of the data in memory +must match the type of the variable - no data conversion is done. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param startp Start vector with one element for each dimension to \ref +specify_hyperslab. + +\param countp Count vector with one element for each dimension to \ref +specify_hyperslab. + +\param stridep Stride vector with one element for each dimension to +\ref specify_hyperslab. + +\param imapp Mapping vector with one element for each dimension to +\ref specify_hyperslab. + +\param ip Pointer where the data will be copied. Memory must be +allocated by the user before this function is called. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. +*/ +/** \{ */ +int +nc_get_varm(int ncid, int varid, const size_t * startp, + const size_t * countp, const ptrdiff_t * stridep, + const ptrdiff_t * imapp, void *ip) +{ + NC* ncp; + int stat = NC_NOERR; + + if ((stat = NC_check_id(ncid, &ncp))) + return stat; + return ncp->dispatch->get_varm(ncid, varid, startp, countp, + stridep, imapp, ip, NC_NAT); +} + +int +nc_get_varm_schar(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const ptrdiff_t *imapp, signed char *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid, varid, startp, countp, + stridep, imapp, (void *)ip, NC_BYTE); +} + +int +nc_get_varm_uchar(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + unsigned char *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_uchar); +} + +int +nc_get_varm_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, short *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,NC_SHORT); +} + +int +nc_get_varm_int(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + int *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,NC_INT); +} + +int +nc_get_varm_long(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + long *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_long); +} + +int +nc_get_varm_float(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + float *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_float); +} + +int +nc_get_varm_double(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + double *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid,varid,startp,countp,stridep,imapp, (void *)ip,T_double); +} + +int +nc_get_varm_ubyte(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + unsigned char *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid,varid,startp,countp,stridep, + imapp, (void *)ip, T_ubyte); +} + +int +nc_get_varm_ushort(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + unsigned short *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid, varid, startp, countp, stridep, + imapp, (void *)ip, T_ushort); +} + +int +nc_get_varm_uint(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + unsigned int *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid, varid, startp, countp, + stridep, imapp, (void *)ip, T_uint); +} + +int +nc_get_varm_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, long long *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)ip, T_longlong); +} + +int +nc_get_varm_ulonglong(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + unsigned long long *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)ip, NC_UINT64); +} + +int +nc_get_varm_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, char *ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)ip, NC_CHAR); +} + +#ifdef USE_NETCDF4 +int +nc_get_varm_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, char **ip) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_get_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)ip, NC_STRING); +} +/** \} */ +#endif /*USE_NETCDF4*/ + +/*! \} */ /* End of named group... */ + diff --git a/extern/src_netcdf4/dvarinq.c b/extern/src_netcdf4/dvarinq.c new file mode 100644 index 0000000000000000000000000000000000000000..3f94770e7a72fbe3925c9fe2c8cbcec64a6fccc2 --- /dev/null +++ b/extern/src_netcdf4/dvarinq.c @@ -0,0 +1,573 @@ +/*! \file +Functions for inquiring about variables. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See COPYRIGHT file for more info. +*/ + +#include "ncdispatch.h" + +/** \name Learning about Variables + +Functions to learn about the variables in a file. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/** +\ingroup variables +Find the ID of a variable, from the name. + +The function nc_inq_varid returns the ID of a netCDF variable, given +its name. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param name Name of the variable. + +\param varidp Pointer to location for returned variable ID. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. + +\section Example + +Here is an example using nc_inq_varid to find out the ID of a variable +named rh in an existing netCDF dataset named foo.nc: + +\code + #include + ... + int status, ncid, rh_id; + ... + status = nc_open("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); +\endcode + */ +int +nc_inq_varid(int ncid, const char *name, int *varidp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_varid(ncid, name, varidp); +} + +/** +\ingroup variables +Learn about a variable. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param name Returned \ref object_name of variable. \ref +ignored_if_null. + +\param xtypep Pointer where typeid will be stored. \ref ignored_if_null. + +\param ndimsp Pointer where number of dimensions will be +stored. \ref ignored_if_null. + +\param dimidsp Pointer where array of dimension IDs will be +stored. \ref ignored_if_null. + +\param nattsp Pointer where number of attributes will be +stored. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. + +\section Example + +Here is an example using nc_inq_var() to find out about a variable named +rh in an existing netCDF dataset named foo.nc: + +\code + #include + ... + int status + int ncid; + int rh_id; + nc_type rh_type; + int rh_ndims; + int rh_dimids[NC_MAX_VAR_DIMS]; + int rh_natts + ... + status = nc_open ("foo.nc", NC_NOWRITE, &ncid); + if (status != NC_NOERR) handle_error(status); + ... + status = nc_inq_varid (ncid, "rh", &rh_id); + if (status != NC_NOERR) handle_error(status); + status = nc_inq_var (ncid, rh_id, 0, &rh_type, &rh_ndims, rh_dimids, + &rh_natts); + if (status != NC_NOERR) handle_error(status); +\endcode + + */ +int +nc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_var_all(ncid, varid, name, xtypep, ndimsp, + dimidsp, nattsp, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +} + +/** +\ingroup variables +Learn the name of a variable. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param name Returned variable name. The caller must allocate space for +the returned name. The maximum length is ::NC_MAX_NAME. Ignored if +NULL. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. + */ +int +nc_inq_varname(int ncid, int varid, char *name) +{ + return nc_inq_var(ncid, varid, name, NULL, NULL, + NULL, NULL); +} + +/** Learn the type of a variable. +\ingroup variables + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param typep Pointer where typeid will be stored. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. + */ +int +nc_inq_vartype(int ncid, int varid, nc_type *typep) +{ + return nc_inq_var(ncid, varid, NULL, typep, NULL, + NULL, NULL); +} + +/** Learn how many dimensions are associated with a variable. +\ingroup variables + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param ndimsp Pointer where number of dimensions will be +stored. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. + */ +int +nc_inq_varndims(int ncid, int varid, int *ndimsp) +{ + return nc_inq_var(ncid, varid, NULL, NULL, ndimsp, NULL, NULL); +} + +/** Learn the dimension IDs associated with a variable. +\ingroup variables + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param dimidsp Pointer where array of dimension IDs will be +stored. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. + */ +int +nc_inq_vardimid(int ncid, int varid, int *dimidsp) +{ + return nc_inq_var(ncid, varid, NULL, NULL, NULL, + dimidsp, NULL); +} + +/** Learn how many attributes are associated with a variable. +\ingroup variables + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param nattsp Pointer where number of attributes will be +stored. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. + */ +int +nc_inq_varnatts(int ncid, int varid, int *nattsp) +{ + if (varid == NC_GLOBAL) + return nc_inq_natts(ncid,nattsp); + /*else*/ + return nc_inq_var(ncid, varid, NULL, NULL, NULL, NULL, + nattsp); +} + +#ifdef USE_NETCDF4 +/** \ingroup variables +Learn the storage and deflate settings for a variable. + +This is a wrapper for nc_inq_var_all(). + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param shufflep A 1 will be written here if the shuffle filter is +turned on for this variable, and a 0 otherwise. \ref ignored_if_null. + +\param deflatep If this pointer is non-NULL, the nc_inq_var_deflate +function will write a 1 if the deflate filter is turned on for this +variable, and a 0 otherwise. \ref ignored_if_null. + +\param deflate_levelp If the deflate filter is in use for this +variable, the deflate_level will be writen here. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTNC4 Not a netCDF-4 file. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. +*/ +int +nc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep, + int *deflate_levelp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_var_all( + ncid, varid, + NULL, /*name*/ + NULL, /*xtypep*/ + NULL, /*ndimsp*/ + NULL, /*dimidsp*/ + NULL, /*nattsp*/ + shufflep, /*shufflep*/ + deflatep, /*deflatep*/ + deflate_levelp, /*deflatelevelp*/ + NULL, /*fletcher32p*/ + NULL, /*contiguousp*/ + NULL, /*chunksizep*/ + NULL, /*nofillp*/ + NULL, /*fillvaluep*/ + NULL, /*endianp*/ + NULL, /*optionsmaskp*/ + NULL /*pixelsp*/ + ); +} + +/** \ingroup variables +Learn the szip settings of a variable. + +This function returns the szip settings for a variable. NetCDF does +not allow variables to be created with szip (due to license problems +with the szip library), but we do enable read-only access of HDF5 +files with szip compression. + +This is a wrapper for nc_inq_var_all(). + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param options_maskp The szip options mask will be copied to this +pointer. \ref ignored_if_null. + +\param pixels_per_blockp The szip pixels per block will be copied +here. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTNC4 Not a netCDF-4 file. +\returns ::NC_ENOTVAR Invalid variable ID. +*/ +int +nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_var_all( + ncid, varid, + NULL, /*name*/ + NULL, /*xtypep*/ + NULL, /*ndimsp*/ + NULL, /*dimidsp*/ + NULL, /*nattsp*/ + NULL, /*shufflep*/ + NULL, /*deflatep*/ + NULL, /*deflatelevelp*/ + NULL, /*fletcher32p*/ + NULL, /*contiguousp*/ + NULL, /*chunksizep*/ + NULL, /*nofillp*/ + NULL, /*fillvaluep*/ + NULL, /*endianp*/ + options_maskp, /*optionsmaskp*/ + pixels_per_blockp /*pixelsp*/ + ); +} + +/** \ingroup variables +Learn the checksum settings for a variable. + +This is a wrapper for nc_inq_var_all(). + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param fletcher32p Will be set to ::NC_FLETCHER32 if the fletcher32 +checksum filter is turned on for this variable, and ::NC_NOCHECKSUM if +it is not. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTNC4 Not a netCDF-4 file. +\returns ::NC_ENOTVAR Invalid variable ID. +*/ +int +nc_inq_var_fletcher32(int ncid, int varid, int *fletcher32p) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_var_all( + ncid, varid, + NULL, /*name*/ + NULL, /*xtypep*/ + NULL, /*ndimsp*/ + NULL, /*dimidsp*/ + NULL, /*nattsp*/ + NULL, /*shufflep*/ + NULL, /*deflatep*/ + NULL, /*deflatelevelp*/ + fletcher32p, /*fletcher32p*/ + NULL, /*contiguousp*/ + NULL, /*chunksizep*/ + NULL, /*nofillp*/ + NULL, /*fillvaluep*/ + NULL, /*endianp*/ + NULL, /*optionsmaskp*/ + NULL /*pixelsp*/ + ); +} + +/** \ingroup variables + +This is a wrapper for nc_inq_var_all(). + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param storagep Address of returned storage property, returned as +::NC_CONTIGUOUS if this variable uses contiguous storage, or +::NC_CHUNKED if it uses chunked storage. \ref ignored_if_null. + +\param chunksizesp The chunksizes will be copied here. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTNC4 Not a netCDF-4 file. +\returns ::NC_ENOTVAR Invalid variable ID. +*/ +int +nc_inq_var_chunking(int ncid, int varid, int *storagep, size_t *chunksizesp) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_var_all(ncid, varid, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, storagep, + chunksizesp, NULL, NULL, NULL, NULL, NULL); +} + +/** \ingroup variables +Learn the fill mode of a variable. + +The fill mode of a variable is set by nc_def_var_fill(). + +This is a wrapper for nc_inq_var_all(). + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param no_fill Pointer to an integer which will get a 1 if no_fill +mode is set for this variable. \ref ignored_if_null. + +\param fill_valuep A pointer which will get the fill value for this +variable. \ref ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. +*/ +int +nc_inq_var_fill(int ncid, int varid, int *no_fill, void *fill_valuep) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_var_all( + ncid, varid, + NULL, /*name*/ + NULL, /*xtypep*/ + NULL, /*ndimsp*/ + NULL, /*dimidsp*/ + NULL, /*nattsp*/ + NULL, /*shufflep*/ + NULL, /*deflatep*/ + NULL, /*deflatelevelp*/ + NULL, /*fletcher32p*/ + NULL, /*contiguousp*/ + NULL, /*chunksizep*/ + no_fill, /*nofillp*/ + fill_valuep, /*fillvaluep*/ + NULL, /*endianp*/ + NULL, /*optionsmaskp*/ + NULL /*pixelsp*/ + ); +} + +/** \ingroup variables +Find the endianness of a variable. + +This is a wrapper for nc_inq_var_all(). + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param endianp Storage which will get ::NC_ENDIAN_LITTLE if this +variable is stored in little-endian format, ::NC_ENDIAN_BIG if it is +stored in big-endian format, and ::NC_ENDIAN_NATIVE if the endianness +is not set, and the variable is not created yet. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTNC4 Not a netCDF-4 file. +\returns ::NC_EBADID Bad ncid. +\returns ::NC_ENOTVAR Invalid variable ID. +*/ +int +nc_inq_var_endian(int ncid, int varid, int *endianp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_var_all( + ncid, varid, + NULL, /*name*/ + NULL, /*xtypep*/ + NULL, /*ndimsp*/ + NULL, /*dimidsp*/ + NULL, /*nattsp*/ + NULL, /*shufflep*/ + NULL, /*deflatep*/ + NULL, /*deflatelevelp*/ + NULL, /*fletcher32p*/ + NULL, /*contiguousp*/ + NULL, /*chunksizep*/ + NULL, /*nofillp*/ + NULL, /*fillvaluep*/ + endianp, /*endianp*/ + NULL, /*optionsmaskp*/ + NULL /*pixelsp*/ + ); +} + +/** Return number and list of unlimited dimensions. + +In netCDF-4 files, it's possible to have multiple unlimited +dimensions. This function returns a list of the unlimited dimension +ids visible in a group. + +Dimensions are visible in a group if they have been defined in that +group, or any ancestor group. + +ncid + NetCDF group ID, from a previous call to nc_open, nc_create, nc_def_grp, etc. +nunlimdimsp + A pointer to an int which will get the number of visible unlimited dimensions. Ignored if NULL. +unlimdimidsp + A pointer to an already allocated array of int which will get the ids of all visible unlimited dimensions. Ignored if NULL. To allocate the correct length for this array, call nc_inq_unlimdims with a NULL for this parameter and use the nunlimdimsp parameter to get the number of visible unlimited dimensions. + +Errors + +NC_NOERR + No error. +NC_EBADID + Bad group id. +NC_ENOTNC4 + Attempting a netCDF-4 operation on a netCDF-3 file. NetCDF-4 operations can only be performed on files defined with a create mode which includes flag HDF5. (see nc_open). +NC_ESTRICTNC3 + This file was created with the strict netcdf-3 flag, therefore netcdf-4 operations are not allowed. (see nc_open). +NC_EHDFERR + An error was reported by the HDF5 layer. + + */ +int +nc_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->inq_unlimdims(ncid, nunlimdimsp, + unlimdimidsp); +} + +#endif /* USE_NETCDF4 */ +/*! \} */ /* End of named group ...*/ diff --git a/extern/src_netcdf4/dvarput.c b/extern/src_netcdf4/dvarput.c new file mode 100644 index 0000000000000000000000000000000000000000..bb18c4a096308690168c765dd51057a74a1ed25c --- /dev/null +++ b/extern/src_netcdf4/dvarput.c @@ -0,0 +1,1358 @@ +/*! \file +Functions for writing data to variables. + +Copyright 2010 University Corporation for Atmospheric +Research/Unidata. See COPYRIGHT file for more info. +*/ + +#include "ncdispatch.h" + +/** \internal +\ingroup variables +*/ +static int +NC_put_vara(int ncid, int varid, const size_t *start, + const size_t *edges, const void *value, nc_type memtype) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + if(edges == NULL) { + size_t shape[NC_MAX_VAR_DIMS]; + int ndims; + stat = nc_inq_varndims(ncid, varid, &ndims); + if(stat != NC_NOERR) return stat; + stat = NC_getshape(ncid, varid, ndims, shape); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_vara(ncid, varid, start, shape, value, memtype); + } else + return ncp->dispatch->put_vara(ncid, varid, start, edges, value, memtype); +} + +/** \internal +\ingroup variables +*/ +static int +NC_put_var(int ncid, int varid, const void *value, nc_type memtype) +{ + int ndims; + size_t shape[NC_MAX_VAR_DIMS]; + int stat = nc_inq_varndims(ncid,varid, &ndims); + if(stat) return stat; + stat = NC_getshape(ncid,varid, ndims, shape); + if(stat) return stat; + return NC_put_vara(ncid, varid, NC_coord_zero, shape, value, memtype); +} + +/** \internal +\ingroup variables +*/ +static int +NC_put_var1(int ncid, int varid, const size_t *coord, const void* value, + nc_type memtype) +{ + return NC_put_vara(ncid, varid, coord, NC_coord_one, value, memtype); +} + +/** \internal +\ingroup variables +*/ +int +NCDEFAULT_put_vars(int ncid, int varid, const size_t * start, + const size_t * edges, const ptrdiff_t * stride, + const void *value, nc_type memtype) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_varm(ncid,varid,start,edges,stride,NULL,value,memtype); +} + +/** \internal +\ingroup variables +*/ +int +NCDEFAULT_put_varm( + int ncid, + int varid, + const size_t * start, + const size_t * edges, + const ptrdiff_t * stride, + const ptrdiff_t * imapp, + const void *value0, + nc_type memtype) +{ + int status = NC_NOERR; + nc_type vartype = NC_NAT; + int varndims = 0; + int maxidim = 0; + NC* ncp; + size_t memtypelen; + ptrdiff_t cvtmap[NC_MAX_VAR_DIMS]; + const char* value = (char*)value0; + + status = NC_check_id (ncid, &ncp); + if(status != NC_NOERR) return status; + +/* + if(NC_indef(ncp)) return NC_EINDEFINE; + if(NC_readonly (ncp)) return NC_EPERM; +*/ + + /* mid body */ + status = nc_inq_vartype(ncid, varid, &vartype); + if(status != NC_NOERR) return status; + /* Check that this is an atomic type */ + if(vartype >= NC_MAX_ATOMIC_TYPE) + return NC_EMAPTYPE; + + status = nc_inq_varndims(ncid, varid, &varndims); + if(status != NC_NOERR) return status; + + if(memtype == NC_NAT) { + if(imapp != NULL && varndims != 0) { + /* + * convert map units from bytes to units of sizeof(type) + */ + size_t ii; + const ptrdiff_t szof = (ptrdiff_t) nctypelen(vartype); + for(ii = 0; ii < varndims; ii++) { + if(imapp[ii] % szof != 0) { + /*free(cvtmap);*/ + return NC_EINVAL; + } + cvtmap[ii] = imapp[ii] / szof; + } + imapp = cvtmap; + } + memtype = vartype; + } + + if(memtype == NC_CHAR && vartype != NC_CHAR) + return NC_ECHAR; + else if(memtype != NC_CHAR && vartype == NC_CHAR) + return NC_ECHAR; + + memtypelen = nctypelen(memtype); + + maxidim = (int) varndims - 1; + + if (maxidim < 0) + { + /* + * The variable is a scalar; consequently, + * there s only one thing to get and only one place to put it. + * (Why was I called?) + */ + size_t edge1[1] = {1}; + return NC_put_vara(ncid, varid, start, edge1, value, memtype); + } + + /* + * else + * The variable is an array. + */ + { + int idim; + size_t *mystart = NULL; + size_t *myedges; + size_t *iocount; /* count vector */ + size_t *stop; /* stop indexes */ + size_t *length; /* edge lengths in bytes */ + ptrdiff_t *mystride; + ptrdiff_t *mymap; + size_t varshape[NC_MAX_VAR_DIMS]; + int isrecvar; + size_t numrecs; + int stride1; /* is stride all ones? */ + + /* + * Verify stride argument. + */ + stride1 = 1; /* assume ok; */ + if(stride != NULL) { + for (idim = 0; idim <= maxidim; ++idim) { + if ((stride[idim] == 0) + /* cast needed for braindead systems with signed size_t */ + || ((unsigned long) stride[idim] >= X_INT_MAX)) + { + return NC_ESTRIDE; + } + if(stride[idim] != 1) stride1 = 0; + } + } + + /* If stride1 is true, and there is no imap, then call get_vara + directly + */ + if(stride1 && imapp == NULL) { + return NC_put_vara(ncid, varid, start, edges, value, memtype); + } + + /* Compute some dimension related values */ + isrecvar = NC_is_recvar(ncid,varid,&numrecs); + NC_getshape(ncid,varid,varndims,varshape); + + /* assert(sizeof(ptrdiff_t) >= sizeof(size_t)); */ + mystart = (size_t *)calloc(varndims * 7, sizeof(ptrdiff_t)); + if(mystart == NULL) return NC_ENOMEM; + myedges = mystart + varndims; + iocount = myedges + varndims; + stop = iocount + varndims; + length = stop + varndims; + mystride = (ptrdiff_t *)(length + varndims); + mymap = mystride + varndims; + + /* + * Initialize I/O parameters. + */ + for (idim = maxidim; idim >= 0; --idim) + { + mystart[idim] = start != NULL + ? start[idim] + : 0; + + if (edges != NULL && edges[idim] == 0) + { + status = NC_NOERR; /* read/write no data */ + goto done; + } + + myedges[idim] = edges != NULL + ? edges[idim] + : idim == 0 && isrecvar + ? numrecs - mystart[idim] + : varshape[idim] - mystart[idim]; + mystride[idim] = stride != NULL + ? stride[idim] + : 1; + mymap[idim] = imapp != NULL + ? imapp[idim] + : idim == maxidim + ? 1 + : mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; + + iocount[idim] = 1; + length[idim] = mymap[idim] * myedges[idim]; + stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; + } + + /* + * Check start, edges + */ + for (idim = isrecvar; idim < maxidim; ++idim) + { + if (mystart[idim] > varshape[idim]) + { + status = NC_EINVALCOORDS; + goto done; + } + if (mystart[idim] + myedges[idim] > varshape[idim]) + { + status = NC_EEDGE; + goto done; + } + } + + /* Lower body */ + /* + * As an optimization, adjust I/O parameters when the fastest + * dimension has unity stride both externally and internally. + * In this case, the user could have called a simpler routine + * (i.e. ncvar$1() + */ + if (mystride[maxidim] == 1 + && mymap[maxidim] == 1) + { + iocount[maxidim] = myedges[maxidim]; + mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; + mymap[maxidim] = (ptrdiff_t) length[maxidim]; + } + + /* + * Perform I/O. Exit when done. + */ + for (;;) + { + /* TODO: */ + int lstatus = NC_put_vara(ncid, varid, mystart, iocount, + value, memtype); + if (lstatus != NC_NOERR) { + if(status == NC_NOERR || lstatus != NC_ERANGE) + status = lstatus; + } + + /* + * The following code permutes through the variable s + * external start-index space and it s internal address + * space. At the UPC, this algorithm is commonly + * called "odometer code". + */ + idim = maxidim; + carry: + value += (mymap[idim] * memtypelen); + mystart[idim] += mystride[idim]; + if (mystart[idim] == stop[idim]) + { + mystart[idim] = start[idim]; + value -= (length[idim] * memtypelen); + if (--idim < 0) + break; /* normal return */ + goto carry; + } + } /* I/O loop */ + done: + free(mystart); + } /* variable is array */ + return status; +} + +/** \internal +\ingroup variables +*/ +static int +NC_put_vars(int ncid, int varid, const size_t *start, + const size_t *edges, const ptrdiff_t *stride, + const void *value, nc_type memtype) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + + if(stat != NC_NOERR) return stat; +#ifdef USE_NETCDF4 + if(memtype >= NC_FIRSTUSERTYPEID) memtype = NC_NAT; +#endif + return ncp->dispatch->put_vars(ncid,varid,start,edges,stride,value,memtype); +} + +/** \internal +\ingroup variables +*/ +static int +NC_put_varm(int ncid, int varid, const size_t *start, + const size_t *edges, const ptrdiff_t *stride, const ptrdiff_t* map, + const void *value, nc_type memtype) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + + if(stat != NC_NOERR) return stat; +#ifdef USE_NETCDF4 + if(memtype >= NC_FIRSTUSERTYPEID) memtype = NC_NAT; +#endif + return ncp->dispatch->put_varm(ncid,varid,start,edges,stride,map,value,memtype); +} + +/** \name Writing Data to Variables + +Functions to write data from variables. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/** \ingroup variables +Write an array of values to a variable. + +The values to be written are associated with the netCDF variable by +assuming that the last dimension of the netCDF variable varies fastest +in the C interface. The netCDF dataset must be in data mode. The array +to be written is specified by giving a corner and a vector of edge +lengths to \ref specify_hyperslab. + +The functions for types ubyte, ushort, uint, longlong, ulonglong, and +string are only available for netCDF-4/HDF5 files. + +The nc_put_var() function will write a variable of any type, including +user defined type. For this function, the type of the data in memory +must match the type of the variable - no data conversion is done. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param startp Start vector with one element for each dimension to \ref +specify_hyperslab. + +\param countp Count vector with one element for each dimension to \ref +specify_hyperslab. + +\param op Pointer where the data will be copied. Memory must be +allocated by the user before this function is called. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_EEDGE Start+count exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. + */ +/**@{*/ +int +nc_put_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, const void *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + nc_type xtype; + if(stat != NC_NOERR) return stat; + stat = nc_inq_vartype(ncid, varid, &xtype); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, op, xtype); +} + +int +nc_put_vara_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const char *op) +{ + return NC_put_vara(ncid, varid, startp, countp, + (void*)op, NC_CHAR); +} + +int +nc_put_vara_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const signed char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + NC_BYTE); +} + +int +nc_put_vara_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + T_uchar); +} + +int +nc_put_vara_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const short *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + NC_SHORT); +} + +int +nc_put_vara_int(int ncid, int varid, const size_t *startp, + const size_t *countp, const int *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + NC_INT); +} + +int +nc_put_vara_long(int ncid, int varid, const size_t *startp, + const size_t *countp, const long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + T_long); +} + +int +nc_put_vara_float(int ncid, int varid, const size_t *startp, + const size_t *countp, const float *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + T_float); +} + +int +nc_put_vara_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const double *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + T_double); +} + +int +nc_put_vara_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + T_ubyte); +} + +int +nc_put_vara_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned short *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + T_ushort); +} + +int +nc_put_vara_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned int *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + T_uint); +} + +int +nc_put_vara_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const long long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + T_longlong); +} + +int +nc_put_vara_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned long long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_put_vara_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const char* *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vara(ncid, varid, startp, countp, (void *)op, + NC_STRING); +} + +#endif /*USE_NETCDF4*/ +/**@}*/ + +/** \ingroup variables +Write one datum. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param indexp Index vector with one element for each dimension. + +\param op Pointer from where the data will be copied. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_EEDGE Start+count exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. + */ +/**@{*/ +int +nc_put_var1(int ncid, int varid, const size_t *indexp, const void *op) +{ + return NC_put_var1(ncid, varid, indexp, op, NC_NAT); +} + +int +nc_put_var1_text(int ncid, int varid, const size_t *indexp, const char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_CHAR); +} + +int +nc_put_var1_schar(int ncid, int varid, const size_t *indexp, const signed char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_BYTE); +} + +int +nc_put_var1_uchar(int ncid, int varid, const size_t *indexp, const unsigned char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_UBYTE); +} + +int +nc_put_var1_short(int ncid, int varid, const size_t *indexp, const short *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_SHORT); +} + +int +nc_put_var1_int(int ncid, int varid, const size_t *indexp, const int *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_INT); +} + +int +nc_put_var1_long(int ncid, int varid, const size_t *indexp, const long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void*)op, longtype); +} + +int +nc_put_var1_float(int ncid, int varid, const size_t *indexp, const float *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void*)op, NC_FLOAT); +} + +int +nc_put_var1_double(int ncid, int varid, const size_t *indexp, const double *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_DOUBLE); +} + +int +nc_put_var1_ubyte(int ncid, int varid, const size_t *indexp, const unsigned char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_UBYTE); +} + +int +nc_put_var1_ushort(int ncid, int varid, const size_t *indexp, const unsigned short *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_USHORT); +} + +int +nc_put_var1_uint(int ncid, int varid, const size_t *indexp, const unsigned int *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_UINT); +} + +int +nc_put_var1_longlong(int ncid, int varid, const size_t *indexp, const long long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_INT64); +} + +int +nc_put_var1_ulonglong(int ncid, int varid, const size_t *indexp, const unsigned long long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void *)op, NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_put_var1_string(int ncid, int varid, const size_t *indexp, const char* *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var1(ncid, varid, indexp, (void*)op, NC_STRING); +} +#endif /*USE_NETCDF4*/ +/**@}*/ + +/** \ingroup variables +Write an entire variable with one call. + +The nc_put_var_ type family of functions write all the values of a +variable into a netCDF variable of an open netCDF dataset. This is the +simplest interface to use for writing a value in a scalar variable or +whenever all the values of a multidimensional variable can all be +written at once. The values to be written are associated with the +netCDF variable by assuming that the last dimension of the netCDF +variable varies fastest in the C interface. The values are converted +to the external data type of the variable, if necessary. + +Take care when using this function with record variables (variables +that use the ::NC_UNLIMITED dimension). If you try to write all the +values of a record variable into a netCDF file that has no record data +yet (hence has 0 records), nothing will be written. Similarly, if you +try to write all the values of a record variable but there are more +records in the file than you assume, more in-memory data will be +accessed than you supply, which may result in a segmentation +violation. To avoid such problems, it is better to use the nc_put_vara +interfaces for variables that use the ::NC_UNLIMITED dimension. + +The functions for types ubyte, ushort, uint, longlong, ulonglong, and +string are only available for netCDF-4/HDF5 files. + +The nc_put_var() function will write a variable of any type, including +user defined type. For this function, the type of the data in memory +must match the type of the variable - no data conversion is done. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param op Pointer from where the data will be copied. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_EEDGE Start+count exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. + */ +/**@{*/ +int +nc_put_var(int ncid, int varid, const void *op) +{ + return NC_put_var(ncid, varid, op, NC_NAT); +} + +int +nc_put_var_text(int ncid, int varid, const char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,NC_CHAR); +} + +int +nc_put_var_schar(int ncid, int varid, const signed char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,NC_BYTE); +} + +int +nc_put_var_uchar(int ncid, int varid, const unsigned char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,T_uchar); +} + +int +nc_put_var_short(int ncid, int varid, const short *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,NC_SHORT); +} + +int +nc_put_var_int(int ncid, int varid, const int *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,NC_INT); +} + +int +nc_put_var_long(int ncid, int varid, const long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,T_long); +} + +int +nc_put_var_float(int ncid, int varid, const float *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,T_float); +} + +int +nc_put_var_double(int ncid, int varid, const double *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,T_double); +} + +int +nc_put_var_ubyte(int ncid, int varid, const unsigned char *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,T_ubyte); +} + +int +nc_put_var_ushort(int ncid, int varid, const unsigned short *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,T_ushort); +} + +int +nc_put_var_uint(int ncid, int varid, const unsigned int *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,T_uint); +} + +int +nc_put_var_longlong(int ncid, int varid, const long long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,T_longlong); +} + +int +nc_put_var_ulonglong(int ncid, int varid, const unsigned long long *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_put_var_string(int ncid, int varid, const char* *op) +{ + NC* ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_var(ncid,varid,(void*)op,NC_STRING); +} +#endif /*USE_NETCDF4*/ +/**\} */ + +/** \ingroup variables +Write a strided array of values to a variable. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param startp Start vector with one element for each dimension to \ref +specify_hyperslab. + +\param countp Count vector with one element for each dimension to \ref +specify_hyperslab. + +\param stridep Stride vector with one element for each dimension to +\ref specify_hyperslab. + +\param op Pointer where the data will be copied. Memory must be +allocated by the user before this function is called. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_EEDGE Start+count exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. + */ +/**@{*/ +int +nc_put_vars (int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const void *op) +{ + NC *ncp; + int stat = NC_NOERR; + + if ((stat = NC_check_id(ncid, &ncp))) + return stat; + return ncp->dispatch->put_vars(ncid, varid, startp, countp, + stridep, op, NC_NAT); +} + +int +nc_put_vars_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const char *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep,(void*)op,NC_CHAR); +} + +int +nc_put_vars_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const signed char *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep,(void*)op,NC_BYTE); +} + +int +nc_put_vars_uchar(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const unsigned char *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, T_uchar); +} + +int +nc_put_vars_short(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const short *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, NC_SHORT); +} + +int +nc_put_vars_int(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const int *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, NC_INT); +} + +int +nc_put_vars_long(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const long *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, T_long); +} + +int +nc_put_vars_float(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const float *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, T_float); +} + +int +nc_put_vars_double(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const double *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, T_double); +} + +int +nc_put_vars_ubyte(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const unsigned char *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, T_ubyte); +} + +int +nc_put_vars_ushort(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const unsigned short *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, T_ushort); +} + +int +nc_put_vars_uint(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const unsigned int *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, T_uint); +} + +int +nc_put_vars_longlong(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const long long *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, T_longlong); +} + +int +nc_put_vars_ulonglong(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const unsigned long long *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, + stridep, (void *)op, NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_put_vars_string(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, + const char**op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_vars(ncid, varid, startp, countp, stridep, + (void *)op, NC_STRING); +} +#endif /*USE_NETCDF4*/ +/**\} */ + +/** \ingroup variables +Write a mapped array of values to a variable. + +\param ncid NetCDF or group ID, from a previous call to nc_open(), +nc_create(), nc_def_grp(), or associated inquiry functions such as +nc_inq_ncid(). + +\param varid Variable ID + +\param startp Start vector with one element for each dimension to \ref +specify_hyperslab. + +\param countp Count vector with one element for each dimension to \ref +specify_hyperslab. + +\param stridep Stride vector with one element for each dimension to +\ref specify_hyperslab. + +\param imapp Mapping vector with one element for each dimension to +\ref specify_hyperslab. + +\param op Pointer where the data will be copied. Memory must be +allocated by the user before this function is called. + +\returns ::NC_NOERR No error. +\returns ::NC_ENOTVAR Variable not found. +\returns ::NC_EINVALCOORDS Index exceeds dimension bound. +\returns ::NC_EEDGE Start+count exceeds dimension bound. +\returns ::NC_ERANGE One or more of the values are out of range. +\returns ::NC_EINDEFINE Operation not allowed in define mode. +\returns ::NC_EBADID Bad ncid. + */ +/**@{*/ +int +nc_put_varm (int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const void *op) +{ + NC *ncp; + int stat = NC_NOERR; + + if ((stat = NC_check_id(ncid, &ncp))) + return stat; + return ncp->dispatch->put_varm(ncid, varid, startp, countp, + stridep, imapp, op, NC_NAT); +} + +int +nc_put_varm_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const char *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, NC_CHAR); +} + +int +nc_put_varm_schar(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const signed char *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, NC_BYTE); +} + +int +nc_put_varm_uchar(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const unsigned char *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, T_uchar); +} + +int +nc_put_varm_short(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const short *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, NC_SHORT); +} + +int +nc_put_varm_int(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const int *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, NC_INT); +} + +int +nc_put_varm_long(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const long *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, T_long); +} + +int +nc_put_varm_float(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const float *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, T_float); +} + +int +nc_put_varm_double(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const double *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, T_double); +} + +int +nc_put_varm_ubyte(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const unsigned char *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, T_ubyte); +} + +int +nc_put_varm_ushort(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const unsigned short *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, T_ushort); +} + +int +nc_put_varm_uint(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const unsigned int *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, T_uint); +} + +int +nc_put_varm_longlong(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const long long *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, T_longlong); +} + +int +nc_put_varm_ulonglong(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const unsigned long long *op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, NC_UINT64); +} + +#ifdef USE_NETCDF4 +int +nc_put_varm_string(int ncid, int varid, + const size_t *startp, const size_t *countp, + const ptrdiff_t *stridep, const ptrdiff_t *imapp, + const char**op) +{ + NC *ncp; + int stat = NC_check_id(ncid, &ncp); + if(stat != NC_NOERR) return stat; + return NC_put_varm(ncid, varid, startp, countp, stridep, imapp, + (void *)op, NC_STRING); +} +#endif /*USE_NETCDF4*/ +/**\} */ + + +/*! \} */ /*End of named group... */ + diff --git a/extern/src_netcdf4/dvlen.c b/extern/src_netcdf4/dvlen.c new file mode 100644 index 0000000000000000000000000000000000000000..13d3560f0d798b615b360ba80156ef27d9d22883 --- /dev/null +++ b/extern/src_netcdf4/dvlen.c @@ -0,0 +1,192 @@ +/*! \file + Functions for VLEN Types + + Copyright 2011 University Corporation for Atmospheric + Research/Unidata. See \ref copyright file for more info. */ + +#include "ncdispatch.h" + +/** \name Variable Length Array Types + + Functions to create and learn about VLEN types. */ +/*! \{ */ /* All these functions are part of this named group... */ + +/** +\ingroup user_types +Free memory in a VLEN object. + +When you read VLEN type the library will actually allocate the storage +space for the data. This storage space must be freed, so pass the +pointer back to this function, when you're done with the data, and it +will free the vlen memory. + +The function nc_free_vlens() is more useful than this function, +because it can free an array of VLEN objects. + +\param vl pointer to the vlen object. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +*/ +int +nc_free_vlen(nc_vlen_t *vl) +{ + free(vl->p); + return NC_NOERR; +} + +/** +\ingroup user_types +Free an array of vlens given the number of elements and an array. + +When you read VLEN type the library will actually allocate the storage +space for the data. This storage space must be freed, so pass the +pointer back to this function, when you're done with the data, and it +will free the vlen memory. + +\param len number of elements in the array. +\param vlens pointer to the vlen object. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +*/ +int +nc_free_vlens(size_t len, nc_vlen_t vlens[]) +{ + int ret; + size_t i; + + for(i = 0; i < len; i++) + if ((ret = nc_free_vlen(&vlens[i]))) + return ret; + + return NC_NOERR; +} + +/** +\ingroup user_types +Use this function to define a variable length array type. + +\param ncid \ref ncid +\param name \ref object_name of new type. + +\param base_typeid The typeid of the base type of the VLEN. For +example, for a VLEN of shorts, the base type is ::NC_SHORT. This can be +a user defined type. + +\param xtypep A pointer to an nc_type variable. The typeid of the new +VLEN type will be set here. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +\returns ::NC_ENAMEINUSE That name is in use. +\returns ::NC_EMAXNAME Name exceeds max length NC_MAX_NAME. +\returns ::NC_EBADNAME Name contains illegal characters. +\returns ::NC_EPERM Attempt to write to a read-only file. +\returns ::NC_ENOTINDEFINE Not in define mode. + */ +int +nc_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type *xtypep) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->def_vlen(ncid,name,base_typeid,xtypep); +} + +/** \ingroup user_types +Learn about a VLEN type. + +\param ncid \ref ncid +\param xtype The type of the VLEN to inquire about. +\param name \ref object_name of the type. \ref ignored_if_null. + +\param datum_sizep A pointer to a size_t, this will get the size of +one element of this vlen. \ref ignored_if_null. + +\param base_nc_typep Pointer to get the base type of the VLEN. \ref +ignored_if_null. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_inq_vlen(int ncid, nc_type xtype, char *name, size_t *datum_sizep, nc_type *base_nc_typep) +{ + int class = 0; + int stat = nc_inq_user_type(ncid,xtype,name,datum_sizep,base_nc_typep,NULL,&class); + if(stat != NC_NOERR) return stat; + if(class != NC_VLEN) stat = NC_EBADTYPE; + return stat; +} +/*! \} */ /* End of named group ...*/ + +/** \internal +\ingroup user_types + +Put a VLEN element. This function writes an element of a VLEN for the +Fortran APIs. + +\param ncid \ref ncid +\param typeid1 Typeid of the VLEN. +\param vlen_element Pointer to the element of the VLEN. +\param len Lenth of the VLEN element. +\param data VLEN data. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. +\returns ::NC_EPERM Attempt to write to a read-only file. + */ +int +nc_put_vlen_element(int ncid, int typeid1, void *vlen_element, size_t len, const void *data) +{ + NC* ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->put_vlen_element(ncid,typeid1,vlen_element,len,data); +} + +/** +\internal +\ingroup user_types + +Get a VLEN element. This function reads an element of a VLEN for the +Fortran APIs. + +\param ncid \ref ncid +\param typeid1 Typeid of the VLEN. +\param vlen_element Pointer to the element of the VLEN. +\param len Lenth of the VLEN element. +\param data VLEN data. + +\returns ::NC_NOERR No error. +\returns ::NC_EBADID Bad \ref ncid. +\returns ::NC_EBADTYPE Bad type id. +\returns ::NC_ENOTNC4 Not an netCDF-4 file, or classic model enabled. +\returns ::NC_EHDFERR An error was reported by the HDF5 layer. + */ +int +nc_get_vlen_element(int ncid, int typeid1, const void *vlen_element, + size_t *len, void *data) +{ + NC *ncp; + int stat = NC_check_id(ncid,&ncp); + if(stat != NC_NOERR) return stat; + return ncp->dispatch->get_vlen_element(ncid, typeid1, vlen_element, + len, data); +} diff --git a/extern/src_netcdf4/err_macros.h b/extern/src_netcdf4/err_macros.h new file mode 100644 index 0000000000000000000000000000000000000000..c087f1c02e9918c60ae7a81f70df9845d62f175a --- /dev/null +++ b/extern/src_netcdf4/err_macros.h @@ -0,0 +1,81 @@ +/* This is part of the netCDF package. + Copyright 2005 University Corporation for Atmospheric Research/Unidata + See COPYRIGHT file for conditions of use. + + Common includes, defines, etc., for test code in the libsrc4 and + nc_test4 directories. +*/ + +#ifndef _ERR_MACROS_H +#define _ERR_MACROS_H + +#include +#include +#include +#include +#include + +/* Err is used to keep track of errors within each set of tests, + * total_err is the number of errors in the entire test program, which + * generally cosists of several sets of tests. */ +static int total_err = 0, err = 0; + +#if 0 +/* This is handy for print statements. */ +static char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4", + "netCDF-4 classic model"}; +#endif + +/* This macro prints an error message with line number and name of + * test program. */ +#define ERR do { \ +fflush(stdout); /* Make sure our stdout is synced with stderr. */ \ +err++; \ +fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \ + __FILE__, __LINE__); \ +return 2; \ +} while (0) + +/* This macro prints an error message with line number and name of + * test program, and then exits the program. */ + +#define ERR_RET do { \ +fflush(stdout); /* Make sure our stdout is synced with stderr. */ \ +fprintf(stderr, "Sorry! Unexpected result, %s, line: %d\n", \ + __FILE__, __LINE__); \ +return 2; \ +} while (0) + +/* After a set of tests, report the number of errors, and increment + * total_err. */ +#define SUMMARIZE_ERR do { \ + if (err) \ + { \ + printf("%d failures\n", err); \ + total_err += err; \ + err = 0; \ + } \ + else \ + printf("ok.\n"); \ +} while (0) + +/* If extra memory debugging is not in use (as it usually isn't), + * define away the nc_exit function, which may be in some tests. */ +#ifndef EXTRA_MEM_DEBUG +#define nc_exit() +#endif + +/* This macro prints out our total number of errors, if any, and exits + * with a 0 if there are not, or a 2 if there were errors. Make will + * stop if a non-zero value is returned from a test program. */ +#define FINAL_RESULTS do { \ + if (total_err) \ + { \ + printf("%d errors detected! Sorry!\n", total_err); \ + return 2; \ + } \ + printf("*** Tests successful!\n"); \ + return 0; \ +} while (0) + +#endif /* _ERR_MACROS_H */ diff --git a/extern/src_netcdf4/error4.c b/extern/src_netcdf4/error4.c new file mode 100644 index 0000000000000000000000000000000000000000..557bdb998873ff5449506ffb499d1068af1ec400 --- /dev/null +++ b/extern/src_netcdf4/error4.c @@ -0,0 +1,75 @@ +/* + +This file is part of netcdf-4, a netCDF-like interface for HDF5, or a +HDF5 backend for netCDF, depending on your point of view. + +This file contains functions relating to logging errors. Also it +contains the functions nc_malloc, nc_calloc, and nc_free. + +Copyright 2003, University Corporation for Atmospheric Research. See +netcdf-4/docs/COPYRIGHT file for copying and redistribution +conditions. + +$Id: error4.c,v 1.4 2010/06/01 17:48:55 ed Exp $ +*/ + +#include +#include +#include +#include +#include +#include + +/* This contents of this file get skipped if LOGGING is not defined + * during compile. */ +#ifdef LOGGING + +extern int nc_log_level; + +/* This function prints out a message, if the severity of the message + is lower than the global nc_log_level. To use it, do something like + this: + + nc_log(0, "this computer will explode in %d seconds", i); + + After the first arg (the severity), use the rest like a normal + printf statement. Output will appear on stdout. + + This function is heavily based on the function in section 15.5 of + the C FAQ. */ +void +nc_log(int severity, const char *fmt, ...) +{ + va_list argp; + int t; + + /* If the severity is greater than the log level, we don' care to + print this message. */ + if (severity > nc_log_level) + return; + + /* If the severity is zero, this is an error. Otherwise insert that + many tabs before the message. */ + if (!severity) + fprintf(stdout, "ERROR: "); + for (t=0; t fetch whole dataset +b. The target variable (as specified in nc_get_vara()) + is already in the cache and is whole variable. + fetchprojection = N.A. since variable is in the cache +c. Vara is requesting part of a variable but NCF_WHOLEVAR flag is set. + fetchprojection = unsliced vara variable => fetch whole variable +d. Vara is requesting part of a variable and NCF_WHOLEVAR flag is not set. + fetchprojection = sliced vara variable => fetch part variable + +2. At this point, all or part of the target variable is available in the cache. + +3. We build a projection to walk (guide) the use of the oc + data procedures in extract the required data from the cache. + For cases a,b,c: + walkprojection = merge(urlprojection,varaprojection) + For case d: + walkprojection = varaprojection without slicing. + This means we need only extract the complete contents of the cache. + Notice that this will not necessarily be a direct memory to + memory copy because the dap encoding still needs to be + interpreted. For this case, we derive a walk projection + from the vara projection that will properly access the cached data. + This walk projection shifts the merged projection so all slices + start at 0 and have a stride of 1. + +*/ + +NCerror +nc3d_getvarx(int ncid, int varid, + const size_t *startp, + const size_t *countp, + const ptrdiff_t* stridep, + void *data, + nc_type dsttype0) +{ + NCerror ncstat = NC_NOERR; + OCerror ocstat = OC_NOERR; + int i; + NC* drno; + NC* substrate; + NCDAPCOMMON* dapcomm; + CDFnode* cdfvar; /* cdf node mapping to var*/ + NClist* varnodes; + nc_type dsttype; + Getvara* varainfo = NULL; + CDFnode* xtarget = NULL; /* target in DATADDS */ + CDFnode* target = NULL; /* target in constrained DDS */ + DCEprojection* varaprojection = NULL; + NCcachenode* cachenode = NULL; + size_t localcount[NC_MAX_VAR_DIMS]; + NClist* ncdimsall; + size_t ncrank; + NClist* vars = NULL; + DCEconstraint* fetchconstraint = NULL; + DCEprojection* fetchprojection = NULL; + DCEprojection* walkprojection = NULL; + int state; +#define FETCHWHOLE 1 /* fetch whole data set */ +#define FETCHVAR 2 /* fetch whole variable */ +#define FETCHPART 4 /* fetch constrained variable */ +#define CACHED 8 /* whole variable is already in the cache */ + + ncstat = NC_check_id(ncid, (NC**)&drno); + if(ncstat != NC_NOERR) goto fail; + dapcomm = (NCDAPCOMMON*)drno->dispatchdata; + + ncstat = NC_check_id(drno->substrate, (NC**)&substrate); + if(ncstat != NC_NOERR) goto fail; + + /* Locate var node via varid */ + varnodes = dapcomm->cdf.varnodes; + for(i=0;iarray.basevar == NULL + && node->nctype == NC_Primitive + && node->ncid == varid) { + cdfvar = node; + break; + } + } + + ASSERT((cdfvar != NULL)); + + /* Get the dimension info */ + ncdimsall = cdfvar->array.dimsetall; + ncrank = nclistlength(ncdimsall); + +#ifdef DEBUG + { +int i; +fprintf(stderr,"getvarx: %s",cdfvar->ncfullname); +for(i=0;idim.declsize; + } + countp = localcount; + } + + if(stridep == NULL) + stridep = nc_ptrdiffvector1; + + /* Validate the dimension sizes */ + for(i=0;i dim->dim.declsize + || startp[i]+countp[i] > dim->dim.declsize) { + ncstat = NC_EINVALCOORDS; + goto fail; + } + } + +#ifdef DEBUG + { +NClist* dims = cdfvar->array.dimsetall; +fprintf(stderr,"getvarx: %s",cdfvar->ncfullname); +if(nclistlength(dims) > 0) {int i; +for(i=0;i "); +for(i=0;iexternaltype; + + /* Validate any implied type conversion*/ + if(cdfvar->etype != dsttype && dsttype == NC_CHAR) { + /* The only disallowed conversion is to/from char and non-byte + numeric types*/ + switch (cdfvar->etype) { + case NC_STRING: case NC_URL: + case NC_CHAR: case NC_BYTE: case NC_UBYTE: + break; + default: + return THROW(NC_ECHAR); + } + } + + ncstat = makegetvar34(dapcomm,cdfvar,data,dsttype,&varainfo); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + + state = 0; + if(iscached(dapcomm,cdfvar,&cachenode)) { + state = CACHED; + ASSERT((cachenode != NULL)); +#ifdef DEBUG +fprintf(stderr,"var is in cache\n"); +#endif + /* If it is cached, then it is a whole variable but may still + need to apply constraints during the walk */ + ASSERT(cachenode->wholevariable); /* by construction */ + } else if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { + state = FETCHWHOLE; + } else {/* load using constraints */ + if(FLAGSET(dapcomm->controls,NCF_WHOLEVAR)) + state = FETCHVAR; + else + state = FETCHPART; + } + + ASSERT(state != 0); + + /* Convert the start/stop/stride info into a projection */ + ncstat = buildvaraprojection3(varainfo, + startp,countp,stridep, + &varaprojection); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + + fetchprojection = NULL; + walkprojection = NULL; + + /* Create walkprojection as the merge of the url projections + and the vara projection; may change in FETCHPART case below*/ + ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections, + varaprojection,&walkprojection); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + +#ifdef DEBUG +fprintf(stderr,"getvarx: walkprojection: |%s|\n",dumpprojection(walkprojection)); +#endif + + /* define the var list of interest */ + vars = nclistnew(); + nclistpush(vars,(ncelem)varainfo->target); + + switch (state) { + + case FETCHWHOLE: { + /* buildcachenode3 will create a new cachenode and + will also fetch the whole corresponding datadds. + */ + /* Build the complete constraint to use in the fetch */ + fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); + /* Use no projections or selections */ + fetchconstraint->projections = nclistnew(); + fetchconstraint->selections = nclistnew(); +#ifdef DEBUG +fprintf(stderr,"getvarx: FETCHWHOLE: fetchconstraint: %s\n",dumpconstraint(fetchconstraint)); +#endif + ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0); + fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/ + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + } break; + + case CACHED: { + } break; + + case FETCHVAR: { /* Fetch a complete single variable */ + /* Create fetch projection as the merge of the url projections + and the vara projection */ + ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections, + varaprojection,&fetchprojection); + /* elide any sequence and string dimensions (dap servers do not allow such). */ + ncstat = removepseudodims(fetchprojection); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + + /* Convert to a whole variable projection */ + dcemakewholeprojection(fetchprojection); + +#ifdef DEBUG +fprintf(stderr,"getvarx: FETCHVAR: fetchprojection: |%s|\n",dumpprojection(fetchprojection)); +#endif + + /* Build the complete constraint to use in the fetch */ + fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); + /* merged constraint just uses the url constraint selection */ + fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections); + /* and the created fetch projection */ + fetchconstraint->projections = nclistnew(); + nclistpush(fetchconstraint->projections,(ncelem)fetchprojection); +#ifdef DEBUG +fprintf(stderr,"getvarx: FETCHVAR: fetchconstraint: %s\n",dumpconstraint(fetchconstraint)); +#endif + /* buildcachenode3 will create a new cachenode and + will also fetch the corresponding datadds. + */ + ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0); + fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/ + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + } break; + + case FETCHPART: { + /* Create fetch projection as the merge of the url projections + and the vara projection */ + ncstat = daprestrictprojection(dapcomm->oc.dapconstraint->projections, + varaprojection,&fetchprojection); + /* elide any sequence and string dimensions (dap servers do not allow such). */ + ncstat = removepseudodims(fetchprojection); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + + /* Shift the varaprojection for simple walk */ + dcefree((DCEnode*)walkprojection) ; /* reclaim any existing walkprojection */ + walkprojection = (DCEprojection*)dceclone((DCEnode*)varaprojection); + dapshiftprojection(walkprojection); + +#ifdef DEBUG +fprintf(stderr,"getvarx: FETCHPART: fetchprojection: |%s|\n",dumpprojection(fetchprojection)); +#endif + + /* Build the complete constraint to use in the fetch */ + fetchconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); + /* merged constraint just uses the url constraint selection */ + fetchconstraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections); + /* and the created fetch projection */ + fetchconstraint->projections = nclistnew(); + nclistpush(fetchconstraint->projections,(ncelem)fetchprojection); +#ifdef DEBUG +fprintf(stderr,"getvarx: FETCHPART: fetchconstraint: %s\n",dumpconstraint(fetchconstraint)); +#endif + /* buildcachenode3 will create a new cachenode and + will also fetch the corresponding datadds. + */ + ncstat = buildcachenode34(dapcomm,fetchconstraint,vars,&cachenode,0); + fetchconstraint = NULL; /*buildcachenode34 takes control of fetchconstraint.*/ + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + } break; + + default: PANIC1("unknown fetch state: %d\n",state); + } + + ASSERT(cachenode != NULL); + +#ifdef DEBUG +fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds)); +#endif + + /* attach DATADDS to (constrained) DDS */ + unattach34(dapcomm->cdf.ddsroot); + ncstat = attachsubset34(cachenode->datadds,dapcomm->cdf.ddsroot); + if(ncstat) goto fail; + + /* Fix up varainfo to use the cache */ + varainfo->cache = cachenode; + cachenode = NULL; + varainfo->varaprojection = walkprojection; + walkprojection = NULL; + + /* Get the var correlate from the datadds */ + target = varainfo->target; + xtarget = target->attachment; + if(xtarget == NULL) + {THROWCHK(ncstat=NC_ENODATA); goto fail;} + + /* Switch to datadds tree space*/ + varainfo->target = xtarget; + ncstat = moveto(dapcomm,varainfo,varainfo->cache->datadds,data); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + + goto ok; + +fail: + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); +ok: + nclistfree(vars); + dcefree((DCEnode*)varaprojection); + dcefree((DCEnode*)fetchconstraint); + freegetvara(varainfo); + return THROW(ncstat); +} + +/* Remove any pseudodimensions (sequence and string)*/ +static NCerror +removepseudodims(DCEprojection* proj) +{ + int i; +#ifdef DEBUG1 +fprintf(stderr,"removesequencedims.before: %s\n",dumpprojection(proj)); +#endif + for(i=0;ivar->segments);i++) { + DCEsegment* seg = (DCEsegment*)nclistget(proj->var->segments,i); + CDFnode* cdfnode = (CDFnode*)seg->annotation; + if(cdfnode->array.seqdim != NULL) + seg->rank = 0; + else if(cdfnode->array.stringdim != NULL) + seg->rank--; + } +#ifdef DEBUG1 +fprintf(stderr,"removepseudodims.after: %s\n",dumpprojection(proj)); +#endif + return NC_NOERR; +} + +static NCerror +moveto(NCDAPCOMMON* nccomm, Getvara* xgetvar, CDFnode* xrootnode, void* memory) +{ + OCerror ocstat = OC_NOERR; + NCerror ncstat = NC_NOERR; + OCconnection conn = nccomm->oc.conn; + OCdata xrootcontent; + OCobject ocroot; + NClist* path = nclistnew(); + struct NCMEMORY memstate; + + memstate.next = (memstate.memory = memory); + + /* Get the root content*/ + ocroot = xrootnode->tree->ocroot; + xrootcontent = oc_data_new(conn); + ocstat = oc_data_root(conn,ocroot,xrootcontent); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} + + /* Remember: xgetvar->target is in DATADDS tree */ + collectnodepath3(xgetvar->target,path,WITHDATASET); + ncstat = movetor(nccomm,xrootcontent, + path,0,xgetvar,0,&memstate, + xgetvar->varaprojection->var->segments); + +done: + nclistfree(path); + oc_data_free(conn,xrootcontent); + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); + return THROW(ncstat); +} + +static NCerror +movetor(NCDAPCOMMON* nccomm, + OCdata currentcontent, + NClist* path, + int depth, /* depth is position in segment list*/ + Getvara* xgetvar, + int dimindex, /* dimindex is position in xgetvar->slices*/ + struct NCMEMORY* memory, + NClist* segments) +{ + int i; + OCerror ocstat = OC_NOERR; + NCerror ncstat = NC_NOERR; + size_t fieldindex,gridindex,rank; + OCconnection conn = nccomm->oc.conn; + CDFnode* xnode = (CDFnode*)nclistget(path,depth); + OCdata reccontent = OCNULL; + OCdata dimcontent = OCNULL; + OCdata fieldcontent = OCNULL; + Dapodometer* odom = OCNULL; + OCmode currentmode = OCNULLMODE; + CDFnode* xnext; + int hasstringdim = 0; + size_t dimoffset; + DCEsegment* segment; + int newdepth; + int caching = FLAGSET(nccomm->controls,NCF_CACHE); + int unconstrainable = FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE); + + /* Note that we use depth-1 because the path contains the DATASET + but the segment list does not */ + segment = (DCEsegment*)nclistget(segments,depth-1); /*may be NULL*/ + if(xnode->etype == NC_STRING || xnode->etype == NC_URL) hasstringdim = 1; + + ocstat = oc_data_mode(conn,currentcontent,¤tmode); + +#ifdef DEBUG2 +fprintf(stderr,"moveto: nctype=%d currentmode=%d depth=%d dimindex=%d", + xnode->nctype, currentmode, depth,dimindex); +fprintf(stderr," segment=%s hasstringdim=%d\n", + dcetostring((DCEnode*)segment),hasstringdim); +#endif + + /* Switch on the combination of nctype and mode */ +#define CASE(nc1,nc2) (nc1*1024+nc2) + + /* This must be consistent with the oc mode transition function */ + switch (CASE(xnode->nctype,currentmode)) { + + default: + PANIC2("Illegal combination: nctype=%d mode=%d", + (int)xnode->nctype,(int)currentmode); + break; + + case CASE(NC_Sequence,OCFIELDMODE): + case CASE(NC_Dataset,OCFIELDMODE): + case CASE(NC_Grid,OCFIELDMODE): + case CASE(NC_Structure,OCFIELDMODE): + /* currentcontent points to the grid/dataset/structure instance */ + xnext = (CDFnode*)nclistget(path,depth+1); + ASSERT((xnext != NULL)); + fieldindex = findfield(xnode,xnext); + /* If the next node is a virtual node, then + we need to effectively + ignore it and use the appropriate subnode. + If the next node is a structuregrid node, then + use it as is. + */ + if(xnext->virtual) { + CDFnode* xgrid = xnext; + xnext = (CDFnode*)nclistget(path,depth+2); /* real node */ + gridindex = fieldindex; + fieldindex = findfield(xgrid,xnext); + fieldindex += gridindex; + newdepth = depth+2; + } else { + newdepth = depth+1; + } + fieldcontent = oc_data_new(conn); + ocstat = oc_data_ith(conn,currentcontent,fieldindex,fieldcontent); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} + ncstat = movetor(nccomm,fieldcontent, + path,newdepth,xgetvar,dimindex,memory, + segments); + break; + + case CASE(NC_Sequence,OCARRAYMODE): /* will actually always be scalar, but will have + rank == 1 to account for the sequence dim */ + case CASE(NC_Grid,OCARRAYMODE): /* will actually always be scalar */ + case CASE(NC_Structure,OCARRAYMODE): + /* figure out which slices refer to this node: + dimindex upto dimindex+rank; */ + ASSERT((segment != NULL)); + rank = segment->rank; + if(xnode->nctype == NC_Sequence) + rank--; /* ignore the sequence dim */ + if(rank == 0) { + odom = newdapodometer1(1); + } else if(caching || unconstrainable) { + odom = newdapodometer(segment->slices,0,rank); + } else { /*Since vara was projected out, build a simple odometer*/ + odom = newsimpledapodometer(segment,rank); + } + while(dapodometermore(odom)) { + OCmode mode; + /* Compute which instance to move to*/ + dimoffset = dapodometercount(odom); + dimcontent = oc_data_new(conn); + ocstat = oc_data_ith(conn,currentcontent,dimoffset,dimcontent); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} + ocstat = oc_data_mode(conn,dimcontent,&mode); + ASSERT((mode == OCFIELDMODE + || (mode == OCSEQUENCEMODE && xnode->nctype == NC_Sequence))); + ncstat = movetor(nccomm,dimcontent, + path,depth, + xgetvar,dimindex+rank, + memory,segments); + dapodometerincr(odom); + } + freedapodometer(odom); + break; + + case CASE(NC_Sequence,OCSEQUENCEMODE): { + DCEslice* uslice; + ASSERT((segment != NULL)); + /* Get and check the corresponding sequence dimension from DDS */ + ASSERT((xnode->attachment != NULL)); + /* use uslice to walk the sequence; however, watch out + for the case when the user set a limit and that limit + is not actually reached in this request. + */ + /* By construction, this sequence represents the first + (and only) dimension of this segment */ + uslice = &segment->slices[0]; + reccontent = oc_data_new(conn); + for(i=uslice->first;istop;i+=uslice->stride) { + OCmode eos; + ocstat = oc_data_ith(conn,currentcontent,i,reccontent); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} + ocstat = oc_data_mode(conn,reccontent,&eos); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} + if(eos == OCNULLMODE) { + /* We asked for too much */ + ncstat = THROW(NC_EINVALCOORDS); + goto fail; + } + ncstat = movetor(nccomm,reccontent, + path,depth, + xgetvar,dimindex+1, + memory,segments); + if(ncstat != OC_NOERR) {THROWCHK(ncstat); goto fail;} + } + } break; + + case CASE(NC_Primitive,OCPRIMITIVEMODE): + if(hasstringdim) + ncstat = extractstring(nccomm, xgetvar, xnode, segment, conn, currentcontent, memory); + else + ncstat = extract(nccomm, xgetvar, xnode, segment, conn, currentcontent, memory); + break; + + } + goto ok; + +fail: +ok: + oc_data_free(conn,dimcontent); + oc_data_free(conn,fieldcontent); + oc_data_free(conn,reccontent); + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); + return THROW(ncstat); +} + +/* Determine the index in the odometer at which + the odometer will be walking the whole subslice + This will allow us to optimize. +*/ +static int +wholeslicepoint(Dapodometer* odom) +{ + unsigned int i; + int point; + for(point=-1,i=0;irank;i++) { + ASSERT((odom->slices[i].declsize != 0)); + if(odom->slices[i].first != 0 || odom->slices[i].stride != 1 + || odom->slices[i].length != odom->slices[i].declsize) + point = i; + } + if(point == -1) + point = 0; /* wholevariable */ + else if(point == (odom->rank - 1)) + point = -1; /* no whole point */ + else + point += 1; /* intermediate point */ + return point; +} + +static int +findfield(CDFnode* node, CDFnode* field) +{ + size_t i; + for(i=0;isubnodes);i++) { + CDFnode* test = (CDFnode*) nclistget(node->subnodes,i); + if(test == field) return i; + } + return -1; +} + + +int +nc3d_getvarmx(int ncid, int varid, + const size_t *start, + const size_t *edges, + const ptrdiff_t* stride, + const ptrdiff_t* map, + void* data, + nc_type dsttype0) +{ + NCerror ncstat = NC_NOERR; + int i; + NC* drno; + NC* substrate; + NCDAPCOMMON* dapcomm; + NC_var* var; + CDFnode* cdfvar; /* cdf node mapping to var*/ + NClist* varnodes; + nc_type dsttype; + size_t externsize; + size_t dimsizes[NC_MAX_VAR_DIMS]; + Dapodometer* odom = NULL; + unsigned int ncrank; + NClist* ncdims = NULL; + size_t nelems; +#ifdef NEWVARM + char* localcopy; /* of whole variable */ +#endif + + ncstat = NC_check_id(ncid, (NC**)&drno); + if(ncstat != NC_NOERR) goto done; + dapcomm = (NCDAPCOMMON*)drno->dispatchdata; + + ncstat = NC_check_id(drno->substrate, (NC**)&substrate); + if(ncstat != NC_NOERR) goto done; + var = NC_lookupvar(substrate,varid); + if(var == NULL) {ncstat = NC_ENOTVAR; goto done;} + + /* Locate var node via varid */ + varnodes = dapcomm->cdf.varnodes; + for(i=0;iarray.basevar == NULL + && node->nctype == NC_Primitive + && node->ncid == varid) { + cdfvar = node; + break; + } + } + + ASSERT((cdfvar != NULL)); + ASSERT((strcmp(cdfvar->ncfullname,var->name->cp)==0)); + + if(nclistlength(cdfvar->array.dimsetplus) == 0) { + /* The variable is a scalar; consequently, there is only one + thing to get and only one place to put it. (Why was I + called?) */ + /* recurse with additional parameters */ + return THROW(nc3d_getvarx(ncid,varid, + NULL,NULL,NULL, + data,dsttype0)); + } + + dsttype = (dsttype0); + + /* Default to using the inquiry type for this var*/ + if(dsttype == NC_NAT) dsttype = cdfvar->externaltype; + + /* Validate any implied type conversion*/ + if(cdfvar->etype != dsttype && dsttype == NC_CHAR) { + /* The only disallowed conversion is to/from char and non-byte + numeric types*/ + switch (cdfvar->etype) { + case NC_STRING: case NC_URL: + case NC_CHAR: case NC_BYTE: case NC_UBYTE: + break; + default: + return THROW(NC_ECHAR); + } + } + + externsize = nctypesizeof(dsttype); + + /* Accumulate the dimension sizes and the total # of elements */ + ncdims = cdfvar->array.dimsetall; + ncrank = nclistlength(ncdims); + + nelems = 1; /* also Compute the number of elements being retrieved */ + for(i=0;idim.declsize; + nelems *= edges[i]; + } + + /* Originally, this code repeatedly extracted single values + using get_var1. In an attempt to improve performance, + I have converted to reading the whole variable at once + and walking it locally. + */ + +#ifdef NEWVARM + localcopy = (char*)malloc(nelems*externsize); + + /* We need to use the varieties of get_vars in order to + properly do conversion to the external type + */ + + switch (dsttype) { + + case NC_CHAR: + ncstat = nc_get_vars_text(ncid,varid,start, edges, stride, + (char*)localcopy); + break; + case NC_BYTE: + ncstat = nc_get_vars_schar(ncid,varid,start, edges, stride, + (signed char*)localcopy); + break; + case NC_SHORT: + ncstat = nc_get_vars_short(ncid,varid, start, edges, stride, + (short*)localcopy); + break; + case NC_INT: + ncstat = nc_get_vars_int(ncid,varid,start, edges, stride, + (int*)localcopy); + break; + case NC_FLOAT: + ncstat = nc_get_vars_float(ncid,varid,start, edges, stride, + (float*)localcopy); + break; + case NC_DOUBLE: + ncstat = nc_get_vars_double(ncid,varid, start, edges, stride, + (double*)localcopy); + break; + default: break; + } + + odom = newdapodometer2(start,edges,stride,0,ncrank); + + /* Walk the local copy */ + for(i=0;i %lu %f\n", + (unsigned long)(i), + (unsigned long)voffset, + *(float*)localpos); +*/ + dapodometerincr(odom); + } +#else + odom = newdapodometer2(start,edges,stride,0,ncrank); + while(dapodometermore(odom)) { + size_t* indexset = dapodometerindices(odom); + size_t voffset = dapodometervarmcount(odom,map,dimsizes); + char internalmem[128]; + char externalmem[128]; + void* dataoffset = (void*)(((char*)data) + (externsize*voffset)); + + /* get the indexset'th value using variable's internal type */ + ncstat = nc_get_var1(ncid,varid,indexset,(void*)&internalmem); + if(ncstat != NC_NOERR) goto done; + /* Convert to external type */ + ncstat = dapconvert3(cdfvar->etype,dsttype,externalmem,internalmem); + if(ncstat != NC_NOERR) goto done; + memcpy(dataoffset,(void*)externalmem,externsize); +/* +fprintf(stderr,"old: %lu -> %lu %f\n", + (unsigned long)dapodometercount(odom), + (unsigned long)voffset, + *(float*)externalmem); +*/ + dapodometerincr(odom); + } +#endif + +done: + return ncstat; +} + +static int +conversionrequired(nc_type t1, nc_type t2) +{ + if(t1 == t2) + return 0; + if(nctypesizeof(t1) != nctypesizeof(t2)) + return 1; + /* Avoid too many cases by making t1 < t2 */ + if(t1 > t2) {int tmp = t1; t1 = t2; t2 = tmp;} +#undef CASE +#define CASE(t1,t2) ((t1)<<5 | (t2)) + switch (CASE(t1,t2)) { + case CASE(NC_BYTE,NC_UBYTE): + case CASE(NC_BYTE,NC_CHAR): + case CASE(NC_CHAR,NC_UBYTE): + case CASE(NC_SHORT,NC_USHORT): + case CASE(NC_INT,NC_UINT): + case CASE(NC_INT64,NC_UINT64): + return 0; + default: break; + } + return 1; +} + +/* We are at a primitive variable or scalar that has no string dimensions. +Extract the data. +(This is way too complicated) +*/ +static int +extract( + NCDAPCOMMON* nccomm, + Getvara* xgetvar, + CDFnode* xnode, + DCEsegment* segment, + OClink conn, + OCdata currentcontent, + struct NCMEMORY* memory + ) +{ + OCerror ocstat = OC_NOERR; + NCerror ncstat = NC_NOERR; + size_t rank; + Dapodometer* odom = OCNULL; + int wholepoint; + size_t externtypesize; + size_t interntypesize; + char* localmemory = NULL; + size_t odomsubsize; + size_t internlen; + int requireconversion; + char value[16]; + + ASSERT((segment != NULL)); + + requireconversion = conversionrequired(xgetvar->dsttype,xnode->etype); + + rank = segment->rank; + + if(rank == 0) {/* scalar */ + char* mem = (requireconversion?value:memory->next); + ASSERT((segment != NULL)); + externtypesize = nctypesizeof(xgetvar->dsttype); + ASSERT(externtypesize <= sizeof(value)); + /* Read the whole scalar directly into memory */ + ocstat = oc_data_get(conn,currentcontent,mem,externtypesize,0,1); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} + if(requireconversion) { + /* convert the value to external type */ + ncstat = dapconvert3(xnode->etype,xgetvar->dsttype,memory->next,value,1); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + } + memory->next += (externtypesize); + + } else {/* rank > 0 */ + +#ifdef DEBUG2 +fprintf(stderr,"moveto: primitive: segment=%s", + dcetostring((DCEnode*)segment)); +fprintf(stderr," iswholevariable=%d",xgetvar->cache->wholevariable); +fprintf(stderr,"\n"); +#endif + + ASSERT(xgetvar->cache != NULL); + if(xgetvar->cache->wholevariable) { + odom = newdapodometer(segment->slices,0,rank); + } else { /*!xgetvar->cache->wholevariable*/ + odom = newsimpledapodometer(segment,rank); + } + /* Optimize off the use of the odometer by checking the slicing + to see if the whole variable, or some whole subslice + is being extracted. + However do not do this if the external type conversion is needed + or if the whole slice point is rank-1 (normal case anyway). + */ + externtypesize = nctypesizeof(xgetvar->dsttype); + interntypesize = nctypesizeof(xnode->etype); + wholepoint = wholeslicepoint(odom); + if(wholepoint == -1) + odomsubsize = 1; /* no whole point */ + else + odomsubsize = dapodometerspace(odom,wholepoint); + internlen = (odomsubsize*interntypesize); + if(requireconversion) { + /* copy the data locally before conversion */ + localmemory = (char*)malloc(internlen); + } else { + localmemory = memory->next; + } + +#ifdef DEBUG2 +fprintf(stderr,"moveto: primitive: "); +fprintf(stderr," wholepoint=%d",wholepoint); +fprintf(stderr,"\n"); +#endif + + if(wholepoint == 0) {/* whole variable */ + /* Read the whole n elements directly into memory.*/ + ocstat = oc_data_get(conn,currentcontent,localmemory, + internlen,0,odomsubsize); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} + if(requireconversion) { + /* do conversion */ + ncstat = dapconvert3(xnode->etype,xgetvar->dsttype, + memory->next,localmemory,odomsubsize); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + } + memory->next += (externtypesize*odomsubsize); + } else if(wholepoint > 0) {/* whole subslice */ + odom->rank = wholepoint; /* truncate */ + while(dapodometermore(odom)) { + size_t dimoffset = dapodometercount(odom) * odomsubsize; + ocstat = oc_data_get(conn,currentcontent,localmemory, + internlen,dimoffset,odomsubsize); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} + if(requireconversion) { + /* do conversion */ + ncstat = dapconvert3(xnode->etype,xgetvar->dsttype, + memory->next,localmemory,odomsubsize); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + } + memory->next += (externtypesize*odomsubsize); + dapodometerincr(odom); + } + } else { /* Oh well, use the odometer to walk to the + appropriate fields*/ + while(dapodometermore(odom)) { + char* mem = (requireconversion?value:memory->next); + size_t dimoffset = dapodometercount(odom); + ocstat = oc_data_get(conn,currentcontent,mem,externtypesize,dimoffset,1); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} + if(requireconversion) { + ncstat = dapconvert3(xnode->etype,xgetvar->dsttype,memory->next,value,1); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + } + memory->next += externtypesize; + dapodometerincr(odom); + } + } + freedapodometer(odom); + if(requireconversion) nullfree(localmemory); + } +done: + return THROW(ncstat); +} + + +static NCerror +slicestring(OCconnection conn, char* stringmem, DCEslice* slice, struct NCMEMORY* memory) +{ + size_t stringlen; + unsigned int i; + NCerror ncstat = NC_NOERR; + char* lastchar; + size_t charcount; /* number of characters inserted into memory */ + + /* libnc-dap chooses to convert string escapes to the corresponding + character; so we do likewise. + */ + dapexpandescapes(stringmem); + stringlen = strlen(stringmem); + +#ifdef DEBUG2 +fprintf(stderr,"moveto: slicestring: string/%lu=%s\n",stringlen,stringmem); +fprintf(stderr,"slicestring: %lu string=|%s|\n",stringlen,stringmem); +fprintf(stderr,"slicestring: slice=[%lu:%lu:%lu/%lu]\n", +slice->first,slice->stride,slice->stop,slice->declsize); +#endif + + /* Stride across string; if we go past end of string, then pad*/ + charcount = 0; + for(i=slice->first;ilength;i+=slice->stride) { + if(i < stringlen) + *memory->next = stringmem[i]; + else /* i >= stringlen*/ + *memory->next = NC_FILL_CHAR; + memory->next++; + charcount++; + } + lastchar = (memory->next); + if(charcount > 0) { + lastchar--; + } + + return THROW(ncstat); +} + +/* +Extract data for a netcdf variable that has a string dimension. +*/ +static int +extractstring( + NCDAPCOMMON* nccomm, + Getvara* xgetvar, + CDFnode* xnode, + DCEsegment* segment, + OClink conn, + OCdata currentcontent, + struct NCMEMORY* memory + ) +{ + NCerror ncstat = NC_NOERR; + OCerror ocstat = OC_NOERR; + int i; + size_t rank; + int caching = FLAGSET(nccomm->controls,NCF_CACHE); + int unconstrainable = FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE); + NClist* strings = NULL; + Dapodometer* odom = OCNULL; + + rank = segment->rank; + + /* A number of optimizations are possible but none is currently used. */ + + /* Use the odometer to walk to the appropriate fields*/ + if(rank == 1) { + odom = newdapodometer1(1); /* scalar case */ + } else if(caching || unconstrainable) { + odom = newdapodometer(segment->slices,0,rank-1); + } else { /*Since vara was projected out, build a simple odometer*/ + odom = newsimpledapodometer(segment,rank-1); + } + + /* step thru the odometer obtaining each string and storing it in an OClist */ + strings = nclistnew(); + nclistsetalloc(strings,dapodometerspace(odom,0)); /* preallocate */ + while(dapodometermore(odom)) { + char* value = NULL; + size_t dimoffset = dapodometercount(odom); + ocstat = oc_data_get(conn,currentcontent,&value,sizeof(value),dimoffset,1); + if(ocstat != OC_NOERR) goto done; + nclistpush(strings,(ncelem)value); + dapodometerincr(odom); + } + freedapodometer(odom); + /* Get each string in turn, slice it and store in user + supplied memory */ + for(i=0;islices[rank-1],memory); + free(s); + } + nclistfree(strings); +done: + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); + return THROW(ncstat); +} diff --git a/extern/src_netcdf4/lookup3.c b/extern/src_netcdf4/lookup3.c new file mode 100644 index 0000000000000000000000000000000000000000..525cdffb2518b62a9cd7dc16dd0480ad646910df --- /dev/null +++ b/extern/src_netcdf4/lookup3.c @@ -0,0 +1,1017 @@ +/* +------------------------------------------------------------------------------- +lookup3.c, by Bob Jenkins, May 2006, Public Domain. +Original: http://burtleburtle.net/bob/c/lookup3.c +Modified by Russ Rew for adaption in netCDF. +- Make use of Paul Hsieh's pstdint.h, if stdint.h not available. +- Declare unused functions static to keep global namespace clean. +- Provide function hash_fast() that uses either hashlittle() or + hashbig(), depending on endianness. +- Because portability is more important than speed for netCDF use, + we define VALGRIND to skip "#ifndef VALGRIND" code, so reads of + strings don't access extra bytes after end of string. This may + slow it down enough to justify a simpler hash, but blame me, not + original author! + +These are functions for producing 32-bit hashes for hash table lookup. +hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() +are externally useful functions. Routines to test the hash are included +if SELF_TEST is defined. You can use this free for any purpose. It's in +the public domain. It has no warranty. + +You probably want to use hashlittle(). hashlittle() and hashbig() +hash byte arrays. hashlittle() is is faster than hashbig() on +little-endian machines. Intel and AMD are little-endian machines. +On second thought, you probably want hashlittle2(), which is identical to +hashlittle() except it returns two 32-bit hashes for the price of one. +You could implement hashbig2() if you wanted but I haven't bothered here. + +If you want to find a hash of, say, exactly 7 integers, do + a = i1; b = i2; c = i3; + mix(a,b,c); + a += i4; b += i5; c += i6; + mix(a,b,c); + a += i7; + final(a,b,c); +then use c as the hash value. If you have a variable length array of +4-byte integers to hash, use hashword(). If you have a byte array (like +a character string), use hashlittle(). If you have several byte arrays, or +a mix of things, see the comments above hashlittle(). + +Why is this so big? I read 12 bytes at a time into 3 4-byte integers, +then mix those integers. This is fast (you can do a lot more thorough +mixing with 12*3 instructions on 3 integers than you can with 3 instructions +on 1 byte), but shoehorning those bytes into integers efficiently is messy. +------------------------------------------------------------------------------- +*/ +/* #define SELF_TEST 1 */ + +#include +#include /* defines printf for tests */ +#include /* defines time_t for timings in the test */ +#ifndef HAVE_STDINT_H +# include "pstdint.h" /* attempts to define uint32_t etc portably */ +#else +# include +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_SYS_PARAM_H +#include /* attempt to define endianness */ +#endif /* HAVE_SYS_PARAM_H */ +#ifdef linux +# include /* attempt to define endianness */ +#endif + +#define VALGRIND /* added by Russ Rew, for portability over speed */ + +#ifndef WORDS_BIGENDIAN /* from config.h */ +#define HASH_LITTLE_ENDIAN 1 +#define HASH_BIG_ENDIAN 0 +#else +#define HASH_LITTLE_ENDIAN 0 +#define HASH_BIG_ENDIAN 1 +#endif + +#define hashsize(n) ((uint32_t)1<<(n)) +#define hashmask(n) (hashsize(n)-1) +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/* +------------------------------------------------------------------------------- +mix -- mix 3 32-bit values reversibly. + +This is reversible, so any information in (a,b,c) before mix() is +still in (a,b,c) after mix(). + +If four pairs of (a,b,c) inputs are run through mix(), or through +mix() in reverse, there are at least 32 bits of the output that +are sometimes the same for one pair and different for another pair. +This was tested for: +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that +satisfy this are + 4 6 8 16 19 4 + 9 15 3 18 27 15 + 14 9 3 7 17 3 +Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing +for "differ" defined as + with a one-bit base and a two-bit delta. I +used http://burtleburtle.net/bob/hash/avalanche.html to choose +the operations, constants, and arrangements of the variables. + +This does not achieve avalanche. There are input bits of (a,b,c) +that fail to affect some output bits of (a,b,c), especially of a. The +most thoroughly mixed value is c, but it doesn't really even achieve +avalanche in c. + +This allows some parallelism. Read-after-writes are good at doubling +the number of bits affected, so the goal of mixing pulls in the opposite +direction as the goal of parallelism. I did what I could. Rotates +seem to cost as much as shifts on every machine I could lay my hands +on, and rotates are much kinder to the top and bottom bits, so I used +rotates. +------------------------------------------------------------------------------- +*/ +#define mix(a,b,c) \ +{ \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ +} + +/* +------------------------------------------------------------------------------- +final -- final mixing of 3 32-bit values (a,b,c) into c + +Pairs of (a,b,c) values differing in only a few bits will usually +produce values of c that look totally different. This was tested for +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +These constants passed: + 14 11 25 16 4 14 24 + 12 14 25 16 4 14 24 +and these came close: + 4 8 15 26 3 22 24 + 10 8 15 26 3 22 24 + 11 8 15 26 3 22 24 +------------------------------------------------------------------------------- +*/ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c,4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} + +/* +-------------------------------------------------------------------- + This works on all machines. To be useful, it requires + -- that the key be an array of uint32_t's, and + -- that the length be the number of uint32_t's in the key + + The function hashword() is identical to hashlittle() on little-endian + machines, and identical to hashbig() on big-endian machines, + except that the length has to be measured in uint32_ts rather than in + bytes. hashlittle() is more complicated than hashword() only because + hashlittle() has to dance around fitting the key bytes into registers. +-------------------------------------------------------------------- +*/ +#ifdef SELF_TEST +static +uint32_t hashword( +const uint32_t *k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t initval) /* the previous hash, or an arbitrary value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + final(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + return c; +} + +/* +-------------------------------------------------------------------- +hashword2() -- same as hashword(), but take two seeds and return two +32-bit values. pc and pb must both be nonnull, and *pc and *pb must +both be initialized with seeds. If you pass in (*pb)==0, the output +(*pc) will be the same as the return value from hashword(). +-------------------------------------------------------------------- +*/ +static +void hashword2 ( +const uint32_t *k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t *pc, /* IN: seed OUT: primary hash value */ +uint32_t *pb) /* IN: more seed OUT: secondary hash value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; + c += *pb; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + final(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + *pc=c; *pb=b; +} + +/* + * hashlittle2: return 2 32-bit hash values + * + * This is identical to hashlittle(), except it returns two 32-bit hash + * values instead of just one. This is good enough for hash table + * lookup with 2^^64 buckets, or if you want a second hash if you're not + * happy with the first, or if you want a probably-unique 64-bit ID for + * the key. *pc is better mixed than *pb, so use *pc first. If you want + * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". + */ +static void +hashlittle2( + const void *key, /* the key to hash */ + size_t length, /* length of the key */ + uint32_t *pc, /* IN: primary initval, OUT: primary hash */ + uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ +{ + uint32_t a,b,c; /* internal state */ + union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; + c += *pb; + + u.ptr = key; + if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + const uint8_t *k8; + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + } + + final(a,b,c); + *pc=c; *pb=b; +} +#endif /*SELF_TEST*/ + + +#ifdef WORDS_BIGENDIAN +/* + * hashbig(): + * This is the same as hashword() on big-endian machines. It is different + * from hashlittle() on all machines. hashbig() takes advantage of + * big-endian byte ordering. + */ +static uint32_t +hashbig( const void *key, size_t length, uint32_t initval) +{ + uint32_t a,b,c; + union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; + + u.ptr = key; + if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + const uint8_t *k8; + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]<<8" actually reads beyond the end of the string, but + * then shifts out the part it's not allowed to read. Because the + * string is aligned, the illegal read is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; + case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; + case 5 : b+=k[1]&0xff000000; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff00; break; + case 2 : a+=k[0]&0xffff0000; break; + case 1 : a+=k[0]&0xff000000; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ + case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ + case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ + case 1 : a+=((uint32_t)k8[0])<<24; break; + case 0 : return c; + } + +#endif /* !VALGRIND */ + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += ((uint32_t)k[0])<<24; + a += ((uint32_t)k[1])<<16; + a += ((uint32_t)k[2])<<8; + a += ((uint32_t)k[3]); + b += ((uint32_t)k[4])<<24; + b += ((uint32_t)k[5])<<16; + b += ((uint32_t)k[6])<<8; + b += ((uint32_t)k[7]); + c += ((uint32_t)k[8])<<24; + c += ((uint32_t)k[9])<<16; + c += ((uint32_t)k[10])<<8; + c += ((uint32_t)k[11]); + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[11]; + case 11: c+=((uint32_t)k[10])<<8; + case 10: c+=((uint32_t)k[9])<<16; + case 9 : c+=((uint32_t)k[8])<<24; + case 8 : b+=k[7]; + case 7 : b+=((uint32_t)k[6])<<8; + case 6 : b+=((uint32_t)k[5])<<16; + case 5 : b+=((uint32_t)k[4])<<24; + case 4 : a+=k[3]; + case 3 : a+=((uint32_t)k[2])<<8; + case 2 : a+=((uint32_t)k[1])<<16; + case 1 : a+=((uint32_t)k[0])<<24; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} +#endif /*WORDS_BIGENDIAN*/ + +/* +------------------------------------------------------------------------------- +hashlittle() -- hash a variable-length key into a 32-bit value + k : the key (the unaligned variable-length array of bytes) + length : the length of the key, counting by bytes + initval : can be any 4-byte value +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Two keys differing by one or two bits will have +totally different hash values. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (uint8_t **)k, do it like this: + for (i=0, h=0; i 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : return c; + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : return c; /* zero length requires no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + + +/* + * hash_fast(key, length, initval) + * Wrapper that calls either hashlittle or hashbig, depending on endianness. + */ +uint32_t +hash_fast( const void *key, size_t length) { +#define NC_ARBITRARY_UINT (992099683U) +#ifndef WORDS_BIGENDIAN + return hashlittle(key, length, NC_ARBITRARY_UINT); +#else + return hashbig(key, length, NC_ARBITRARY_UINT); +#endif +} + +#ifdef SELF_TEST +/* used for timings */ +void driver1() +{ + uint8_t buf[256]; + uint32_t i; + uint32_t h=0; + time_t a,z; + + time(&a); + for (i=0; i<256; ++i) buf[i] = 'x'; + for (i=0; i<1; ++i) + { + h = hashlittle(&buf[0],1,h); + } + time(&z); + if (z-a > 0) printf("time %d %.8x\n", z-a, h); +} + +/* check that every input bit changes every output bit half the time */ +#define HASHSTATE 1 +#define HASHLEN 1 +#define MAXPAIR 60 +#define MAXLEN 70 +void driver2() +{ + uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; + uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; + uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; + uint32_t x[HASHSTATE],y[HASHSTATE]; + uint32_t hlen; + + printf("No more than %d trials should ever be needed \n",MAXPAIR/2); + for (hlen=0; hlen < MAXLEN; ++hlen) + { + z=0; + for (i=0; i>(8-j)); + c[0] = hashlittle(a, hlen, m); + b[i] ^= ((k+1)<>(8-j)); + d[0] = hashlittle(b, hlen, m); + /* check every bit is 1, 0, set, and not set at least once */ + for (l=0; lz) z=k; + if (k==MAXPAIR) + { + printf("Some bit didn't change: "); + printf("%.8x %.8x %.8x %.8x %.8x %.8x ", + e[0],f[0],g[0],h[0],x[0],y[0]); + printf("i %d j %d m %d len %d\n", i, j, m, hlen); + } + if (z==MAXPAIR) goto done; + } + } + } + done: + if (z < MAXPAIR) + { + printf("Mix success %2d bytes %2d initvals ",i,m); + printf("required %d trials\n", z/2); + } + } + printf("\n"); +} + +/* Check for reading beyond the end of the buffer and alignment problems */ +void driver3() +{ + uint8_t buf[MAXLEN+20], *b; + uint32_t len; + uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; + uint32_t h; + uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; + uint32_t i; + uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; + uint32_t j; + uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; + uint32_t ref,x,y; + uint8_t *p; + + printf("Endianness. These lines should all be the same (for values filled in):\n"); + printf("%.8x %.8x %.8x\n", + hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13), + hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13), + hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13)); + p = q; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qq[1]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qqq[2]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qqqq[3]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + printf("\n"); + + /* check that hashlittle2 and hashlittle produce the same results */ + i=47; j=0; + hashlittle2(q, sizeof(q), &i, &j); + if (hashlittle(q, sizeof(q), 47) != i) + printf("hashlittle2 and hashlittle mismatch\n"); + + /* check that hashword2 and hashword produce the same results */ + len = 0xdeadbeef; + i=47, j=0; + hashword2(&len, 1, &i, &j); + if (hashword(&len, 1, 47) != i) + printf("hashword2 and hashword mismatch %x %x\n", + i, hashword(&len, 1, 47)); + + /* check hashlittle doesn't read before or after the ends of the string */ + for (h=0, b=buf+1; h<8; ++h, ++b) + { + for (i=0; i +#include +#include +#define lseek64 lseek +#endif + +#include "config.h" +#include +#include +#include +#include +#ifdef _MSC_VER /* Microsoft Compilers */ +#include +#else +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#include "nc.h" + +#undef DEBUG + +#ifdef DEBUG +#include +#endif + +#ifndef HAVE_SSIZE_T +#define ssize_t int +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +/* Define the mode flags for create: let umask rule */ +#define OPENMODE 0666 + +#include "ncio.h" +#include "fbits.h" +#include "rnd.h" + +/* #define INSTRUMENT 1 */ +#if INSTRUMENT /* debugging */ +#undef NDEBUG +#include +/*#include "instr.h"*/ +#endif + +#ifndef MEMIO_MAXBLOCKSIZE +#define MEMIO_MAXBLOCKSIZE 268435456 /* sanity check, about X_SIZE_T_MAX/8 */ +#endif + +#undef MIN /* system may define MIN somewhere and complain */ +#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn)) + +#if !defined(NDEBUG) && !defined(X_INT_MAX) +#define X_INT_MAX 2147483647 +#endif + +#if 0 /* !defined(NDEBUG) && !defined(X_ALIGN) */ +#define X_ALIGN 4 +#else +#undef X_ALIGN +#endif + +/* Private data for memio */ + +typedef struct NCMEMIO { + int locked; /* => we cannot realloc */ + int persist; /* => save to a file; triggered by NC_WRITE */ + char* memory; + off_t alloc; + off_t size; + off_t pos; +} NCMEMIO; + +/* Forward */ +static int memio_rel(ncio *const nciop, off_t offset, int rflags); +static int memio_get(ncio *const nciop, off_t offset, size_t extent, int rflags, void **const vpp); +static int memio_move(ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags); +static int memio_sync(ncio *const nciop); +static int memio_filesize(ncio* nciop, off_t* filesizep); +static int memio_pad_length(ncio* nciop, off_t length); +static int memio_close(ncio* nciop, int); + +/* Mnemonic */ +#define DOOPEN 1 + +static long pagesize = 0; + +/* Create a new ncio struct to hold info about the file. */ +static int +memio_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMEMIO** memiop) +{ + int status = NC_NOERR; + ncio* nciop = NULL; + NCMEMIO* memio = NULL; + int openfd = -1; + + if(pagesize == 0) { + +#if defined (_WIN32) || defined(_WIN64) + SYSTEM_INFO info; + GetSystemInfo (&info); + pagesize = info.dwPageSize; +#elif defined HAVE_SYSCONF + pagesize = sysconf(_SC_PAGE_SIZE); +#elif defined HAVE_GETPAGESIZE + pagesize = getpagesize(); +#else + pagesize = 4096; /* good guess */ +#endif + } + + errno = 0; + + /* Always force the allocated size to be a multiple of pagesize */ + if(initialsize == 0) initialsize = pagesize; + if((initialsize % pagesize) != 0) + initialsize += (pagesize - (initialsize % pagesize)); + + nciop = (ncio* )calloc(1,sizeof(ncio)); + if(nciop == NULL) {status = NC_ENOMEM; goto fail;} + + nciop->ioflags = ioflags; + *((int*)&nciop->fd) = -1; /* caller will fix */ + + *((char**)&nciop->path) = strdup(path); + if(nciop->path == NULL) {status = NC_ENOMEM; goto fail;} + + *((ncio_relfunc**)&nciop->rel) = memio_rel; + *((ncio_getfunc**)&nciop->get) = memio_get; + *((ncio_movefunc**)&nciop->move) = memio_move; + *((ncio_syncfunc**)&nciop->sync) = memio_sync; + *((ncio_filesizefunc**)&nciop->filesize) = memio_filesize; + *((ncio_pad_lengthfunc**)&nciop->pad_length) = memio_pad_length; + *((ncio_closefunc**)&nciop->close) = memio_close; + + memio = (NCMEMIO*)calloc(1,sizeof(NCMEMIO)); + if(memio == NULL) {status = NC_ENOMEM; goto fail;} + *((void* *)&nciop->pvt) = memio; + + memio->alloc = initialsize; + + memio->memory = NULL; + memio->size = 0; + memio->pos = 0; + memio->persist = fIsSet(ioflags,NC_WRITE); + + if(nciopp) *nciopp = nciop; + if(memiop) *memiop = memio; + +done: + if(openfd >= 0) close(openfd); + return status; + +fail: + if(nciop != NULL) { + if(nciop->path != NULL) free((char*)nciop->path); + } + goto done; +} + +/* Create a file, and the ncio struct to go with it. This function is + only called from nc__create_mp. + + path - path of file to create. + ioflags - flags from nc_create + initialsz - From the netcdf man page: "The argument + Iinitialsize sets the initial size of the file at creation time." + igeto - + igetsz - + sizehintp - the size of a page of data for buffered reads and writes. + nciopp - pointer to a pointer that will get location of newly + created and inited ncio struct. + mempp - pointer to pointer to the initial memory read. +*/ +int +memio_create(const char* path, int ioflags, + size_t initialsz, + off_t igeto, size_t igetsz, size_t* sizehintp, + ncio* *nciopp, void** const mempp) +{ + ncio* nciop; + int fd; + int status; + NCMEMIO* memio = NULL; + int persist = (ioflags & NC_WRITE?1:0); + int oflags; + + if(path == NULL ||* path == 0) + return NC_EINVAL; + + /* For diskless open has, the file must be classic version 1 or 2.*/ + if(fIsSet(ioflags,NC_NETCDF4)) + return NC_EDISKLESS; /* violates constraints */ + + status = memio_new(path, ioflags, initialsz, &nciop, &memio); + if(status != NC_NOERR) + return status; + memio->size = 0; + + if(!persist) { + memio->memory = (char*)malloc(memio->alloc); + if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;} + } else { /*persist */ + /* Open the file, but make sure we can write it if needed */ + oflags = (persist ? O_RDWR : O_RDONLY); +#ifdef O_BINARY + fSet(oflags, O_BINARY); +#endif + oflags |= (O_CREAT|O_TRUNC); + if(fIsSet(ioflags,NC_NOCLOBBER)) + oflags |= O_EXCL; +#ifdef vms + fd = open(path, oflags, 0, "ctx=stm"); +#else + fd = open(path, oflags, OPENMODE); +#endif + if(fd < 0) {status = errno; goto unwind_open;} + + (void)close(fd); /* will reopen at nc_close */ + /* malloc memory */ + memio->memory = (char*)malloc(memio->alloc); + if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;} + } /*!persist*/ + +#ifdef DEBUG +fprintf(stderr,"memio_create: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc); +#endif + + fd = nc__pseudofd(); + *((int* )&nciop->fd) = fd; + + fSet(nciop->ioflags, NC_WRITE); + + if(igetsz != 0) + { + status = nciop->get(nciop, + igeto, igetsz, + RGN_WRITE, + mempp); + if(status != NC_NOERR) + goto unwind_open; + } + + /* Pick a default sizehint */ + if(sizehintp) *sizehintp = pagesize; + + *nciopp = nciop; + return NC_NOERR; + +unwind_open: + memio_close(nciop,1); + return status; +} + +/* This function opens the data file. It is only called from nc.c, + from nc__open_mp and nc_delete_mp. + + path - path of data file. + ioflags - flags passed into nc_open. + igeto - looks like this function can do an initial page get, and + igeto is going to be the offset for that. But it appears to be + unused + igetsz - the size in bytes of initial page get (a.k.a. extent). Not + ever used in the library. + sizehintp - the size of a page of data for buffered reads and writes. + nciopp - pointer to pointer that will get address of newly created + and inited ncio struct. + mempp - pointer to pointer to the initial memory read. +*/ +int +memio_open(const char* path, + int ioflags, + off_t igeto, size_t igetsz, size_t* sizehintp, + ncio* *nciopp, void** const mempp) +{ + ncio* nciop; + int fd; + int status; + int persist = (fIsSet(ioflags,NC_WRITE)?1:0); + int oflags; + NCMEMIO* memio = NULL; + size_t sizehint; + off_t filesize; + + if(path == NULL ||* path == 0) + return EINVAL; + + assert(sizehintp != NULL); + sizehint = *sizehintp; + + /* Open the file, but make sure we can write it if needed */ + oflags = (persist ? O_RDWR : O_RDONLY); +#ifdef O_BINARY + fSet(oflags, O_BINARY); +#endif + oflags |= O_EXCL; +#ifdef vms + fd = open(path, oflags, 0, "ctx=stm"); +#else + fd = open(path, oflags, OPENMODE); +#endif +#ifdef DEBUG + if(fd < 0) { + fprintf(stderr,"open failed: file=%s err=",path); + perror(""); + } +#endif + if(fd < 0) {status = errno; goto unwind_open;} + + /* get current filesize = max(|file|,initialize)*/ + filesize = lseek(fd,0,SEEK_END); + if(filesize < 0) {status = errno; goto unwind_open;} + /* move pointer back to beginning of file */ + (void)lseek(fd,0,SEEK_SET); + if(filesize < (off_t)sizehint) + filesize = (off_t)sizehint; + + status = memio_new(path, ioflags, filesize, &nciop, &memio); + if(status != NC_NOERR) + return status; + memio->size = filesize; + + memio->memory = (char*)malloc(memio->alloc); + if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;} + +#ifdef DEBUG +fprintf(stderr,"memio_open: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc); +#endif + + /* Read the file into the memio memory */ + /* We need to do multiple reads because there is no + guarantee that the amount read will be the full amount */ + { + off_t red = memio->size; + char* pos = memio->memory; + while(red > 0) { + ssize_t count = read(fd, pos, red); + if(count < 0) + {close(fd); status = errno; goto unwind_open;} + if(count == 0) + {close(fd); status = NC_ENOTNC; goto unwind_open;} + red -= count; + pos += count; + } + } + (void)close(fd); /* until memio_close() */ + + /* Use half the filesize as the blocksize */ + sizehint = filesize/2; + + fd = nc__pseudofd(); + *((int* )&nciop->fd) = fd; + + if(igetsz != 0) + { + status = nciop->get(nciop, + igeto, igetsz, + 0, + mempp); + if(status != NC_NOERR) + goto unwind_open; + } + + *sizehintp = sizehint; + *nciopp = nciop; + return NC_NOERR; + +unwind_open: + memio_close(nciop,0); + return status; +} + + +/* + * Get file size in bytes. + */ +static int +memio_filesize(ncio* nciop, off_t* filesizep) +{ + NCMEMIO* memio; + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + memio = (NCMEMIO*)nciop->pvt; + if(filesizep != NULL) *filesizep = memio->size; + return NC_NOERR; +} + +/* + * Sync any changes to disk, then truncate or extend file so its size + * is length. This is only intended to be called before close, if the + * file is open for writing and the actual size does not match the + * calculated size, perhaps as the result of having been previously + * written in NOFILL mode. + */ +static int +memio_pad_length(ncio* nciop, off_t length) +{ + NCMEMIO* memio; + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + memio = (NCMEMIO*)nciop->pvt; + + if(!fIsSet(nciop->ioflags, NC_WRITE)) + return EPERM; /* attempt to write readonly file*/ + + if(memio->locked > 0) + return NC_EDISKLESS; + + if(length > memio->alloc) { + /* Realloc the allocated memory to a multiple of the pagesize*/ + off_t newsize = length; + void* newmem = NULL; + /* Round to a multiple of pagesize */ + if((newsize % pagesize) != 0) + newsize += (pagesize - (newsize % pagesize)); + + newmem = (char*)realloc(memio->memory,newsize); + if(newmem == NULL) return NC_ENOMEM; + + /* zero out the extra memory */ + memset((void*)(newmem+memio->alloc),0,(newsize - memio->alloc)); + +#ifdef DEBUG +fprintf(stderr,"realloc: %lu/%lu -> %lu/%lu\n", +(unsigned long)memio->memory,(unsigned long)memio->alloc, +(unsigned long)newmem,(unsigned long)newsize); +#endif + memio->memory = newmem; + memio->alloc = newsize; + } + memio->size = length; + return NC_NOERR; +} + +/* Write out any dirty buffers to disk and + ensure that next read will get data from disk. + Sync any changes, then close the open file associated with the ncio + struct, and free its memory. + nciop - pointer to ncio to close. + doUnlink - if true, unlink file +*/ + +static int +memio_close(ncio* nciop, int doUnlink) +{ + int status = NC_NOERR; + NCMEMIO* memio; + int fd = -1; + if(nciop == NULL || nciop->pvt == NULL) return NC_NOERR; + + memio = (NCMEMIO*)nciop->pvt; + assert(memio != NULL); + + /* See if the user wants the contents persisted to a file */ + if(memio->persist) { + /* Try to open the file for writing */ + int oflags = O_WRONLY|O_CREAT|O_TRUNC; +#ifdef O_BINARY + fSet(oflags, O_BINARY); +#endif + fd = open(nciop->path, oflags, OPENMODE); + if(fd >= 0) { + /* We need to do multiple writes because there is no + guarantee that the amount written will be the full amount */ + off_t written = memio->size; + char* pos = memio->memory; + while(written > 0) { + ssize_t count = write(fd, pos, written); + if(count < 0) + {status = errno; goto done;} + if(count == 0) + {status = NC_ENOTNC; goto done;} + written -= count; + pos += count; + } + } else + status = errno; + /* Free up things */ + if(memio->memory != NULL) free(memio->memory); + } + +done: + /* do cleanup */ + if(fd >= 0) (void)close(fd); + if(memio != NULL) free(memio); + if(nciop->path != NULL) free((char*)nciop->path); + free(nciop); + return status; +} + +static int +guarantee(ncio* nciop, off_t endpoint) +{ + NCMEMIO* memio = (NCMEMIO*)nciop->pvt; + if(endpoint > memio->alloc) { + /* extend the allocated memory and size */ + int status = memio_pad_length(nciop,endpoint); + if(status != NC_NOERR) return status; + } + if(memio->size < endpoint) + memio->size = endpoint; + return NC_NOERR; +} + +/* + * Request that the region (offset, extent) + * be made available through *vpp. + */ +static int +memio_get(ncio* const nciop, off_t offset, size_t extent, int rflags, void** const vpp) +{ + int status = NC_NOERR; + NCMEMIO* memio; + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + memio = (NCMEMIO*)nciop->pvt; + status = guarantee(nciop, offset+extent); + memio->locked++; + if(status != NC_NOERR) return status; + if(vpp) *vpp = memio->memory+offset; + return NC_NOERR; +} + +/* + * Like memmove(), safely move possibly overlapping data. + */ +static int +memio_move(ncio* const nciop, off_t to, off_t from, size_t nbytes, int ignored) +{ + int status = NC_NOERR; + NCMEMIO* memio; + + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + memio = (NCMEMIO*)nciop->pvt; + if(from < to) { + /* extend if "to" is not currently allocated */ + status = guarantee(nciop,to+nbytes); + if(status != NC_NOERR) return status; + } + /* check for overlap */ + if((to + nbytes) > from || (from + nbytes) > to) { + /* Ranges overlap */ +#ifdef HAVE_MEMMOVE + memmove((void*)(memio->memory+to),(void*)(memio->memory+from),nbytes); +#else + off_t overlap; + off_t nbytes1; + if((from + nbytes) > to) { + overlap = ((from + nbytes) - to); /* # bytes of overlap */ + nbytes1 = (nbytes - overlap); /* # bytes of non-overlap */ + /* move the non-overlapping part */ + memcpy((void*)(memio->memory+(to+overlap)), + (void*)(memio->memory+(from+overlap)), + nbytes1); + /* move the overlapping part */ + memcpy((void*)(memio->memory+to), + (void*)(memio->memory+from), + overlap); + } else { /*((to + nbytes) > from) */ + overlap = ((to + nbytes) - from); /* # bytes of overlap */ + nbytes1 = (nbytes - overlap); /* # bytes of non-overlap */ + /* move the non-overlapping part */ + memcpy((void*)(memio->memory+to), + (void*)(memio->memory+from), + nbytes1); + /* move the overlapping part */ + memcpy((void*)(memio->memory+(to+nbytes1)), + (void*)(memio->memory+(from+nbytes1)), + overlap); + } +#endif + } else {/* no overlap */ + memcpy((void*)(memio->memory+to),(void*)(memio->memory+from),nbytes); + } + return status; +} + +static int +memio_rel(ncio* const nciop, off_t offset, int rflags) +{ + NCMEMIO* memio; + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + memio = (NCMEMIO*)nciop->pvt; + memio->locked--; + return NC_NOERR; /* do nothing */ +} + +/* + * Write out any dirty buffers to disk and + * ensure that next read will get data from disk. + */ +static int +memio_sync(ncio* const nciop) +{ + return NC_NOERR; /* do nothing */ +} diff --git a/extern/src_netcdf4/mmapio.c b/extern/src_netcdf4/mmapio.c new file mode 100644 index 0000000000000000000000000000000000000000..b80b9435a27e3599f41c10859c2e0f6d45bb7f31 --- /dev/null +++ b/extern/src_netcdf4/mmapio.c @@ -0,0 +1,595 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ + +#include "config.h" +#include +#include +#include +#include +#ifdef _MSC_VER /* Microsoft Compilers */ +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#include "nc.h" + +#undef DEBUG + +#ifdef DEBUG +#include +#endif + +#include + +#ifndef MAP_ANONYMOUS +# ifdef MAP_ANON +# define MAP_ANONYMOUS MAP_ANON +# endif +#endif + +/* !MAP_ANONYMOUS => !HAVE_MMAP */ +#ifndef MAP_ANONYMOUS +#error mmap not fully implemented: missing MAP_ANONYMOUS +#endif + +#ifdef HAVE_MMAP + /* This is conditionalized by __USE_GNU ; why? */ + extern void *mremap(void*,size_t,size_t,int); +# ifndef MREMAP_MAYMOVE +# define MREMAP_MAYMOVE 1 +# endif +#endif /*HAVE_MMAP*/ + +#ifndef HAVE_SSIZE_T +#define ssize_t int +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +/* Define the mode flags for create: let umask decide */ +#define OPENMODE 0666 + +#include "ncio.h" +#include "fbits.h" +#include "rnd.h" + +/* #define INSTRUMENT 1 */ +#if INSTRUMENT /* debugging */ +#undef NDEBUG +#include +/*#include "instr.h"*/ +#endif + +#ifndef MMAP_MAXBLOCKSIZE +#define MMAP_MAXBLOCKSIZE 268435456 /* sanity check, about X_SIZE_T_MAX/8 */ +#endif + +#undef MIN /* system may define MIN somewhere and complain */ +#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn)) + +#if !defined(NDEBUG) && !defined(X_INT_MAX) +#define X_INT_MAX 2147483647 +#endif + +#if 0 /* !defined(NDEBUG) && !defined(X_ALIGN) */ +#define X_ALIGN 4 +#else +#undef X_ALIGN +#endif + +/* Private data for mmap */ + +typedef struct NCMMAPIO { + int locked; /* => we cannot realloc */ + int persist; /* => save to a file; triggered by NC_WRITE */ + char* memory; + off_t alloc; + off_t size; + off_t pos; + int mapfd; +} NCMMAPIO; + +/* Forward */ +static int mmapio_rel(ncio *const nciop, off_t offset, int rflags); +static int mmapio_get(ncio *const nciop, off_t offset, size_t extent, int rflags, void **const vpp); +static int mmapio_move(ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags); +static int mmapio_sync(ncio *const nciop); +static int mmapio_filesize(ncio* nciop, off_t* filesizep); +static int mmapio_pad_length(ncio* nciop, off_t length); +static int mmapio_close(ncio* nciop, int); + +/* Mnemonic */ +#define DOOPEN 1 + +static long pagesize = 0; + +/* Create a new ncio struct to hold info about the file. */ +static int +mmapio_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMMAPIO** mmapp) +{ + int status = NC_NOERR; + ncio* nciop = NULL; + NCMMAPIO* mmapio = NULL; + int openfd = -1; + + if(pagesize == 0) { +#if defined HAVE_SYSCONF + pagesize = sysconf(_SC_PAGE_SIZE); +#elif defined HAVE_GETPAGESIZE + pagesize = getpagesize(); +#else + pagesize = 4096; /* good guess */ +#endif + } + + errno = 0; + + /* Always force the allocated size to be a multiple of pagesize */ + if(initialsize == 0) initialsize = pagesize; + if((initialsize % pagesize) != 0) + initialsize += (pagesize - (initialsize % pagesize)); + + nciop = (ncio* )calloc(1,sizeof(ncio)); + if(nciop == NULL) {status = NC_ENOMEM; goto fail;} + + nciop->ioflags = ioflags; + *((int*)&nciop->fd) = -1; /* caller will fix */ + + *((char**)&nciop->path) = strdup(path); + if(nciop->path == NULL) {status = NC_ENOMEM; goto fail;} + + *((ncio_relfunc**)&nciop->rel) = mmapio_rel; + *((ncio_getfunc**)&nciop->get) = mmapio_get; + *((ncio_movefunc**)&nciop->move) = mmapio_move; + *((ncio_syncfunc**)&nciop->sync) = mmapio_sync; + *((ncio_filesizefunc**)&nciop->filesize) = mmapio_filesize; + *((ncio_pad_lengthfunc**)&nciop->pad_length) = mmapio_pad_length; + *((ncio_closefunc**)&nciop->close) = mmapio_close; + + mmapio = (NCMMAPIO*)calloc(1,sizeof(NCMMAPIO)); + if(mmapio == NULL) {status = NC_ENOMEM; goto fail;} + *((void* *)&nciop->pvt) = mmapio; + + mmapio->alloc = initialsize; + + mmapio->memory = NULL; + mmapio->size = 0; + mmapio->pos = 0; + mmapio->persist = fIsSet(ioflags,NC_WRITE); + + /* See if ok to use mmap */ + if(sizeof(void*) < 8 && fIsSet(ioflags,NC_64BIT_OFFSET)) + return NC_DISKLESS; /* cannot support */ + mmapio->mapfd = -1; + + if(nciopp) *nciopp = nciop; + if(mmapp) *mmapp = mmapio; + +done: + if(openfd >= 0) close(openfd); + return status; + +fail: + if(nciop != NULL) { + if(nciop->path != NULL) free((char*)nciop->path); + } + goto done; +} + +/* Create a file, and the ncio struct to go with it. This function is + only called from nc__create_mp. + + path - path of file to create. + ioflags - flags from nc_create + initialsz - From the netcdf man page: "The argument + Iinitialsize sets the initial size of the file at creation time." + igeto - + igetsz - + sizehintp - the size of a page of data for buffered reads and writes. + nciopp - pointer to a pointer that will get location of newly + created and inited ncio struct. + mempp - pointer to pointer to the initial memory read. +*/ +int +mmapio_create(const char* path, int ioflags, + size_t initialsz, + off_t igeto, size_t igetsz, size_t* sizehintp, + ncio* *nciopp, void** const mempp) +{ + ncio* nciop; + int fd; + int status; + NCMMAPIO* mmapio = NULL; + int persist = (ioflags & NC_WRITE?1:0); + int oflags; + + if(path == NULL ||* path == 0) + return NC_EINVAL; + + /* For diskless open has, the file must be classic version 1 or 2.*/ + if(fIsSet(ioflags,NC_NETCDF4)) + return NC_EDISKLESS; /* violates constraints */ + + status = mmapio_new(path, ioflags, initialsz, &nciop, &mmapio); + if(status != NC_NOERR) + return status; + mmapio->size = 0; + + if(!persist) { + mmapio->mapfd = -1; + mmapio->memory = (char*)mmap(NULL,mmapio->alloc, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, + mmapio->mapfd,0); + {mmapio->memory[0] = 0;} /* test writing of the mmap'd memory */ + } else { /*persist */ + /* Open the file, but make sure we can write it if needed */ + oflags = (persist ? O_RDWR : O_RDONLY); +#ifdef O_BINARY + fSet(oflags, O_BINARY); +#endif + oflags |= (O_CREAT|O_TRUNC); + if(fIsSet(ioflags,NC_NOCLOBBER)) + oflags |= O_EXCL; +#ifdef vms + fd = open(path, oflags, 0, "ctx=stm"); +#else + fd = open(path, oflags, OPENMODE); +#endif + if(fd < 0) {status = errno; goto unwind_open;} + mmapio->mapfd = fd; + + { /* Cause the output file to have enough allocated space */ + lseek(fd,mmapio->alloc-1,SEEK_SET); /* cause file to appear */ + write(fd,"",mmapio->alloc); + lseek(fd,0,SEEK_SET); /* rewind */ + } + mmapio->memory = (char*)mmap(NULL,mmapio->alloc, + PROT_READ|PROT_WRITE, + MAP_SHARED, + mmapio->mapfd,0); + if(mmapio->memory == NULL) { + return NC_EDISKLESS; + } + } /*!persist*/ + +#ifdef DEBUG +fprintf(stderr,"mmap_create: initial memory: %lu/%lu\n",(unsigned long)mmapio->memory,(unsigned long)mmapio->alloc); +#endif + + fd = nc__pseudofd(); + *((int* )&nciop->fd) = fd; + + fSet(nciop->ioflags, NC_WRITE); + + if(igetsz != 0) + { + status = nciop->get(nciop, + igeto, igetsz, + RGN_WRITE, + mempp); + if(status != NC_NOERR) + goto unwind_open; + } + + /* Pick a default sizehint */ + if(sizehintp) *sizehintp = pagesize; + + *nciopp = nciop; + return NC_NOERR; + +unwind_open: + mmapio_close(nciop,1); + return status; +} + +/* This function opens the data file. It is only called from nc.c, + from nc__open_mp and nc_delete_mp. + + path - path of data file. + ioflags - flags passed into nc_open. + igeto - looks like this function can do an initial page get, and + igeto is going to be the offset for that. But it appears to be + unused + igetsz - the size in bytes of initial page get (a.k.a. extent). Not + ever used in the library. + sizehintp - the size of a page of data for buffered reads and writes. + nciopp - pointer to pointer that will get address of newly created + and inited ncio struct. + mempp - pointer to pointer to the initial memory read. +*/ +int +mmapio_open(const char* path, + int ioflags, + off_t igeto, size_t igetsz, size_t* sizehintp, + ncio* *nciopp, void** const mempp) +{ + ncio* nciop; + int fd; + int status; + int persist = (fIsSet(ioflags,NC_WRITE)?1:0); + int oflags; + NCMMAPIO* mmapio = NULL; + size_t sizehint; + off_t filesize; + + if(path == NULL ||* path == 0) + return EINVAL; + + assert(sizehintp != NULL); + sizehint = *sizehintp; + + /* Open the file, but make sure we can write it if needed */ + oflags = (persist ? O_RDWR : O_RDONLY); +#ifdef O_BINARY + fSet(oflags, O_BINARY); +#endif + oflags |= O_EXCL; +#ifdef vms + fd = open(path, oflags, 0, "ctx=stm"); +#else + fd = open(path, oflags, OPENMODE); +#endif + if(fd < 0) {status = errno; goto unwind_open;} + + /* get current filesize = max(|file|,initialize)*/ + filesize = lseek(fd,0,SEEK_END); + if(filesize < 0) {status = errno; goto unwind_open;} + /* move pointer back to beginning of file */ + (void)lseek(fd,0,SEEK_SET); + if(filesize < (off_t)sizehint) + filesize = (off_t)sizehint; + + status = mmapio_new(path, ioflags, filesize, &nciop, &mmapio); + if(status != NC_NOERR) + return status; + mmapio->size = filesize; + + mmapio->mapfd = fd; + mmapio->memory = (char*)mmap(NULL,mmapio->alloc, + persist?(PROT_READ|PROT_WRITE):(PROT_READ), + MAP_SHARED, + mmapio->mapfd,0); +#ifdef DEBUG +fprintf(stderr,"mmapio_open: initial memory: %lu/%lu\n",(unsigned long)mmapio->memory,(unsigned long)mmapio->alloc); +#endif + + /* Use half the filesize as the blocksize */ + sizehint = filesize/2; + + fd = nc__pseudofd(); + *((int* )&nciop->fd) = fd; + + if(igetsz != 0) + { + status = nciop->get(nciop, + igeto, igetsz, + 0, + mempp); + if(status != NC_NOERR) + goto unwind_open; + } + + *sizehintp = sizehint; + *nciopp = nciop; + return NC_NOERR; + +unwind_open: + mmapio_close(nciop,0); + return status; +} + + +/* + * Get file size in bytes. + */ +static int +mmapio_filesize(ncio* nciop, off_t* filesizep) +{ + NCMMAPIO* mmapio; + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + mmapio = (NCMMAPIO*)nciop->pvt; + if(filesizep != NULL) *filesizep = mmapio->size; + return NC_NOERR; +} + +/* + * Sync any changes to disk, then truncate or extend file so its size + * is length. This is only intended to be called before close, if the + * file is open for writing and the actual size does not match the + * calculated size, perhaps as the result of having been previously + * written in NOFILL mode. + */ +static int +mmapio_pad_length(ncio* nciop, off_t length) +{ + NCMMAPIO* mmapio; + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + mmapio = (NCMMAPIO*)nciop->pvt; + + if(!fIsSet(nciop->ioflags, NC_WRITE)) + return EPERM; /* attempt to write readonly file*/ + + if(mmapio->locked > 0) + return NC_EDISKLESS; + + if(length > mmapio->alloc) { + /* Realloc the allocated memory to a multiple of the pagesize*/ + off_t newsize = length; + void* newmem = NULL; + /* Round to a multiple of pagesize */ + if((newsize % pagesize) != 0) + newsize += (pagesize - (newsize % pagesize)); + + /* Force file size to be properly extended */ + { /* Cause the output file to have enough allocated space */ + off_t pos = lseek(mmapio->mapfd,0,SEEK_CUR); /* save current position*/ + /* cause file to be extended in size */ + lseek(mmapio->mapfd,newsize-1,SEEK_SET); + write(mmapio->mapfd,"",mmapio->alloc); + lseek(mmapio->mapfd,pos,SEEK_SET); /* reset position */ + } + + newmem = (char*)mremap(mmapio->memory,mmapio->alloc,newsize,MREMAP_MAYMOVE); + if(newmem == NULL) return NC_ENOMEM; + +#ifdef DEBUG +fprintf(stderr,"realloc: %lu/%lu -> %lu/%lu\n", +(unsigned long)mmapio->memory,(unsigned long)mmapio->alloc, +(unsigned long)newmem,(unsigned long)newsize); +#endif + mmapio->memory = newmem; + mmapio->alloc = newsize; + } + mmapio->size = length; + return NC_NOERR; +} + +/* Write out any dirty buffers to disk and + ensure that next read will get data from disk. + Sync any changes, then close the open file associated with the ncio + struct, and free its memory. + nciop - pointer to ncio to close. + doUnlink - if true, unlink file +*/ + +static int +mmapio_close(ncio* nciop, int doUnlink) +{ + int status = NC_NOERR; + NCMMAPIO* mmapio; + if(nciop == NULL || nciop->pvt == NULL) return NC_NOERR; + + mmapio = (NCMMAPIO*)nciop->pvt; + assert(mmapio != NULL); + + /* Since we are using mmap, persisting to a file should be automatic */ + status = munmap(mmapio->memory,mmapio->alloc); + mmapio->memory = NULL; /* so we do not try to free it */ + + /* Close file if it was open */ + if(mmapio->mapfd >= 0) + close(mmapio->mapfd); + + /* do cleanup */ + if(mmapio != NULL) free(mmapio); + if(nciop->path != NULL) free((char*)nciop->path); + free(nciop); + return status; +} + +static int +guarantee(ncio* nciop, off_t endpoint) +{ + NCMMAPIO* mmapio = (NCMMAPIO*)nciop->pvt; + if(endpoint > mmapio->alloc) { + /* extend the allocated memory and size */ + int status = mmapio_pad_length(nciop,endpoint); + if(status != NC_NOERR) return status; + } + if(mmapio->size < endpoint) + mmapio->size = endpoint; + return NC_NOERR; +} + +/* + * Request that the region (offset, extent) + * be made available through *vpp. + */ +static int +mmapio_get(ncio* const nciop, off_t offset, size_t extent, int rflags, void** const vpp) +{ + int status = NC_NOERR; + NCMMAPIO* mmapio; + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + mmapio = (NCMMAPIO*)nciop->pvt; + status = guarantee(nciop, offset+extent); + mmapio->locked++; + if(status != NC_NOERR) return status; + if(vpp) *vpp = mmapio->memory+offset; + return NC_NOERR; +} + +/* + * Like memmove(), safely move possibly overlapping data. + */ +static int +mmapio_move(ncio* const nciop, off_t to, off_t from, size_t nbytes, int ignored) +{ + int status = NC_NOERR; + NCMMAPIO* mmapio; + + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + mmapio = (NCMMAPIO*)nciop->pvt; + if(from < to) { + /* extend if "to" is not currently allocated */ + status = guarantee(nciop,to+nbytes); + if(status != NC_NOERR) return status; + } + /* check for overlap */ + if((to + nbytes) > from || (from + nbytes) > to) { + /* Ranges overlap */ +#ifdef HAVE_MEMMOVE + memmove((void*)(mmapio->memory+to),(void*)(mmapio->memory+from),nbytes); +#else + off_t overlap; + off_t nbytes1; + if((from + nbytes) > to) { + overlap = ((from + nbytes) - to); /* # bytes of overlap */ + nbytes1 = (nbytes - overlap); /* # bytes of non-overlap */ + /* move the non-overlapping part */ + memcpy((void*)(mmapio->memory+(to+overlap)), + (void*)(mmapio->memory+(from+overlap)), + nbytes1); + /* move the overlapping part */ + memcpy((void*)(mmapio->memory+to), + (void*)(mmapio->memory+from), + overlap); + } else { /*((to + nbytes) > from) */ + overlap = ((to + nbytes) - from); /* # bytes of overlap */ + nbytes1 = (nbytes - overlap); /* # bytes of non-overlap */ + /* move the non-overlapping part */ + memcpy((void*)(mmapio->memory+to), + (void*)(mmapio->memory+from), + nbytes1); + /* move the overlapping part */ + memcpy((void*)(mmapio->memory+(to+nbytes1)), + (void*)(mmapio->memory+(from+nbytes1)), + overlap); + } +#endif + } else {/* no overlap */ + memcpy((void*)(mmapio->memory+to),(void*)(mmapio->memory+from),nbytes); + } + return status; +} + +static int +mmapio_rel(ncio* const nciop, off_t offset, int rflags) +{ + NCMMAPIO* mmapio; + if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; + mmapio = (NCMMAPIO*)nciop->pvt; + mmapio->locked--; + return NC_NOERR; /* do nothing */ +} + +/* + * Write out any dirty buffers to disk and + * ensure that next read will get data from disk. + */ +static int +mmapio_sync(ncio* const nciop) +{ + return NC_NOERR; /* do nothing */ +} diff --git a/extern/src_netcdf4/nc.c b/extern/src_netcdf4/nc.c new file mode 100644 index 0000000000000000000000000000000000000000..c11f922e570e1964809c5d189f12c987a555bb6a --- /dev/null +++ b/extern/src_netcdf4/nc.c @@ -0,0 +1,1559 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ + +#include +#include +#include +#include +#if defined(LOCKNUMREC) /* && _CRAYMPP */ +# include +# include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "nc.h" +#include "ncdispatch.h" +#include "nc3dispatch.h" +#include "rnd.h" +#include "ncx.h" + +/* This is the default create format for nc_create and nc__create. */ +int default_create_format = NC_FORMAT_CLASSIC; + +/* These have to do with version numbers. */ +#define MAGIC_NUM_LEN 4 +#define VER_CLASSIC 1 +#define VER_64BIT_OFFSET 2 +#define VER_HDF5 3 + +int +NC_check_id(int ncid, NC **ncpp) +{ + NC* nc = find_in_NCList(ncid); + if(nc == NULL) return NC_EBADID; + if(ncpp) *ncpp = nc; + return NC_NOERR; +} + +static void +free_NC(NC *ncp) +{ + if(ncp == NULL) + return; + free_NC_dimarrayV(&ncp->dims); + free_NC_attrarrayV(&ncp->attrs); + free_NC_vararrayV(&ncp->vars); + if (ncp->path) + free(ncp->path); +#if _CRAYMPP && defined(LOCKNUMREC) + shfree(ncp); +#else + free(ncp); +#endif /* _CRAYMPP && LOCKNUMREC */ +} + +static NC * +new_NC(const size_t *chunkp, NC_Dispatch* dispatch) +{ + NC *ncp; + int stat = dispatch->new_nc(&ncp); + if(stat) return NULL; + ncp->xsz = MIN_NC_XSZ; + assert(ncp->xsz == ncx_len_NC(ncp,0)); + ncp->chunk = chunkp != NULL ? *chunkp : NC_SIZEHINT_DEFAULT; + return ncp; +} + +static NC * +dup_NC(const NC *ref) +{ + NC *ncp; + int stat = ref->dispatch->new_nc(&ncp); + if(stat) return NULL; + if(ncp == NULL) + return NULL; + + if(dup_NC_dimarrayV(&ncp->dims, &ref->dims) != NC_NOERR) + goto err; + if(dup_NC_attrarrayV(&ncp->attrs, &ref->attrs) != NC_NOERR) + goto err; + if(dup_NC_vararrayV(&ncp->vars, &ref->vars) != NC_NOERR) + goto err; + + ncp->xsz = ref->xsz; + ncp->begin_var = ref->begin_var; + ncp->begin_rec = ref->begin_rec; + ncp->recsize = ref->recsize; + NC_set_numrecs(ncp, NC_get_numrecs(ref)); + return ncp; +err: + free_NC(ncp); + return NULL; +} + + +/* + * Verify that this is a user nc_type + * Formerly +NCcktype() + * Sense of the return is changed. + */ +int +nc_cktype(nc_type type) +{ + switch((int)type){ + case NC_BYTE: + case NC_CHAR: + case NC_SHORT: + case NC_INT: + case NC_FLOAT: + case NC_DOUBLE: + return(NC_NOERR); + } + return(NC_EBADTYPE); +} + + +/* + * How many objects of 'type' + * will fit into xbufsize? + */ +size_t +ncx_howmany(nc_type type, size_t xbufsize) +{ + switch(type){ + case NC_BYTE: + case NC_CHAR: + return xbufsize; + case NC_SHORT: + return xbufsize/X_SIZEOF_SHORT; + case NC_INT: + return xbufsize/X_SIZEOF_INT; + case NC_FLOAT: + return xbufsize/X_SIZEOF_FLOAT; + case NC_DOUBLE: + return xbufsize/X_SIZEOF_DOUBLE; + default: + assert("ncx_howmany: Bad type" == 0); + return(0); + } +} + +#define D_RNDUP(x, align) _RNDUP(x, (off_t)(align)) + +/* + * Compute each variable's 'begin' offset, + * update 'begin_rec' as well. + */ +static int +NC_begins(NC *ncp, + size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align) +{ + size_t ii; + int sizeof_off_t; + off_t index = 0; + NC_var **vpp; + NC_var *last = NULL; + + if(v_align == NC_ALIGN_CHUNK) + v_align = ncp->chunk; + if(r_align == NC_ALIGN_CHUNK) + r_align = ncp->chunk; + + if (fIsSet(ncp->flags, NC_64BIT_OFFSET)) { + sizeof_off_t = 8; + } else { + sizeof_off_t = 4; + } + + ncp->xsz = ncx_len_NC(ncp,sizeof_off_t); + + if(ncp->vars.nelems == 0) + return NC_NOERR; + + /* only (re)calculate begin_var if there is not sufficient space in header + or start of non-record variables is not aligned as requested by valign */ + if (ncp->begin_var < ncp->xsz + h_minfree || + ncp->begin_var != D_RNDUP(ncp->begin_var, v_align) ) + { + index = (off_t) ncp->xsz; + ncp->begin_var = D_RNDUP(index, v_align); + if(ncp->begin_var < index + h_minfree) + { + ncp->begin_var = D_RNDUP(index + (off_t)h_minfree, v_align); + } + } + index = ncp->begin_var; + + /* loop thru vars, first pass is for the 'non-record' vars */ + vpp = ncp->vars.value; + for(ii = 0; ii < ncp->vars.nelems ; ii++, vpp++) + { + if( IS_RECVAR(*vpp) ) + { + /* skip record variables on this pass */ + continue; + } +#if 0 +fprintf(stderr, " VAR %d %s: %ld\n", ii, (*vpp)->name->cp, (long)index); +#endif + if( sizeof_off_t == 4 && (index > X_OFF_MAX || index < 0) ) + { + return NC_EVARSIZE; + } + (*vpp)->begin = index; + index += (*vpp)->len; + } + + /* only (re)calculate begin_rec if there is not sufficient + space at end of non-record variables or if start of record + variables is not aligned as requested by r_align */ + if (ncp->begin_rec < index + v_minfree || + ncp->begin_rec != D_RNDUP(ncp->begin_rec, r_align) ) + { + ncp->begin_rec = D_RNDUP(index, r_align); + if(ncp->begin_rec < index + v_minfree) + { + ncp->begin_rec = D_RNDUP(index + (off_t)v_minfree, r_align); + } + } + index = ncp->begin_rec; + + ncp->recsize = 0; + + /* loop thru vars, second pass is for the 'record' vars */ + vpp = (NC_var **)ncp->vars.value; + for(ii = 0; ii < ncp->vars.nelems; ii++, vpp++) + { + if( !IS_RECVAR(*vpp) ) + { + /* skip non-record variables on this pass */ + continue; + } + +#if 0 +fprintf(stderr, " REC %d %s: %ld\n", ii, (*vpp)->name->cp, (long)index); +#endif + if( sizeof_off_t == 4 && (index > X_OFF_MAX || index < 0) ) + { + return NC_EVARSIZE; + } + (*vpp)->begin = index; + index += (*vpp)->len; + /* check if record size must fit in 32-bits */ +#if SIZEOF_OFF_T == SIZEOF_SIZE_T && SIZEOF_SIZE_T == 4 + if( ncp->recsize > X_UINT_MAX - (*vpp)->len ) + { + return NC_EVARSIZE; + } +#endif + if((*vpp)->len != UINT32_MAX) /* flag for vars >= 2**32 bytes */ + ncp->recsize += (*vpp)->len; + last = (*vpp); + } + + /* + * for special case of + */ + if(last != NULL) { + if(ncp->recsize == last->len) { /* exactly one record variable, pack value */ + ncp->recsize = *last->dsizes * last->xsz; + } else if(last->len == UINT32_MAX) { /* huge last record variable */ + ncp->recsize += *last->dsizes * last->xsz; + } + } + if(NC_IsNew(ncp)) + NC_set_numrecs(ncp, 0); + return NC_NOERR; +} + + +/* + * Read just the numrecs member. + * (A relatively expensive way to do things.) + */ +int +read_numrecs(NC *ncp) +{ + int status = NC_NOERR; + const void *xp = NULL; + size_t nrecs = NC_get_numrecs(ncp); + + assert(!NC_indef(ncp)); + +#define NC_NUMRECS_OFFSET 4 +#define NC_NUMRECS_EXTENT 4 + status = ncio_get(ncp->nciop, + NC_NUMRECS_OFFSET, NC_NUMRECS_EXTENT, 0, (void **)&xp); + /* cast away const */ + if(status != NC_NOERR) + return status; + + status = ncx_get_size_t(&xp, &nrecs); + + (void) ncio_rel(ncp->nciop, NC_NUMRECS_OFFSET, 0); + + if(status == NC_NOERR) + { + NC_set_numrecs(ncp, nrecs); + fClr(ncp->flags, NC_NDIRTY); + } + + return status; +} + + +/* + * Write out just the numrecs member. + * (A relatively expensive way to do things.) + */ +int +write_numrecs(NC *ncp) +{ + int status = NC_NOERR; + void *xp = NULL; + + assert(!NC_readonly(ncp)); + assert(!NC_indef(ncp)); + + status = ncio_get(ncp->nciop, + NC_NUMRECS_OFFSET, NC_NUMRECS_EXTENT, RGN_WRITE, &xp); + if(status != NC_NOERR) + return status; + + { + const size_t nrecs = NC_get_numrecs(ncp); + status = ncx_put_size_t(&xp, &nrecs); + } + + (void) ncio_rel(ncp->nciop, NC_NUMRECS_OFFSET, RGN_MODIFIED); + + if(status == NC_NOERR) + fClr(ncp->flags, NC_NDIRTY); + + return status; +} + + +/* + * Read in the header + * It is expensive. + */ +static int +read_NC(NC *ncp) +{ + int status = NC_NOERR; + + free_NC_dimarrayV(&ncp->dims); + free_NC_attrarrayV(&ncp->attrs); + free_NC_vararrayV(&ncp->vars); + + status = nc_get_NC(ncp); + + if(status == NC_NOERR) + fClr(ncp->flags, NC_NDIRTY | NC_HDIRTY); + + return status; +} + + +/* + * Write out the header + */ +static int +write_NC(NC *ncp) +{ + int status = NC_NOERR; + + assert(!NC_readonly(ncp)); + + status = ncx_put_NC(ncp, NULL, 0, 0); + + if(status == NC_NOERR) + fClr(ncp->flags, NC_NDIRTY | NC_HDIRTY); + + return status; +} + + +/* + * Write the header or the numrecs if necessary. + */ +int +NC_sync(NC *ncp) +{ + assert(!NC_readonly(ncp)); + + if(NC_hdirty(ncp)) + { + return write_NC(ncp); + } + /* else */ + + if(NC_ndirty(ncp)) + { + return write_numrecs(ncp); + } + /* else */ + + return NC_NOERR; +} + + +/* + * Initialize the 'non-record' variables. + */ +static int +fillerup(NC *ncp) +{ + int status = NC_NOERR; + size_t ii; + NC_var **varpp; + + assert(!NC_readonly(ncp)); + assert(NC_dofill(ncp)); + + /* loop thru vars */ + varpp = ncp->vars.value; + for(ii = 0; ii < ncp->vars.nelems; ii++, varpp++) + { + if(IS_RECVAR(*varpp)) + { + /* skip record variables */ + continue; + } + + status = fill_NC_var(ncp, *varpp, (*varpp)->len, 0); + if(status != NC_NOERR) + break; + } + return status; +} + +/* Begin endef */ + +/* + */ +static int +fill_added_recs(NC *gnu, NC *old) +{ + NC_var ** const gnu_varpp = (NC_var **)gnu->vars.value; + + const int old_nrecs = (int) NC_get_numrecs(old); + int recno = 0; + NC_var **vpp = gnu_varpp; + NC_var *const *const end = &vpp[gnu->vars.nelems]; + int numrecvars = 0; + + /* Determine if there is only one record variable. If so, we + must treat as a special case because there's no record padding */ + for(; vpp < end; vpp++) { + if(IS_RECVAR(*vpp)) { + numrecvars++; + } + } + + for(; recno < old_nrecs; recno++) + { + int varid = (int)old->vars.nelems; + for(; varid < (int)gnu->vars.nelems; varid++) + { + const NC_var *const gnu_varp = *(gnu_varpp + varid); + if(!IS_RECVAR(gnu_varp)) + { + /* skip non-record variables */ + continue; + } + /* else */ + { + size_t varsize = numrecvars == 1 ? gnu->recsize : gnu_varp->len; + const int status = fill_NC_var(gnu, gnu_varp, varsize, recno); + if(status != NC_NOERR) + return status; + } + } + } + return NC_NOERR; +} + +/* + */ +static int +fill_added(NC *gnu, NC *old) +{ + NC_var ** const gnu_varpp = (NC_var **)gnu->vars.value; + int varid = (int)old->vars.nelems; + + for(; varid < (int)gnu->vars.nelems; varid++) + { + const NC_var *const gnu_varp = *(gnu_varpp + varid); + if(IS_RECVAR(gnu_varp)) + { + /* skip record variables */ + continue; + } + /* else */ + { + const int status = fill_NC_var(gnu, gnu_varp, gnu_varp->len, 0); + if(status != NC_NOERR) + return status; + } + } + + return NC_NOERR; +} + + +/* + * Move the records "out". + * Fill as needed. + */ +static int +move_recs_r(NC *gnu, NC *old) +{ + int status; + int recno; + int varid; + NC_var **gnu_varpp = (NC_var **)gnu->vars.value; + NC_var **old_varpp = (NC_var **)old->vars.value; + NC_var *gnu_varp; + NC_var *old_varp; + off_t gnu_off; + off_t old_off; + const size_t old_nrecs = NC_get_numrecs(old); + + /* Don't parallelize this loop */ + for(recno = (int)old_nrecs -1; recno >= 0; recno--) + { + /* Don't parallelize this loop */ + for(varid = (int)old->vars.nelems -1; varid >= 0; varid--) + { + gnu_varp = *(gnu_varpp + varid); + if(!IS_RECVAR(gnu_varp)) + { + /* skip non-record variables on this pass */ + continue; + } + /* else */ + + /* else, a pre-existing variable */ + old_varp = *(old_varpp + varid); + gnu_off = gnu_varp->begin + (off_t)(gnu->recsize * recno); + old_off = old_varp->begin + (off_t)(old->recsize * recno); + + if(gnu_off == old_off) + continue; /* nothing to do */ + + assert(gnu_off > old_off); + + status = ncio_move(gnu->nciop, gnu_off, old_off, + old_varp->len, 0); + + if(status != NC_NOERR) + return status; + + } + } + + NC_set_numrecs(gnu, old_nrecs); + + return NC_NOERR; +} + + +/* + * Move the "non record" variables "out". + * Fill as needed. + */ +static int +move_vars_r(NC *gnu, NC *old) +{ + int status; + int varid; + NC_var **gnu_varpp = (NC_var **)gnu->vars.value; + NC_var **old_varpp = (NC_var **)old->vars.value; + NC_var *gnu_varp; + NC_var *old_varp; + off_t gnu_off; + off_t old_off; + + /* Don't parallelize this loop */ + for(varid = (int)old->vars.nelems -1; + varid >= 0; varid--) + { + gnu_varp = *(gnu_varpp + varid); + if(IS_RECVAR(gnu_varp)) + { + /* skip record variables on this pass */ + continue; + } + /* else */ + + old_varp = *(old_varpp + varid); + gnu_off = gnu_varp->begin; + old_off = old_varp->begin; + + if(gnu_off == old_off) + continue; /* nothing to do */ + + assert(gnu_off > old_off); + + status = ncio_move(gnu->nciop, gnu_off, old_off, + old_varp->len, 0); + + if(status != NC_NOERR) + return status; + + } + + return NC_NOERR; +} + + +/* + * Given a valid ncp, return NC_EVARSIZE if any variable has a bad len + * (product of non-rec dim sizes too large), else return NC_NOERR. + */ +static int +NC_check_vlens(NC *ncp) +{ + NC_var **vpp; + /* maximum permitted variable size (or size of one record's worth + of a record variable) in bytes. This is different for format 1 + and format 2. */ + size_t vlen_max; + size_t ii; + size_t large_vars_count; + size_t rec_vars_count; + int last = 0; + + if(ncp->vars.nelems == 0) + return NC_NOERR; + + if ((ncp->flags & NC_64BIT_OFFSET) && sizeof(off_t) > 4) { + /* CDF2 format and LFS */ + vlen_max = X_UINT_MAX - 3; /* "- 3" handles rounded-up size */ + } else { + /* CDF1 format */ + vlen_max = X_INT_MAX - 3; + } + /* Loop through vars, first pass is for non-record variables. */ + large_vars_count = 0; + rec_vars_count = 0; + vpp = ncp->vars.value; + for (ii = 0; ii < ncp->vars.nelems; ii++, vpp++) { + if( !IS_RECVAR(*vpp) ) { + last = 0; + if( NC_check_vlen(*vpp, vlen_max) == 0 ) { + large_vars_count++; + last = 1; + } + } else { + rec_vars_count++; + } + } + /* OK if last non-record variable size too large, since not used to + compute an offset */ + if( large_vars_count > 1) { /* only one "too-large" variable allowed */ + return NC_EVARSIZE; + } + /* and it has to be the last one */ + if( large_vars_count == 1 && last == 0) { + return NC_EVARSIZE; + } + if( rec_vars_count > 0 ) { + /* and if it's the last one, there can't be any record variables */ + if( large_vars_count == 1 && last == 1) { + return NC_EVARSIZE; + } + /* Loop through vars, second pass is for record variables. */ + large_vars_count = 0; + vpp = ncp->vars.value; + for (ii = 0; ii < ncp->vars.nelems; ii++, vpp++) { + if( IS_RECVAR(*vpp) ) { + last = 0; + if( NC_check_vlen(*vpp, vlen_max) == 0 ) { + large_vars_count++; + last = 1; + } + } + } + /* OK if last record variable size too large, since not used to + compute an offset */ + if( large_vars_count > 1) { /* only one "too-large" variable allowed */ + return NC_EVARSIZE; + } + /* and it has to be the last one */ + if( large_vars_count == 1 && last == 0) { + return NC_EVARSIZE; + } + } + return NC_NOERR; +} + + +/* + * End define mode. + * Common code for ncendef, ncclose(endef) + * Flushes I/O buffers. + */ +static int +NC_endef(NC *ncp, + size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align) +{ + int status = NC_NOERR; + + assert(!NC_readonly(ncp)); + assert(NC_indef(ncp)); + + status = NC_check_vlens(ncp); + if(status != NC_NOERR) + return status; + status = NC_begins(ncp, h_minfree, v_align, v_minfree, r_align); + if(status != NC_NOERR) + return status; + + if(ncp->old != NULL) + { + /* a plain redef, not a create */ + assert(!NC_IsNew(ncp)); + assert(fIsSet(ncp->flags, NC_INDEF)); + assert(ncp->begin_rec >= ncp->old->begin_rec); + assert(ncp->begin_var >= ncp->old->begin_var); + + if(ncp->vars.nelems != 0) + { + if(ncp->begin_rec > ncp->old->begin_rec) + { + status = move_recs_r(ncp, ncp->old); + if(status != NC_NOERR) + return status; + if(ncp->begin_var > ncp->old->begin_var) + { + status = move_vars_r(ncp, ncp->old); + if(status != NC_NOERR) + return status; + } + /* else if (ncp->begin_var == ncp->old->begin_var) { NOOP } */ + } + else + { /* Even if (ncp->begin_rec == ncp->old->begin_rec) + and (ncp->begin_var == ncp->old->begin_var) + might still have added a new record variable */ + if(ncp->recsize > ncp->old->recsize) + { + status = move_recs_r(ncp, ncp->old); + if(status != NC_NOERR) + return status; + } + } + } + } + + status = write_NC(ncp); + if(status != NC_NOERR) + return status; + + if(NC_dofill(ncp)) + { + if(NC_IsNew(ncp)) + { + status = fillerup(ncp); + if(status != NC_NOERR) + return status; + + } + else if(ncp->vars.nelems > ncp->old->vars.nelems) + { + status = fill_added(ncp, ncp->old); + if(status != NC_NOERR) + return status; + status = fill_added_recs(ncp, ncp->old); + if(status != NC_NOERR) + return status; + } + } + + if(ncp->old != NULL) + { + free_NC(ncp->old); + ncp->old = NULL; + } + + fClr(ncp->flags, NC_CREAT | NC_INDEF); + + return ncio_sync(ncp->nciop); +} + +#ifdef LOCKNUMREC +static int +NC_init_pe(NC *ncp, int basepe) { + if (basepe < 0 || basepe >= _num_pes()) { + return NC_EINVAL; /* invalid base pe */ + } + /* initialize common values */ + ncp->lock[LOCKNUMREC_VALUE] = 0; + ncp->lock[LOCKNUMREC_LOCK] = 0; + ncp->lock[LOCKNUMREC_SERVING] = 0; + ncp->lock[LOCKNUMREC_BASEPE] = basepe; + return NC_NOERR; +} +#endif + + +/* + * Compute the expected size of the file. + */ +int +NC_calcsize(const NC *ncp, off_t *calcsizep) +{ + NC_var **vpp = (NC_var **)ncp->vars.value; + NC_var *const *const end = &vpp[ncp->vars.nelems]; + NC_var *last_fix = NULL; /* last "non-record" var */ + int numrecvars = 0; /* number of record variables */ + + if(ncp->vars.nelems == 0) { /* no non-record variables and + no record variables */ + *calcsizep = ncp->xsz; /* size of header */ + return NC_NOERR; + } + + for( /*NADA*/; vpp < end; vpp++) { + if(IS_RECVAR(*vpp)) { + numrecvars++; + } else { + last_fix = *vpp; + } + } + + if(numrecvars == 0) { + off_t varsize; + assert(last_fix != NULL); + varsize = last_fix->len; + if(last_fix->len == X_UINT_MAX) { /* huge last fixed var */ + int i; + varsize = 1; + for(i = 0; i < last_fix->ndims; i++ ) { + varsize *= last_fix->shape[i]; + } + } + *calcsizep = last_fix->begin + varsize; + /*last_var = last_fix;*/ + } else { /* we have at least one record variable */ + *calcsizep = ncp->begin_rec + ncp->numrecs * ncp->recsize; + } + + return NC_NOERR; +} + +/* Public */ + +int NC3_new_nc(NC** ncpp) +{ + NC *ncp; + +#if _CRAYMPP && defined(LOCKNUMREC) + ncp = (NC *) shmalloc(sizeof(NC)); +#else + ncp = (NC *) malloc(sizeof(NC)); +#endif /* _CRAYMPP && LOCKNUMREC */ + if(ncp == NULL) + return NC_ENOMEM; + (void) memset(ncp, 0, sizeof(NC)); + + ncp->xsz = MIN_NC_XSZ; + assert(ncp->xsz == ncx_len_NC(ncp,0)); + + if(ncpp) *ncpp = ncp; + return NC_NOERR; + +} + +/* WARNING: SIGNATURE CHANGE */ +int +NC3_create(const char *path, int ioflags, + size_t initialsz, int basepe, + size_t *chunksizehintp, + int use_parallel, void* parameters, + NC_Dispatch* dispatch, NC** ncpp) +{ + NC *ncp; + int status; + void *xp = NULL; + int sizeof_off_t = 0; + +#if ALWAYS_NC_SHARE /* DEBUG */ + fSet(ioflags, NC_SHARE); +#endif + + ncp = new_NC(chunksizehintp,dispatch); + if(ncp == NULL) + return NC_ENOMEM; + +#if defined(LOCKNUMREC) /* && _CRAYMPP */ + if (status = NC_init_pe(ncp, basepe)) { + return status; + } +#else + /* + * !_CRAYMPP, only pe 0 is valid + */ + if(basepe != 0) + return NC_EINVAL; +#endif + + assert(ncp->flags == 0); + + /* Apply default create format. */ + if (default_create_format == NC_FORMAT_64BIT) + ioflags |= NC_64BIT_OFFSET; + + if (fIsSet(ioflags, NC_64BIT_OFFSET)) { + fSet(ncp->flags, NC_64BIT_OFFSET); + sizeof_off_t = 8; + } else { + sizeof_off_t = 4; + } + + assert(ncp->xsz == ncx_len_NC(ncp,sizeof_off_t)); + + status = ncio_create(path, ioflags, initialsz, + 0, ncp->xsz, &ncp->chunk, + &ncp->nciop, &xp); + if(status != NC_NOERR) + { + /* translate error status */ + if(status == EEXIST) + status = NC_EEXIST; + goto unwind_alloc; + } + + fSet(ncp->flags, NC_CREAT); + + if(fIsSet(ncp->nciop->ioflags, NC_SHARE)) + { + /* + * NC_SHARE implies sync up the number of records as well. + * (File format version one.) + * Note that other header changes are not shared + * automatically. Some sort of IPC (external to this package) + * would be used to trigger a call to nc_sync(). + */ + fSet(ncp->flags, NC_NSYNC); + } + + status = ncx_put_NC(ncp, &xp, sizeof_off_t, ncp->xsz); + if(status != NC_NOERR) + goto unwind_ioc; + + add_to_NCList(ncp); + + if(chunksizehintp != NULL) + *chunksizehintp = ncp->chunk; + + ncp->int_ncid = ncp->nciop->fd; + + if(ncpp) *ncpp = ncp; + + return NC_NOERR; + +unwind_ioc: + (void) ncio_close(ncp->nciop, 1); /* N.B.: unlink */ + ncp->nciop = NULL; + /*FALLTHRU*/ +unwind_alloc: + free_NC(ncp); + return status; +} + +/* This function sets a default create flag that will be logically + or'd to whatever flags are passed into nc_create for all future + calls to nc_create. + Valid default create flags are NC_64BIT_OFFSET, NC_CLOBBER, + NC_LOCK, NC_SHARE. */ +int +nc_set_default_format(int format, int *old_formatp) +{ + /* Return existing format if desired. */ + if (old_formatp) + *old_formatp = default_create_format; + + /* Make sure only valid format is set. */ +#ifdef USE_NETCDF4 + if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT && + format != NC_FORMAT_NETCDF4 && format != NC_FORMAT_NETCDF4_CLASSIC) + return NC_EINVAL; +#else + if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT) + return NC_EINVAL; +#endif + default_create_format = format; + return NC_NOERR; +} + +int +NC3_open(const char * path, int ioflags, + int basepe, size_t *chunksizehintp, + int use_parallel,void* parameters, + NC_Dispatch* dispatch, NC** ncpp) +{ + NC *ncp; + int status; + +#if ALWAYS_NC_SHARE /* DEBUG */ + fSet(ioflags, NC_SHARE); +#endif + + ncp = new_NC(chunksizehintp,dispatch); + if(ncp == NULL) + return NC_ENOMEM; + +#if defined(LOCKNUMREC) /* && _CRAYMPP */ + if (status = NC_init_pe(ncp, basepe)) { + return status; + } +#else + /* + * !_CRAYMPP, only pe 0 is valid + */ + if(basepe != 0) + return NC_EINVAL; +#endif + + status = ncio_open(path, ioflags, 0, 0, &ncp->chunk, &ncp->nciop, 0); + if(status) + goto unwind_alloc; + + assert(ncp->flags == 0); + + if(fIsSet(ncp->nciop->ioflags, NC_SHARE)) + { + /* + * NC_SHARE implies sync up the number of records as well. + * (File format version one.) + * Note that other header changes are not shared + * automatically. Some sort of IPC (external to this package) + * would be used to trigger a call to nc_sync(). + */ + fSet(ncp->flags, NC_NSYNC); + } + + status = nc_get_NC(ncp); + if(status != NC_NOERR) + goto unwind_ioc; + + add_to_NCList(ncp); + + if(chunksizehintp != NULL) + *chunksizehintp = ncp->chunk; + + ncp->int_ncid = ncp->nciop->fd; + + if(ncpp) *ncpp = ncp; + + return NC_NOERR; + +unwind_ioc: + (void) ncio_close(ncp->nciop, 0); + ncp->nciop = NULL; + /*FALLTHRU*/ +unwind_alloc: + free_NC(ncp); + return status; +} + +int +NC3__enddef(int ncid, + size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align) +{ + int status; + NC *ncp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(!NC_indef(ncp)) + return(NC_ENOTINDEFINE); + + return (NC_endef(ncp, h_minfree, v_align, v_minfree, r_align)); +} + + +int +NC3_close(int ncid) +{ + int status = NC_NOERR; + NC *ncp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_indef(ncp)) + { + status = NC_endef(ncp, 0, 1, 0, 1); /* TODO: defaults */ + if(status != NC_NOERR ) + { + (void) nc_abort(ncid); + return status; + } + } + else if(!NC_readonly(ncp)) + { + status = NC_sync(ncp); + /* flush buffers before any filesize comparisons */ + (void) ncio_sync(ncp->nciop); + } + + /* + * If file opened for writing and filesize is less than + * what it should be (due to previous use of NOFILL mode), + * pad it to correct size, as reported by NC_calcsize(). + */ + if (status == ENOERR) { + off_t filesize; /* current size of open file */ + off_t calcsize; /* calculated file size, from header */ + status = ncio_filesize(ncp->nciop, &filesize); + if(status != ENOERR) + return status; + status = NC_calcsize(ncp, &calcsize); + if(status != NC_NOERR) + return status; + if(filesize < calcsize && !NC_readonly(ncp)) { + status = ncio_pad_length(ncp->nciop, calcsize); + if(status != ENOERR) + return status; + } + } + + (void) ncio_close(ncp->nciop, 0); + ncp->nciop = NULL; + + del_from_NCList(ncp); + + free_NC(ncp); + + return status; +} + +/* + * In data mode, same as ncclose. + * In define mode, restore previous definition. + * In create, remove the file. + */ +int +NC3_abort(int ncid) +{ + int status; + NC *ncp; + int doUnlink = 0; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + doUnlink = NC_IsNew(ncp); + + if(ncp->old != NULL) + { + /* a plain redef, not a create */ + assert(!NC_IsNew(ncp)); + assert(fIsSet(ncp->flags, NC_INDEF)); + free_NC(ncp->old); + ncp->old = NULL; + fClr(ncp->flags, NC_INDEF); + } + else if(!NC_readonly(ncp)) + { + status = NC_sync(ncp); + if(status != NC_NOERR) + return status; + } + + + (void) ncio_close(ncp->nciop, doUnlink); + ncp->nciop = NULL; + + del_from_NCList(ncp); + + free_NC(ncp); + + return NC_NOERR; +} + + +int +NC3_redef(int ncid) +{ + int status; + NC *ncp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_readonly(ncp)) + return NC_EPERM; + + if(NC_indef(ncp)) + return NC_EINDEFINE; + + + if(fIsSet(ncp->nciop->ioflags, NC_SHARE)) + { + /* read in from disk */ + status = read_NC(ncp); + if(status != NC_NOERR) + return status; + } + + ncp->old = dup_NC(ncp); + if(ncp->old == NULL) + return NC_ENOMEM; + + fSet(ncp->flags, NC_INDEF); + + return NC_NOERR; +} + + +int +NC3_inq(int ncid, + int *ndimsp, + int *nvarsp, + int *nattsp, + int *xtendimp) +{ + int status; + NC *ncp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(ndimsp != NULL) + *ndimsp = (int) ncp->dims.nelems; + if(nvarsp != NULL) + *nvarsp = (int) ncp->vars.nelems; + if(nattsp != NULL) + *nattsp = (int) ncp->attrs.nelems; + if(xtendimp != NULL) + *xtendimp = find_NC_Udim(&ncp->dims, NULL); + + return NC_NOERR; +} + +int +NC3_inq_unlimdim(int ncid, int *xtendimp) +{ + int status; + NC *ncp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(xtendimp != NULL) + *xtendimp = find_NC_Udim(&ncp->dims, NULL); + + return NC_NOERR; +} + +int +NC3_sync(int ncid) +{ + int status; + NC *ncp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_indef(ncp)) + return NC_EINDEFINE; + + if(NC_readonly(ncp)) + { + return read_NC(ncp); + } + /* else, read/write */ + + status = NC_sync(ncp); + if(status != NC_NOERR) + return status; + + status = ncio_sync(ncp->nciop); + if(status != NC_NOERR) + return status; + +#ifdef USE_FSYNC + /* may improve concurrent access, but slows performance if + * called frequently */ +#ifndef WIN32 + status = fsync(ncp->nciop->fd); +#else + status = _commit(ncp->nciop->fd); +#endif /* WIN32 */ +#endif /* USE_FSYNC */ + + return status; +} + + +int +NC3_set_fill(int ncid, + int fillmode, int *old_mode_ptr) +{ + int status; + NC *ncp; + int oldmode; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_readonly(ncp)) + return NC_EPERM; + + oldmode = fIsSet(ncp->flags, NC_NOFILL) ? NC_NOFILL : NC_FILL; + + if(fillmode == NC_NOFILL) + { + fSet(ncp->flags, NC_NOFILL); + } + else if(fillmode == NC_FILL) + { + if(fIsSet(ncp->flags, NC_NOFILL)) + { + /* + * We are changing back to fill mode + * so do a sync + */ + status = NC_sync(ncp); + if(status != NC_NOERR) + return status; + } + fClr(ncp->flags, NC_NOFILL); + } + else + { + return NC_EINVAL; /* Invalid fillmode */ + } + + if(old_mode_ptr != NULL) + *old_mode_ptr = oldmode; + + return NC_NOERR; +} + +#ifdef LOCKNUMREC + +/* create function versions of the NC_*_numrecs macros */ +size_t +NC_get_numrecs(const NC *ncp) { + shmem_t numrec; + shmem_short_get(&numrec, (shmem_t *) ncp->lock + LOCKNUMREC_VALUE, 1, + ncp->lock[LOCKNUMREC_BASEPE]); + return (size_t) numrec; +} + +void +NC_set_numrecs(NC *ncp, size_t nrecs) +{ + shmem_t numrec = (shmem_t) nrecs; + /* update local value too */ + ncp->lock[LOCKNUMREC_VALUE] = (ushmem_t) numrec; + shmem_short_put((shmem_t *) ncp->lock + LOCKNUMREC_VALUE, &numrec, 1, + ncp->lock[LOCKNUMREC_BASEPE]); +} + +void NC_increase_numrecs(NC *ncp, size_t nrecs) +{ + /* this is only called in one place that's already protected + * by a lock ... so don't worry about it */ + if (nrecs > NC_get_numrecs(ncp)) + NC_set_numrecs(ncp, nrecs); +} + +#endif /* LOCKNUMREC */ + +/* everyone in communicator group will be executing this */ +/*ARGSUSED*/ +int +NC3_set_base_pe(int ncid, int pe) +{ +#if _CRAYMPP && defined(LOCKNUMREC) + int status; + NC *ncp; + shmem_t numrecs; + + if ((status = NC_check_id(ncid, &ncp)) != NC_NOERR) { + return status; + } + if (pe < 0 || pe >= _num_pes()) { + return NC_EINVAL; /* invalid base pe */ + } + + numrecs = (shmem_t) NC_get_numrecs(ncp); + + ncp->lock[LOCKNUMREC_VALUE] = (ushmem_t) numrecs; + + /* update serving & lock values for a "smooth" transition */ + /* note that the "real" server will being doing this as well */ + /* as all the rest in the group */ + /* must have syncronization before & after this step */ + shmem_short_get( + (shmem_t *) ncp->lock + LOCKNUMREC_SERVING, + (shmem_t *) ncp->lock + LOCKNUMREC_SERVING, + 1, ncp->lock[LOCKNUMREC_BASEPE]); + + shmem_short_get( + (shmem_t *) ncp->lock + LOCKNUMREC_LOCK, + (shmem_t *) ncp->lock + LOCKNUMREC_LOCK, + 1, ncp->lock[LOCKNUMREC_BASEPE]); + + /* complete transition */ + ncp->lock[LOCKNUMREC_BASEPE] = (ushmem_t) pe; + +#endif /* _CRAYMPP && LOCKNUMREC */ + return NC_NOERR; +} + +/*ARGSUSED*/ +int +NC3_inq_base_pe(int ncid, int *pe) +{ +#if _CRAYMPP && defined(LOCKNUMREC) + int status; + NC *ncp; + + if ((status = NC_check_id(ncid, &ncp)) != NC_NOERR) { + return status; + } + + *pe = (int) ncp->lock[LOCKNUMREC_BASEPE]; +#else + /* + * !_CRAYMPP, only pe 0 is valid + */ + *pe = 0; +#endif /* _CRAYMPP && LOCKNUMREC */ + return NC_NOERR; +} + +int +NC3_inq_format(int ncid, int *formatp) +{ + int status; + NC *ncp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + /* only need to check for netCDF-3 variants, since this is never called for netCDF-4 + files */ + *formatp = fIsSet(ncp->flags, NC_64BIT_OFFSET) ? NC_FORMAT_64BIT + : NC_FORMAT_CLASSIC; + return NC_NOERR; +} + +/* The sizes of types may vary from platform to platform, but within + * netCDF files, type sizes are fixed. */ +#define NC_BYTE_LEN 1 +#define NC_CHAR_LEN 1 +#define NC_SHORT_LEN 2 +#define NC_INT_LEN 4 +#define NC_FLOAT_LEN 4 +#define NC_DOUBLE_LEN 8 +#define NUM_ATOMIC_TYPES 6 + +/* This netCDF-4 function proved so popular that a netCDF-classic + * version is provided. You're welcome. */ +int +NC3_inq_type(int ncid, nc_type typeid, char *name, size_t *size) +{ + int atomic_size[NUM_ATOMIC_TYPES] = {NC_BYTE_LEN, NC_CHAR_LEN, NC_SHORT_LEN, + NC_INT_LEN, NC_FLOAT_LEN, NC_DOUBLE_LEN}; + char atomic_name[NUM_ATOMIC_TYPES][NC_MAX_NAME + 1] = {"byte", "char", "short", + "int", "float", "double"}; + + /* Only netCDF classic model needs to be handled. */ + if (typeid < NC_BYTE || typeid > NC_DOUBLE) + return NC_EBADTYPE; + + /* Give the user the values they want. Subtract one because types + * are numbered starting at 1, not 0. */ + if (name) + strcpy(name, atomic_name[typeid - 1]); + if (size) + *size = atomic_size[typeid - 1]; + + return NC_NOERR; +} + +int +nc_delete_mp(const char * path, int basepe) +{ + NC *ncp; + int status; + size_t chunk = 512; + + status = NC3_new_nc(&ncp); + if(status) return status; + ncp->chunk = chunk; + +#if defined(LOCKNUMREC) /* && _CRAYMPP */ + if (status = NC_init_pe(ncp, basepe)) { + return status; + } +#else + /* + * !_CRAYMPP, only pe 0 is valid + */ + if(basepe != 0) + return NC_EINVAL; +#endif + + status = ncio_open(path, NC_NOWRITE, + 0, 0, &ncp->chunk, + &ncp->nciop, 0); + if(status) + goto unwind_alloc; + + assert(ncp->flags == 0); + + status = nc_get_NC(ncp); + if(status != NC_NOERR) + { + /* Not a netcdf file, don't delete */ + /* ??? is this the right semantic? what if it was just too big? */ + (void) ncio_close(ncp->nciop, 0); + } + else + { + /* ncio_close does the unlink */ + status = ncio_close(ncp->nciop, 1); /* ncio_close does the unlink */ + } + ncp->nciop = NULL; + + ncp->nciop = NULL; +unwind_alloc: + free_NC(ncp); + return status; +} + +int +nc_delete(const char * path) +{ + return nc_delete_mp(path, 0); +} + diff --git a/extern/src_netcdf4/nc.h b/extern/src_netcdf4/nc.h new file mode 100644 index 0000000000000000000000000000000000000000..2e920225e6c2e250b8c4e727d0345666cb1a8af7 --- /dev/null +++ b/extern/src_netcdf4/nc.h @@ -0,0 +1,429 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +#ifndef _NC_H_ +#define _NC_H_ + +/* + * netcdf library 'private' data structures, objects and interfaces + */ +#include +#include /* size_t */ +#ifndef HAVE_STDINT_H +# include "pstdint.h" /* attempts to define uint32_t etc portably */ +#else +# include +#endif /* HAVE_STDINT_H */ +#include /* off_t */ +#ifdef USE_PARALLEL +#include +#else +#include +#endif /* USE_PARALLEL */ +#if 0 +#include "ncio.h" +#include "fbits.h" +#endif + +/*#ifndef HAVE_SSIZE_T +#define ssize_t int +#endif*/ + +#ifndef NC_ARRAY_GROWBY +#define NC_ARRAY_GROWBY 4 +#endif + +/* + * The extern size of an empty + * netcdf version 1 file. + * The initial value of ncp->xsz. + */ +#define MIN_NC_XSZ 32 + +/* Forward */ +typedef struct NC NC; /* forward reference */ +struct ncio; + +/* + * The internal data types + */ +typedef enum { + NC_UNSPECIFIED = 0, +/* future NC_BITFIELD = 7, */ +/* NC_STRING = 8, */ + NC_DIMENSION = 10, + NC_VARIABLE = 11, + NC_ATTRIBUTE = 12 +} NCtype; + + +/* + * Counted string for names and such + */ +typedef struct { + /* all xdr'd */ + size_t nchars; + char *cp; +} NC_string; + +/* Begin defined in string.c */ +extern void +free_NC_string(NC_string *ncstrp); + +extern int +NC_check_name(const char *name); + +extern NC_string * +new_NC_string(size_t slen, const char *str); + +extern int +set_NC_string(NC_string *ncstrp, const char *str); + +/* End defined in string.c */ + +/* + * NC dimension stucture + */ +typedef struct { + /* all xdr'd */ + NC_string *name; + uint32_t hash; + size_t size; +} NC_dim; + +typedef struct NC_dimarray { + size_t nalloc; /* number allocated >= nelems */ + /* below gets xdr'd */ + /* NCtype type = NC_DIMENSION */ + size_t nelems; /* length of the array */ + NC_dim **value; +} NC_dimarray; + +/* Begin defined in dim.c */ + +extern void +free_NC_dim(NC_dim *dimp); + +extern NC_dim * +new_x_NC_dim(NC_string *name); + +extern int +find_NC_Udim(const NC_dimarray *ncap, NC_dim **dimpp); + +/* dimarray */ + +extern void +free_NC_dimarrayV0(NC_dimarray *ncap); + +extern void +free_NC_dimarrayV(NC_dimarray *ncap); + +extern int +dup_NC_dimarrayV(NC_dimarray *ncap, const NC_dimarray *ref); + +extern NC_dim * +elem_NC_dimarray(const NC_dimarray *ncap, size_t elem); + +/* End defined in dim.c */ + +/* + * NC attribute + */ +typedef struct { + size_t xsz; /* amount of space at xvalue */ + /* below gets xdr'd */ + NC_string *name; + nc_type type; /* the discriminant */ + size_t nelems; /* length of the array */ + void *xvalue; /* the actual data, in external representation */ +} NC_attr; + +typedef struct NC_attrarray { + size_t nalloc; /* number allocated >= nelems */ + /* below gets xdr'd */ + /* NCtype type = NC_ATTRIBUTE */ + size_t nelems; /* length of the array */ + NC_attr **value; +} NC_attrarray; + +/* Begin defined in attr.c */ + +extern void +free_NC_attr(NC_attr *attrp); + +extern NC_attr * +new_x_NC_attr( + NC_string *strp, + nc_type type, + size_t nelems); + +extern NC_attr ** +NC_findattr(const NC_attrarray *ncap, const char *name); + +/* attrarray */ + +extern void +free_NC_attrarrayV0(NC_attrarray *ncap); + +extern void +free_NC_attrarrayV(NC_attrarray *ncap); + +extern int +dup_NC_attrarrayV(NC_attrarray *ncap, const NC_attrarray *ref); + +extern NC_attr * +elem_NC_attrarray(const NC_attrarray *ncap, size_t elem); + +/* End defined in attr.c */ + + +/* + * NC variable: description and data + */ +typedef struct NC_var { + size_t xsz; /* xszof 1 element */ + size_t *shape; /* compiled info: dim->size of each dim */ + off_t *dsizes; /* compiled info: the right to left product of shape */ + /* below gets xdr'd */ + NC_string *name; + uint32_t hash; + /* next two: formerly NC_iarray *assoc */ /* user definition */ + size_t ndims; /* assoc->count */ + int *dimids; /* assoc->value */ + NC_attrarray attrs; + nc_type type; /* the discriminant */ + size_t len; /* the total length originally allocated */ + off_t begin; +} NC_var; + +typedef struct NC_vararray { + size_t nalloc; /* number allocated >= nelems */ + /* below gets xdr'd */ + /* NCtype type = NC_VARIABLE */ + size_t nelems; /* length of the array */ + NC_var **value; +} NC_vararray; + +/* Begin defined in lookup3.c */ + +extern uint32_t +hash_fast(const void *key, size_t length); + +/* End defined in lookup3.c */ + +/* Begin defined in var.c */ + +extern void +free_NC_var(NC_var *varp); + +extern NC_var * +new_x_NC_var( + NC_string *strp, + size_t ndims); + +/* vararray */ + +extern void +free_NC_vararrayV0(NC_vararray *ncap); + +extern void +free_NC_vararrayV(NC_vararray *ncap); + +extern int +dup_NC_vararrayV(NC_vararray *ncap, const NC_vararray *ref); + +extern int +NC_var_shape(NC_var *varp, const NC_dimarray *dims); + +extern int +NC_findvar(const NC_vararray *ncap, const char *name, NC_var **varpp); + +extern int +NC_check_vlen(NC_var *varp, size_t vlen_max); + +extern NC_var * +NC_lookupvar(NC *ncp, int varid); + +/* End defined in var.c */ + +#define IS_RECVAR(vp) \ + ((vp)->shape != NULL ? (*(vp)->shape == NC_UNLIMITED) : 0 ) + +#ifdef LOCKNUMREC +/* + * typedef SHMEM type + * for whenever the SHMEM functions can handle other than shorts + */ +typedef unsigned short int ushmem_t; +typedef short int shmem_t; +#endif + +/* Warning: fields from BEGIN COMMON to END COMMON must be same for: + 1. NCcommon (include/ncdispatch.h) + 2. NC (libsrc/nc.h) + 3. NC_FILE_INFO (libsrc4/nc4internal.h) + 4. whatever libdiskless uses +*/ +struct NC { +/*BEGIN COMMON (see include/ncdispatch.h: struct NCcommon) */ + int ext_ncid; + int int_ncid; + struct NC_Dispatch* dispatch; + void* dispatchdata; + char* path; + int substrate; + void* instance; /* per-instance data specific to netcdf3,4,dap,etc. + Currently only used by librpc, will retrofit other + dispatch kinds over time. */ +/*END COMMON*/ + /* contains the previous NC during redef. */ + struct NC *old; + /* flags */ +#define NC_CREAT 2 /* in create phase, cleared by ncendef */ +#define NC_INDEF 8 /* in define mode, cleared by ncendef */ +#define NC_NSYNC 0x10 /* synchronise numrecs on change */ +#define NC_HSYNC 0x20 /* synchronise whole header on change */ +#define NC_NDIRTY 0x40 /* numrecs has changed */ +#define NC_HDIRTY 0x80 /* header info has changed */ +/* NC_NOFILL in netcdf.h, historical interface */ + int flags; + struct ncio* nciop; + size_t chunk; /* largest extent this layer will request from ncio->get() */ + size_t xsz; /* external size of this header, == var[0].begin */ + off_t begin_var; /* position of the first (non-record) var */ + off_t begin_rec; /* position of the first 'record' */ + /* Don't constrain maximum size of record unnecessarily */ +#if SIZEOF_OFF_T > SIZEOF_SIZE_T + off_t recsize; /* length of 'record' */ +#else + size_t recsize; /* length of 'record' */ +#endif + /* below gets xdr'd */ + size_t numrecs; /* number of 'records' allocated */ + NC_dimarray dims; + NC_attrarray attrs; + NC_vararray vars; +#ifdef LOCKNUMREC +/* size and named indexes for the lock array protecting NC.numrecs */ +# define LOCKNUMREC_DIM 4 +# define LOCKNUMREC_VALUE 0 +# define LOCKNUMREC_LOCK 1 +# define LOCKNUMREC_SERVING 2 +# define LOCKNUMREC_BASEPE 3 + /* Used on Cray T3E MPP to maintain the + * integrity of numrecs for an unlimited dimension + */ + ushmem_t lock[LOCKNUMREC_DIM]; +#endif +}; + +#define NC_readonly(ncp) \ + (!fIsSet(ncp->nciop->ioflags, NC_WRITE)) + +#define NC_IsNew(ncp) \ + fIsSet((ncp)->flags, NC_CREAT) + +#define NC_indef(ncp) \ + (NC_IsNew(ncp) || fIsSet((ncp)->flags, NC_INDEF)) + +#define set_NC_ndirty(ncp) \ + fSet((ncp)->flags, NC_NDIRTY) + +#define NC_ndirty(ncp) \ + fIsSet((ncp)->flags, NC_NDIRTY) + +#define set_NC_hdirty(ncp) \ + fSet((ncp)->flags, NC_HDIRTY) + +#define NC_hdirty(ncp) \ + fIsSet((ncp)->flags, NC_HDIRTY) + +#define NC_dofill(ncp) \ + (!fIsSet((ncp)->flags, NC_NOFILL)) + +#define NC_doHsync(ncp) \ + fIsSet((ncp)->flags, NC_HSYNC) + +#define NC_doNsync(ncp) \ + fIsSet((ncp)->flags, NC_NSYNC) + +#ifndef LOCKNUMREC +# define NC_get_numrecs(ncp) \ + ((ncp)->numrecs) + +# define NC_set_numrecs(ncp, nrecs) \ + {((ncp)->numrecs = (nrecs));} + +# define NC_increase_numrecs(ncp, nrecs) \ + {if((nrecs) > (ncp)->numrecs) ((ncp)->numrecs = (nrecs));} +#else + size_t NC_get_numrecs(const NC *ncp); + void NC_set_numrecs(NC *ncp, size_t nrecs); + void NC_increase_numrecs(NC *ncp, size_t nrecs); +#endif + +/* Begin defined in nc.c */ + +extern int +NC_check_id(int ncid, NC **ncpp); + +extern int +nc_cktype(nc_type datatype); + +extern size_t +ncx_howmany(nc_type type, size_t xbufsize); + +extern int +read_numrecs(NC *ncp); + +extern int +write_numrecs(NC *ncp); + +extern int +NC_sync(NC *ncp); + +extern int +NC_calcsize(const NC *ncp, off_t *filesizep); + +/* End defined in nc.c */ +/* Begin defined in v1hpg.c */ + +extern size_t +ncx_len_NC(const NC *ncp, size_t sizeof_off_t); + +extern int +ncx_put_NC(const NC *ncp, void **xpp, off_t offset, size_t extent); + +extern int +nc_get_NC( NC *ncp); + +/* End defined in v1hpg.c */ +/* Begin defined in putget.c */ + +extern int +fill_NC_var(NC *ncp, const NC_var *varp, size_t varsize, size_t recno); + +extern int +nc_inq_rec(int ncid, size_t *nrecvars, int *recvarids, size_t *recsizes); + +extern int +nc_get_rec(int ncid, size_t recnum, void **datap); + +extern int +nc_put_rec(int ncid, size_t recnum, void *const *datap); + +/* End defined in putget.c */ + +extern int add_to_NCList(NC*); +extern void del_from_NCList(NC*);/* does not free object */ +extern NC* find_in_NCList(int ext_ncid); +extern void free_NCList(void);/* reclaim whole list */ +extern int count_NCList(void); /* return # of entries in NClist */ + +/* Create a pseudo file descriptor that does not + overlap real file descriptors +*/ +extern int nc__pseudofd(void); + +#endif /* _NC_H_ */ diff --git a/extern/src_netcdf4/nc3dispatch.c b/extern/src_netcdf4/nc3dispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..e304893ad2317a21f51fa6b026810e176c497b74 --- /dev/null +++ b/extern/src_netcdf4/nc3dispatch.c @@ -0,0 +1,500 @@ +/********************************************************************* + Copyright 2010, UCAR/Unidata See netcdf/COPYRIGHT file for + copying and redistribution conditions. + + $Id: nc3dispatch.c,v 2.8 2010/05/26 11:11:26 ed Exp $ + *********************************************************************/ + +#include "config.h" +#include +#include + +#include "netcdf.h" +#include "nc.h" +#include "nc3dispatch.h" + +#ifndef NC_CONTIGUOUS +#define NC_CONTIGUOUS 1 +#endif + +#ifndef NC_ENOTNC4 +#define NC_ENOTNC4 (-111) +#endif + +#ifndef NC_ENOGRP +#define NC_ENOGRP (-125) +#endif + +#ifndef NC_STRING +#define NC_STRING (12) +#endif + + +static int NC3_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp, + int *shufflep, int *deflatep, int *deflate_levelp, + int *fletcher32p, int *contiguousp, size_t *chunksizesp, + int *no_fill, void *fill_valuep, int *endiannessp, + int *options_maskp, int *pixels_per_blockp); + +#ifdef USE_NETCDF4 +static int NC3_show_metadata(int); +static int NC3_inq_unlimdims(int,int*,int*); +static int NC3_var_par_access(int,int,int); +static int NC3_inq_ncid(int,const char*,int*); +static int NC3_inq_grps(int,int*,int*); +static int NC3_inq_grpname(int,char*); +static int NC3_inq_grpname_full(int,size_t*,char*); +static int NC3_inq_grp_parent(int,int*); +static int NC3_inq_grp_full_ncid(int,const char*,int*); +static int NC3_inq_varids(int,int* nvars,int*); +static int NC3_inq_dimids(int,int* ndims,int*,int); +static int NC3_inq_typeids(int,int* ntypes,int*); +static int NC3_inq_type_equal(int,nc_type,int,nc_type,int*); +static int NC3_def_grp(int,const char*,int*); +static int NC3_inq_user_type(int,nc_type,char*,size_t*,nc_type*,size_t*,int*); +static int NC3_inq_typeid(int,const char*,nc_type*); +static int NC3_def_compound(int,size_t,const char*,nc_type*); +static int NC3_insert_compound(int,nc_type,const char*,size_t,nc_type); +static int NC3_insert_array_compound(int,nc_type,const char*,size_t,nc_type,int,const int*); +static int NC3_inq_compound_field(int,nc_type,int,char*,size_t*,nc_type*,int*,int*); +static int NC3_inq_compound_fieldindex(int,nc_type,const char*,int*); +static int NC3_def_vlen(int,const char*,nc_type base_typeid,nc_type*); +static int NC3_put_vlen_element(int,int,void*,size_t,const void*); +static int NC3_get_vlen_element(int,int,const void*,size_t*,void*); +static int NC3_def_enum(int,nc_type,const char*,nc_type*); +static int NC3_insert_enum(int,nc_type,const char*,const void*); +static int NC3_inq_enum_member(int,nc_type,int,char*,void*); +static int NC3_inq_enum_ident(int,nc_type,long long,char*); +static int NC3_def_opaque(int,size_t,const char*,nc_type*); +static int NC3_def_var_deflate(int,int,int,int,int); +static int NC3_def_var_fletcher32(int,int,int); +static int NC3_def_var_chunking(int,int,int,const size_t*); +static int NC3_def_var_fill(int,int,int,const void*); +static int NC3_def_var_endian(int,int,int); +static int NC3_set_var_chunk_cache(int,int,size_t,size_t,float); +static int NC3_get_var_chunk_cache(int,int,size_t*,size_t*,float*); +#endif /*USE_NETCDF4*/ + +NC_Dispatch NC3_dispatcher = { + +NC_DISPATCH_NC3, + +NC3_new_nc, + +NC3_create, +NC3_open, + +NC3_redef, +NC3__enddef, +NC3_sync, +NC3_abort, +NC3_close, +NC3_set_fill, +NC3_inq_base_pe, +NC3_set_base_pe, +NC3_inq_format, + +NC3_inq, +NC3_inq_type, + +NC3_def_dim, +NC3_inq_dimid, +NC3_inq_dim, +NC3_inq_unlimdim, +NC3_rename_dim, + +NC3_inq_att, +NC3_inq_attid, +NC3_inq_attname, +NC3_rename_att, +NC3_del_att, +NC3_get_att, +NC3_put_att, + +NC3_def_var, +NC3_inq_varid, +NC3_rename_var, +NC3_get_vara, +NC3_put_vara, +NCDEFAULT_get_vars, +NCDEFAULT_put_vars, +NCDEFAULT_get_varm, +NCDEFAULT_put_varm, + +NC3_inq_var_all, + +#ifdef USE_NETCDF4 +NC3_show_metadata, +NC3_inq_unlimdims, +NC3_var_par_access, +NC3_inq_ncid, +NC3_inq_grps, +NC3_inq_grpname, +NC3_inq_grpname_full, +NC3_inq_grp_parent, +NC3_inq_grp_full_ncid, +NC3_inq_varids, +NC3_inq_dimids, +NC3_inq_typeids, +NC3_inq_type_equal, +NC3_def_grp, +NC3_inq_user_type, +NC3_inq_typeid, + +NC3_def_compound, +NC3_insert_compound, +NC3_insert_array_compound, +NC3_inq_compound_field, +NC3_inq_compound_fieldindex, +NC3_def_vlen, +NC3_put_vlen_element, +NC3_get_vlen_element, +NC3_def_enum, +NC3_insert_enum, +NC3_inq_enum_member, +NC3_inq_enum_ident, +NC3_def_opaque, +NC3_def_var_deflate, +NC3_def_var_fletcher32, +NC3_def_var_chunking, +NC3_def_var_fill, +NC3_def_var_endian, +NC3_set_var_chunk_cache, +NC3_get_var_chunk_cache, + +#endif /*_NC4DISPATCH_H*/ + +}; + +NC_Dispatch* NC3_dispatch_table = NULL; /* moved here from ddispatch.c */ + +int +NC3_initialize(void) +{ + NC3_dispatch_table = &NC3_dispatcher; + return NC_NOERR; +} + +static int +NC3_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp, + int *shufflep, int *deflatep, int *deflate_levelp, + int *fletcher32p, int *contiguousp, size_t *chunksizesp, + int *no_fill, void *fill_valuep, int *endiannessp, + int *options_maskp, int *pixels_per_blockp) +{ + int stat = NC3_inq_var(ncid,varid,name,xtypep,ndimsp,dimidsp,nattsp); + if(stat) return stat; + if(shufflep) *shufflep = 0; + if(deflatep) *deflatep = 0; + if(fletcher32p) *fletcher32p = 0; + if(contiguousp) *contiguousp = NC_CONTIGUOUS; + if(no_fill) *no_fill = 1; + if(endiannessp) return NC_ENOTNC4; + if(options_maskp) return NC_ENOTNC4; + return NC_NOERR; +} + +#ifdef USE_NETCDF4 + +static int +NC3_inq_unlimdims(int ncid, int *ndimsp, int *unlimdimidsp) +{ + int retval; + int unlimid; + + if ((retval = nc_inq_unlimdim(ncid, &unlimid))) + return retval; + if (unlimid != -1) { + if(ndimsp) *ndimsp = 1; + if (unlimdimidsp) + unlimdimidsp[0] = unlimid; + } else + if(ndimsp) *ndimsp = 0; + return NC_NOERR; +} + +static int +NC3_def_grp(int parent_ncid, const char *name, int *new_ncid) +{ + return NC_ENOTNC4; +} + +static int +NC3_inq_ncid(int ncid, const char *name, int *grp_ncid) +{ + if(grp_ncid) *grp_ncid = ncid; + return NC_NOERR; +} + +static int +NC3_inq_grps(int ncid, int *numgrps, int *ncids) +{ + if (numgrps) + *numgrps = 0; + return NC_NOERR; +} + +static int +NC3_inq_grpname(int ncid, char *name) +{ + if (name) + strcpy(name, "/"); + return NC_NOERR; +} + +static int +NC3_inq_grpname_full(int ncid, size_t *lenp, char *full_name) +{ + if (full_name) + strcpy(full_name, "/"); + if(lenp) *lenp = 1; + return NC_NOERR; +} + +static int +NC3_inq_grp_parent(int ncid, int *parent_ncid) +{ + return NC_ENOGRP; +} + +static int +NC3_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid) +{ + return NC_ENOGRP; +} + +static int +NC3_inq_varids(int ncid, int *nvarsp, int *varids) +{ + int retval,v,nvars; + /* If this is a netcdf-3 file, there is only one group, the root + group, and its vars have ids 0 thru nvars - 1. */ + if ((retval = nc_inq(ncid, NULL, &nvars, NULL, NULL))) + return retval; + if(nvarsp) *nvarsp = nvars; + if (varids) + for (v = 0; v < nvars; v++) + varids[v] = v; + return NC_NOERR; +} + +static int +NC3_inq_dimids(int ncid, int *ndimsp, int *dimids, int include_parents) +{ + int retval,d,ndims; + /* If this is a netcdf-3 file, then the dimids are going to be 0 + thru ndims-1, so just provide them. */ + if ((retval = nc_inq(ncid, &ndims, NULL, NULL, NULL))) + return retval; + if(ndimsp) *ndimsp = ndims; + if (dimids) + for (d = 0; d < ndims; d++) + dimids[d] = d; + return NC_NOERR; +} + +static int +NC3_show_metadata(int ncid) +{ + return NC_NOERR; +} + +static int +NC3_inq_type_equal(int ncid1, nc_type typeid1, int ncid2, nc_type typeid2, int* equalp) +{ + /* Check input. */ + if(equalp == NULL) return NC_NOERR; + + if (typeid1 <= NC_NAT || typeid2 <= NC_NAT) + return NC_EINVAL; + + *equalp = 0; /* assume */ + + /* If one is atomic, and the other user-defined, the types are not equal */ + if ((typeid1 <= NC_STRING && typeid2 > NC_STRING) || + (typeid2 <= NC_STRING && typeid1 > NC_STRING)) { + if (equalp) *equalp = 0; + return NC_NOERR; + } + + /* If both are atomic types, the answer is easy. */ + if (typeid1 <= ATOMICTYPEMAX) { + if (equalp) { + if (typeid1 == typeid2) + *equalp = 1; + else + *equalp = 0; + } + return NC_NOERR; + } + return NC_NOERR; +} + +static int +NC3_inq_typeid(int ncid, const char *name, nc_type *typeidp) +{ + int i; + for (i = 0; i <= ATOMICTYPEMAX; i++) + if (!strcmp(name, NC_atomictypename(i))) { + if (typeidp) *typeidp = i; + return NC_NOERR; + } + return NC_ENOTNC4; +} + +static int +NC3_inq_typeids(int ncid, int *ntypes, int *typeids) +{ + if(ntypes) *ntypes = 0; + return NC_NOERR; +} + +static int +NC3_inq_user_type(int ncid, nc_type typeid, char *name, size_t *size, + nc_type *base_nc_typep, size_t *nfieldsp, int *classp) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp) +{ + return NC_ENOTNC4; +} + +static int +NC3_insert_compound(int ncid, nc_type typeid, const char *name, size_t offset, + nc_type field_typeid) +{ + return NC_ENOTNC4; +} + +static int +NC3_insert_array_compound(int ncid, nc_type typeid, const char *name, + size_t offset, nc_type field_typeid, + int ndims, const int *dim_sizes) +{ + return NC_ENOTNC4; +} + + +static int +NC3_inq_compound_field(int ncid, nc_type typeid, int fieldid, char *name, + size_t *offsetp, nc_type *field_typeidp, int *ndimsp, + int *dim_sizesp) +{ + return NC_ENOTNC4; +} + +static int +NC3_inq_compound_fieldindex(int ncid, nc_type typeid, const char *name, int *fieldidp) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_opaque(int ncid, size_t datum_size, const char *name, nc_type* xtypep) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type* xtypep) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_enum(int ncid, nc_type base_typeid, const char *name, + nc_type *typeidp) +{ + return NC_ENOTNC4; +} + +static int +NC3_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier) +{ + return NC_ENOTNC4; +} + +static int +NC3_inq_enum_member(int ncid, nc_type typeid, int idx, char *identifier, + void *value) +{ + return NC_ENOTNC4; +} + +static int +NC3_insert_enum(int ncid, nc_type typeid, const char *identifier, + const void *value) +{ + return NC_ENOTNC4; +} + +static int +NC3_put_vlen_element(int ncid, int typeid, void *vlen_element, + size_t len, const void *data) +{ + return NC_ENOTNC4; +} + +static int +NC3_get_vlen_element(int ncid, int typeid, const void *vlen_element, + size_t *len, void *data) +{ + return NC_ENOTNC4; +} + +static int +NC3_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, float preemption) +{ + return NC_ENOTNC4; +} + +static int +NC3_get_var_chunk_cache(int ncid, int varid, size_t *sizep, size_t *nelemsp, float *preemptionp) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_var_deflate(int ncid, int varid, int shuffle, int deflate, + int deflate_level) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_var_fletcher32(int ncid, int varid, int fletcher32) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksizesp) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value) +{ + return NC_ENOTNC4; +} + +static int +NC3_def_var_endian(int ncid, int varid, int endianness) +{ + return NC_ENOTNC4; +} + +static int +NC3_var_par_access(int ncid, int varid, int par_access) +{ + return NC_ENOTNC4; +} + +#endif /*USE_NETCDF4*/ + diff --git a/extern/src_netcdf4/nc3dispatch.h b/extern/src_netcdf4/nc3dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..7f0323f24a0cf8409c5f9a7962970d50bca28a76 --- /dev/null +++ b/extern/src_netcdf4/nc3dispatch.h @@ -0,0 +1,186 @@ +/* + * Copyright 1993-1996 University Corporation for Atmospheric Research/Unidata + * + * Portions of this software were developed by the Unidata Program at the + * University Corporation for Atmospheric Research. + * + * Access and use of this software shall impose the following obligations + * and understandings on the user. The user is granted the right, without + * any fee or cost, to use, copy, modify, alter, enhance and distribute + * this software, and any derivative works thereof, and its supporting + * documentation for any purpose whatsoever, provided that this entire + * notice appears in all copies of the software, derivative works and + * supporting documentation. Further, UCAR requests that the user credit + * UCAR/Unidata in any publications that result from the use of this + * software or in any product that includes this software. The names UCAR + * and/or Unidata, however, may not be used in any advertising or publicity + * to endorse or promote any products or commercial entity unless specific + * written permission is obtained from UCAR/Unidata. The user also + * understands that UCAR/Unidata is not obligated to provide the user with + * any support, consulting, training or assistance of any kind with regard + * to the use, operation and performance of this software nor to provide + * the user with any updates, revisions, new versions or "bug fixes." + * + * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "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 UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* "$Id: nc3dispatch.h,v 2.8 2010/05/26 18:11:08 dmh Exp $" */ + +#ifndef _NC3DISPATCH_H +#define _NC3DISPATCH_H + +#include /* size_t, ptrdiff_t */ +#include "netcdf.h" +#include "ncdispatch.h" + + + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * The Interface + */ + +/* WARNING: this signature differs from external nc_create API*/ +EXTERNL int +NC3_create(const char *path, int cmode, + size_t initialsz, int basepe, size_t *chunksizehintp, + int useparallel, void* mpidata, + struct NC_Dispatch*, NC** ncp); + +/* WARNING: this signature differs from external nc_open API*/ +EXTERNL int +NC3_open(const char *path, int mode, + int basepe, size_t *chunksizehintp, + int use_parallel, void* mpidata, + NC_Dispatch*, NC** ncp); + +EXTERNL int +NC3_new_nc(NC**); + +EXTERNL int +NC3_redef(int ncid); + +EXTERNL int +NC3__enddef(int ncid, size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align); + +EXTERNL int +NC3_sync(int ncid); + +EXTERNL int +NC3_abort(int ncid); + +EXTERNL int +NC3_close(int ncid); + +EXTERNL int +NC3_set_fill(int ncid, int fillmode, int *old_modep); + +EXTERNL int +NC3_set_base_pe(int ncid, int pe); + +EXTERNL int +NC3_inq_base_pe(int ncid, int *pe); + +EXTERNL int +NC3_inq_format(int ncid, int *formatp); + +EXTERNL int +NC3_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp); + +EXTERNL int +NC3_inq_type(int, nc_type, char *, size_t *); + +/* Begin _dim */ + +EXTERNL int +NC3_def_dim(int ncid, const char *name, size_t len, int *idp); + +EXTERNL int +NC3_inq_dimid(int ncid, const char *name, int *idp); + +EXTERNL int +NC3_inq_dim(int ncid, int dimid, char *name, size_t *lenp); + +EXTERNL int +NC3_inq_unlimdim(int ncid, int *unlimdimidp); + +EXTERNL int +NC3_rename_dim(int ncid, int dimid, const char *name); + +/* End _dim */ +/* Begin _att */ + +EXTERNL int +NC3_inq_att(int ncid, int varid, const char *name, + nc_type *xtypep, size_t *lenp); + +EXTERNL int +NC3_inq_attid(int ncid, int varid, const char *name, int *idp); + +EXTERNL int +NC3_inq_attname(int ncid, int varid, int attnum, char *name); + +EXTERNL int +NC3_rename_att(int ncid, int varid, const char *name, const char *newname); + +EXTERNL int +NC3_del_att(int ncid, int varid, const char*); + +/* End _att */ +/* Begin {put,get}_att */ + +EXTERNL int +NC3_get_att(int ncid, int varid, const char *name, void *value, nc_type); + +EXTERNL int +NC3_put_att(int ncid, int varid, const char *name, nc_type datatype, + size_t len, const void *value, nc_type); + +/* End {put,get}_att */ +/* Begin _var */ + +EXTERNL int +NC3_def_var(int ncid, const char *name, + nc_type xtype, int ndims, const int *dimidsp, int *varidp); + +EXTERNL int +NC3_inq_var(int ncid, int varid, char *name, + nc_type *xtypep, int *ndimsp, int *dimidsp, int *nattsp); + +EXTERNL int +NC3_inq_varid(int ncid, const char *name, int *varidp); + +EXTERNL int +NC3_rename_var(int ncid, int varid, const char *name); + + +EXTERNL int +NC3_put_vara(int ncid, int varid, + const size_t *start, const size_t *count, + const void *value, nc_type); + +EXTERNL int +NC3_get_vara(int ncid, int varid, + const size_t *start, const size_t *count, + void *value, nc_type); + +/* End _var */ + +extern int NC3_initialize(); + + +#if defined(__cplusplus) +} +#endif + +#endif /*_NC3DISPATCH_H*/ diff --git a/extern/src_netcdf4/nc4attr.c b/extern/src_netcdf4/nc4attr.c new file mode 100644 index 0000000000000000000000000000000000000000..92bba263cb2ce14ca0e3c1130e4540a6902c5fc2 --- /dev/null +++ b/extern/src_netcdf4/nc4attr.c @@ -0,0 +1,897 @@ +/* +This file is part of netcdf-4, a netCDF-like interface for HDF5, or a +HDF5 backend for netCDF, depending on your point of view. + +This file handles the nc4 attribute functions. + +Remember that with atts, type conversion can take place when writing +them, and when reading them. + +Copyright 2003-2011, University Corporation for Atmospheric +Research. See COPYRIGHT file for copying and redistribution +conditions. +*/ + +#include "nc4internal.h" +#include "nc.h" +#include "nc4dispatch.h" +#include "ncdispatch.h" + +#ifdef USE_PNETCDF +#include +#endif + +int nc4typelen(nc_type type); + +/* Get or put attribute metadata from our linked list of file + info. Always locate the attribute by name, never by attnum. + The mem_type is ignored if data=NULL. */ +int +nc4_get_att(int ncid, NC_FILE_INFO_T *nc, int varid, const char *name, + nc_type *xtype, nc_type mem_type, size_t *lenp, + int *attnum, int is_long, void *data) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_ATT_INFO_T *att; + int my_attnum = -1; + int need_to_convert = 0; + int range_error = NC_NOERR; + void *bufr = NULL; + size_t type_size; + char norm_name[NC_MAX_NAME + 1]; + int i; + int retval = NC_NOERR; + + if (attnum) + my_attnum = *attnum; + assert(nc && nc->nc4_info); + + LOG((3, "nc4_get_att: ncid 0x%x varid %d name %s attnum %d mem_type %d", + ncid, varid, name, my_attnum, mem_type)); + + /* Find info for this file and group, and set pointer to each. */ + h5 = nc->nc4_info; + if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK)))) + return NC_EBADGRPID; + + /* Normalize name. */ + if ((retval = nc4_normalize_name(name, norm_name))) + return retval; + + /* Find the attribute, if it exists. If we don't find it, we are + major failures. */ + if ((retval = nc4_find_grp_att(grp, varid, norm_name, my_attnum, &att))) + return retval; + + /* If mem_type is NC_NAT, it means we want to use the attribute's + * file type as the mem type as well. */ + if (mem_type == NC_NAT) + mem_type = att->xtype; + + /* If the attribute is NC_CHAR, and the mem_type isn't, or vice + * versa, that's a freakish attempt to convert text to + * numbers. Some pervert out there is trying to pull a fast one! + * Send him an NC_ECHAR error...*/ + if (data && att->len && + ((att->xtype == NC_CHAR && mem_type != NC_CHAR) || + (att->xtype != NC_CHAR && mem_type == NC_CHAR))) + return NC_ECHAR; /* take that, you freak! */ + + /* Copy the info. */ + if (lenp) + *lenp = att->len; + if (xtype) + *xtype = att->xtype; + if (attnum) + *attnum = att->attnum; + + /* Zero len attributes are easy to read! */ + if (!att->len) + return NC_NOERR; + + /* Later on, we will need to know the size of this type. */ + if ((retval = nc4_get_typelen_mem(h5, mem_type, is_long, &type_size))) + return retval; + + /* We may have to convert data. Treat NC_CHAR the same as + * NC_UBYTE. If the mem_type is NAT, don't try any conversion - use + * the attribute's type. */ + if (data && att->len && mem_type != att->xtype && + mem_type != NC_NAT && + !(mem_type == NC_CHAR && + (att->xtype == NC_UBYTE || att->xtype == NC_BYTE))) + { + need_to_convert++; + if (!(bufr = malloc((size_t)(att->len * type_size)))) + return NC_ENOMEM; + if ((retval = nc4_convert_type(att->data, bufr, att->xtype, + mem_type, (size_t)att->len, &range_error, + NULL, (h5->cmode & NC_CLASSIC_MODEL), 0, is_long))) + BAIL(retval); + + /* For strict netcdf-3 rules, ignore erange errors between UBYTE + * and BYTE types. */ + if ((h5->cmode & NC_CLASSIC_MODEL) && + (att->xtype == NC_UBYTE || att->xtype == NC_BYTE) && + (mem_type == NC_UBYTE || mem_type == NC_BYTE) && + range_error) + range_error = 0; + } + else + { + bufr = att->data; + } + + /* If the caller wants data, copy it for him. If he hasn't + allocated enough memory for it, he will burn in segmantation + fault hell, writhing with the agony of undiscovered memory + bugs! */ + if (data) + { + if (att->vldata) + { + size_t base_typelen = type_size; + hvl_t *vldest = data; + NC_TYPE_INFO_T *type; + if ((retval = nc4_find_type(h5, att->xtype, &type))) + return retval; + for (i = 0; i < att->len; i++) + { + vldest[i].len = att->vldata[i].len; + if (!(vldest[i].p = malloc(vldest[i].len * base_typelen))) + BAIL(NC_ENOMEM); + memcpy(vldest[i].p, att->vldata[i].p, vldest[i].len * base_typelen); + } + } + else if (att->stdata) + { + for (i = 0; i < att->len; i++) + { + if (!(((char **)data)[i] = malloc(strlen(att->stdata[i]) + 1))) + BAIL(NC_ENOMEM); + strcpy(((char **)data)[i], att->stdata[i]); + } + } + else + { + /* For long types, we need to handle this special... */ + if (is_long && att->xtype == NC_INT) + { + long *lp = data; + int *ip = bufr; + for (i = 0; i < att->len; i++) + *lp++ = *ip++; + } + else + memcpy(data, bufr, (size_t)(att->len * type_size)); + } + } + + exit: + if (need_to_convert) free(bufr); + if (retval) + return retval; + if (range_error) + return NC_ERANGE; + return NC_NOERR; +} + +/* Put attribute metadata into our global metadata. */ +int +nc4_put_att(int ncid, NC_FILE_INFO_T *nc, int varid, const char *name, + nc_type file_type, nc_type mem_type, size_t len, int is_long, + const void *data) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var = NULL; + NC_ATT_INFO_T *att, **attlist = NULL, *varatt; + NC_TYPE_INFO_T *type = NULL; + char norm_name[NC_MAX_NAME + 1]; + int new_att = 0; + int retval = NC_NOERR, range_error = 0; + size_t type_size; + int i; + int res; + + if (!name) + return NC_EBADNAME; + assert(nc && nc->nc4_info); + + LOG((1, "nc4_put_att: ncid 0x%x varid %d name %s " + "file_type %d mem_type %d len %d", ncid, varid, + name, file_type, mem_type, len)); + + /* If len is not zero, then there must be some data. */ + if (len && !data) + return NC_EINVAL; + + /* Find info for this file and group, and set pointer to each. */ + h5 = nc->nc4_info; + if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK)))) + return NC_EBADGRPID; + + /* If the file is read-only, return an error. */ + if (h5->no_write) + return NC_EPERM; + + /* Check and normalize the name. */ + if ((retval = nc4_check_name(name, norm_name))) + return retval; + + /* Find att, if it exists. */ + if (varid == NC_GLOBAL) + attlist = &grp->att; + else + { + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + { + attlist = &var->att; + break; + } + if (!var) + return NC_ENOTVAR; + } + for (att = *attlist; att; att = att->next) + if (!strcmp(att->name, norm_name)) + break; + + if (!att) + { + /* If this is a new att, require define mode. */ + if (!(h5->flags & NC_INDEF)) + { + if (h5->cmode & NC_CLASSIC_MODEL) + return NC_EINDEFINE; + if ((retval = NC4_redef(ncid))) + BAIL(retval); + } + new_att++; + } + else + { + /* For an existing att, if we're not in define mode, the len + must not be greater than the existing len for classic model. */ + if (!(h5->flags & NC_INDEF) && + len * nc4typelen(file_type) > (size_t)att->len * nc4typelen(att->xtype)) + { + if (h5->cmode & NC_CLASSIC_MODEL) + return NC_EINDEFINE; + if ((retval = NC4_redef(ncid))) + BAIL(retval); + } + } + + /* We must have two valid types to continue. */ + if (file_type == NC_NAT || mem_type == NC_NAT) + return NC_EBADTYPE; + + /* Get information about this type. */ + if ((retval = nc4_find_type(h5, file_type, &type))) + return retval; + if ((retval = nc4_get_typelen_mem(h5, file_type, is_long, &type_size))) + return retval; + + /* No character conversions are allowed. */ + if (file_type != mem_type && + (file_type == NC_CHAR || mem_type == NC_CHAR || + file_type == NC_STRING || mem_type == NC_STRING)) + return NC_ECHAR; + + /* For classic mode file, only allow atts with classic types to be + * created. */ + if (h5->cmode & NC_CLASSIC_MODEL && file_type > NC_DOUBLE) + return NC_ESTRICTNC3; + + /* Add to the end of the attribute list, if this att doesn't + already exist. */ + if (new_att) + { + LOG((3, "adding attribute %s to the list...", norm_name)); + if ((res = nc4_att_list_add(attlist))) + BAIL (res); + /* Find this att's entry in the list (the last one). */ + for (att=*attlist; att->next; att=att->next) + ; + } + + /* Now fill in the metadata. */ + att->dirty++; + if (att->name) + free(att->name); + if (!(att->name = malloc((strlen(norm_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(att->name, norm_name); + att->xtype = file_type; + att->len = len; + if (att->prev) + att->attnum = att->prev->attnum + 1; + else + att->attnum = 0; + if (type) + att->class = type->class; + + /* If this is the _FillValue attribute, then we will also have to + * copy the value to the fll_vlue pointer of the NC_VAR_INFO_T + * struct for this var. (But ignore a global _FillValue + * attribute). */ + if (!strcmp(att->name, _FillValue) && varid != NC_GLOBAL) + { + NC_TYPE_INFO_T *type_info; + int size; + + /* Fill value must be same type. */ + if (att->xtype != var->xtype) + return NC_EINVAL; + + /* If we already wrote to the dataset, then return an error. */ + if (var->written_to) + return NC_ELATEFILL; + + /* If fill value hasn't been set, allocate space. Of course, + * vlens have to be differnt... */ + if ((retval = nc4_get_typelen_mem(grp->file->nc4_info, var->xtype, 0, + &type_size))) + return retval; + if ((retval = nc4_find_type(grp->file->nc4_info, var->xtype, &type_info))) + BAIL(retval); + + /* Already set a fill value? Now I'll have to free the old + * one. Make up your damn mind, would you? */ + if (var->fill_value) + { + if (type_info && type_info->class == NC_VLEN) + if ((retval = nc_free_vlen(var->fill_value))) + return retval; + free(var->fill_value); + } + + /* Allocate space for the fill value. */ + if (type_info && type_info->class == NC_VLEN) + size = sizeof(hvl_t); + else if (var->xtype == NC_STRING) + size = sizeof(char *); + else + size = type_size; + + /* size = strlen(*(char **)data) + 1; */ + if (!(var->fill_value = malloc(size))) + return NC_ENOMEM; + + /* Copy the fill_value. */ + LOG((4, "Copying fill value into metadata for variable %s", var->name)); + if (type_info && type_info->class == NC_VLEN) + { + nc_vlen_t *in_vlen = (nc_vlen_t *)data, *fv_vlen = (nc_vlen_t *)(var->fill_value); + fv_vlen->len = in_vlen->len; + if (!(fv_vlen->p = malloc(size * in_vlen->len))) + return NC_ENOMEM; + memcpy(fv_vlen->p, in_vlen->p, in_vlen->len * size); + } + else if (var->xtype == NC_STRING) + { + if (!(*(char **)var->fill_value = malloc(strlen(*(char **)data) + 1))) + return NC_ENOMEM; + strcpy(*(char **)(var->fill_value), *(char **)data); + } + else + memcpy(var->fill_value, data, type_size); + + /* Mark the var and all its atts as dirty, so they get + * rewritten. */ + var->dirty++; + for (varatt = var->att; varatt; varatt = varatt->next) + varatt->dirty++; + } + + /* Copy the attribute data, if there is any. VLENs and string + * arrays have to be handled specially. */ + if (type && type->class == NC_VLEN && data && att->len) + { + const hvl_t *vldata1; + + vldata1 = data; + if (!(att->vldata = malloc(att->len * sizeof(hvl_t)))) + BAIL(NC_ENOMEM); + for (i = 0; i < att->len; i++) + { + att->vldata[i].len = vldata1[i].len; + if (!(att->vldata[i].p = malloc(type_size * att->vldata[i].len))) + BAIL(NC_ENOMEM); + memcpy(att->vldata[i].p, vldata1[i].p, type_size * att->vldata[i].len); + } + } + else if (file_type == NC_STRING && data && att->len) + { + LOG((4, "copying array of NC_STRING")); + if (!(att->stdata = malloc(sizeof(char *) * att->len))) + BAIL(NC_ENOMEM); + for (i = 0; i < att->len; i++) + { + LOG((5, "copying string %d of size %d", i, strlen(((char **)data)[i]) + 1)); + if (!(att->stdata[i] = malloc(strlen(((char **)data)[i]) + 1))) + BAIL(NC_ENOMEM); + strcpy(att->stdata[i], ((char **)data)[i]); + } + } + else + { + /* Data types are like religions, in that one can convert. */ + if (att->len) + { + if (!new_att) + free (att->data); + if (!(att->data = malloc(att->len * type_size))) + BAIL(NC_ENOMEM); + if (type) + { + /* Just copy the data... */ + if (type->class == NC_OPAQUE || type->class == NC_COMPOUND || type->class == NC_ENUM) + memcpy(att->data, data, len * type_size); + else + LOG((0, "nc4_put_att: unknown type.")); + } + else + { + if ((retval = nc4_convert_type(data, att->data, mem_type, file_type, + len, &range_error, NULL, + (h5->cmode & NC_CLASSIC_MODEL), is_long, 0))) + BAIL(retval); + } + } + } + att->dirty = 1; + att->created = 0; + + exit: + /* If there was an error return it, otherwise return any potential + range error value. If none, return NC_NOERR as usual.*/ + if (retval) + return retval; + if (range_error) + return NC_ERANGE; + return NC_NOERR; +} + +/* Learn about an att. All the nc4 nc_inq_ functions just call + * add_meta_get to get the metadata on an attribute. */ +int +NC4_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, size_t *lenp) +{ + NC_FILE_INFO_T *nc; + + LOG((2, "nc_inq_att: ncid 0x%x varid %d name %s", ncid, varid, name)); + + /* Find metadata. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + { + MPI_Offset mpi_len; + int ret; + + if ((ret = ncmpi_inq_att(nc->int_ncid, varid, name, xtypep, &mpi_len))) + return ret; + if (lenp) + *lenp = mpi_len; + } +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(nc->nc4_info); + + /* Handle netcdf-4 files. */ + return nc4_get_att(ncid, nc, varid, name, xtypep, NC_UBYTE, lenp, NULL, 0, NULL); +} + +/* Learn an attnum, given a name. */ +int +NC4_inq_attid(int ncid, int varid, const char *name, int *attnump) +{ + NC_FILE_INFO_T *nc; + + LOG((2, "nc_inq_attid: ncid 0x%x varid %d name %s", ncid, varid, name)); + + /* Find metadata. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_inq_attid(nc->int_ncid, varid, name, attnump); +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(nc->nc4_info); + + /* Handle netcdf-4 files. */ + return nc4_get_att(ncid, nc, varid, name, NULL, NC_UBYTE, + NULL, attnump, 0, NULL); +} + + +/* Given an attnum, find the att's name. */ +int +NC4_inq_attname(int ncid, int varid, int attnum, char *name) +{ + NC_FILE_INFO_T *nc; + NC_ATT_INFO_T *att; + int retval = NC_NOERR; + + LOG((2, "nc_inq_attname: ncid 0x%x varid %d attnum %d", + ncid, varid, attnum)); + + /* Find metadata. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_inq_attname(nc->int_ncid, varid, attnum, name); +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(nc->nc4_info); + + /* Handle netcdf-4 files. */ + if ((retval = nc4_find_nc_att(ncid, varid, NULL, attnum, &att))) + return retval; + + /* Get the name. */ + if (name) + strcpy(name, att->name); + + return NC_NOERR; +} + +/* I think all atts should be named the exact same thing, to avoid + confusion! */ +int +NC4_rename_att(int ncid, int varid, const char *name, + const char *newname) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + NC_ATT_INFO_T *att, *list; + char norm_newname[NC_MAX_NAME + 1], norm_name[NC_MAX_NAME + 1]; + hid_t datasetid = 0; + int retval = NC_NOERR; + + if (!name || !newname) + return NC_EINVAL; + + LOG((2, "nc_rename_att: ncid 0x%x varid %d name %s newname %s", + ncid, varid, name, newname)); + + /* If the new name is too long, that's an error. */ + if (strlen(newname) > NC_MAX_NAME) + return NC_EMAXNAME; + + /* Find metadata for this file. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_rename_att(nc->int_ncid, varid, name, newname); +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(h5); + + /* If the file is read-only, return an error. */ + if (h5->no_write) + return NC_EPERM; + + /* Check and normalize the name. */ + if ((retval = nc4_check_name(newname, norm_newname))) + return retval; + + /* Is norm_newname in use? */ + if (varid == NC_GLOBAL) + { + list = grp->att; + } + else + { + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + { + list = var->att; + break; + } + if (!var) + return NC_ENOTVAR; + } + for (att = list; att; att = att->next) + if (!strncmp(att->name, norm_newname, NC_MAX_NAME)) + return NC_ENAMEINUSE; + + /* Normalize name and find the attribute. */ + if ((retval = nc4_normalize_name(name, norm_name))) + return retval; + for (att = list; att; att = att->next) + if (!strncmp(att->name, norm_name, NC_MAX_NAME)) + break; + if (!att) + return NC_ENOTATT; + + /* If we're not in define mode, new name must be of equal or + less size, if complying with strict NC3 rules. */ + if (!(h5->flags & NC_INDEF) && strlen(norm_newname) > strlen(att->name) && + (h5->cmode & NC_CLASSIC_MODEL)) + return NC_ENOTINDEFINE; + + /* Delete the original attribute, if it exists in the HDF5 file. */ + if (att->created) + { + if (varid == NC_GLOBAL) + { + if (H5Adelete(grp->hdf_grpid, att->name) < 0) + return NC_EHDFERR; + } + else + { + if ((retval = nc4_open_var_grp2(grp, varid, &datasetid))) + return retval; + if (H5Adelete(datasetid, att->name) < 0) + return NC_EHDFERR; + } + att->created = 0; + } + + /* Copy the new name into our metadata. */ + free(att->name); + if (!(att->name = malloc((strlen(norm_newname) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(att->name, norm_newname); + att->dirty = 1; + + return retval; +} + +/* Delete an att. Rub it out. Push the button on it. Liquidate + it. Bump it off. Take it for a one-way ride. Terminate it. Drop the + bomb on it. You get the idea. + Ed Hartnett, 10/1/3 +*/ +int +NC4_del_att(int ncid, int varid, const char *name) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_ATT_INFO_T *att, *natt; + NC_VAR_INFO_T *var; + NC_ATT_INFO_T **attlist = NULL; + hid_t locid = 0, datasetid = 0; + int retval = NC_NOERR; + + if (!name) + return NC_EINVAL; + + LOG((2, "nc_del_att: ncid 0x%x varid %d name %s", + ncid, varid, name)); + + /* Find metadata for this file. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_del_att(nc->int_ncid, varid, name); +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(h5); + + assert(h5 && grp); + + /* If the file is read-only, return an error. */ + if (h5->no_write) + return NC_EPERM; + + /* If it's not in define mode, forget it. */ + if (!(h5->flags & NC_INDEF)) + { + if (h5->cmode & NC_CLASSIC_MODEL) + return NC_ENOTINDEFINE; + if ((retval = NC4_redef(ncid))) + BAIL(retval); + } + + /* Get either the global or a variable attribute list. Also figure + out the HDF5 location it's attached to. */ + if (varid == NC_GLOBAL) + { + attlist = &grp->att; + locid = grp->hdf_grpid; + } + else + { + for(var = grp->var; var; var = var->next) + { + if (var->varid == varid) + { + attlist = &var->att; + break; + } + } + if (!var) + return NC_ENOTVAR; + if (var->created) + { + locid = var->hdf_datasetid; + } + } + + /* Now find the attribute by name or number. */ + for (att = *attlist; att; att = att->next) + if (!strcmp(att->name, name)) + break; + + /* If att is NULL, we couldn't find the attribute. */ + if (!att) + BAIL_QUIET(NC_ENOTATT); + + /* Delete it from the HDF5 file, if it's been created. */ + if (att->created) + if(H5Adelete(locid, att->name) < 0) + BAIL(NC_EATTMETA); + + /* Renumber all following attributes. */ + for (natt = att->next; natt; natt = natt->next) + natt->attnum--; + + /* Delete this attribute from this list. */ + if ((retval = nc4_att_list_del(attlist, att))) + BAIL(retval); + + exit: + if (datasetid > 0) H5Dclose(datasetid); + return retval; +} + +/* Write an attribute with type conversion. */ +int +nc4_put_att_tc(int ncid, int varid, const char *name, nc_type file_type, + nc_type mem_type, int mem_type_is_long, size_t len, + const void *op) +{ + NC_FILE_INFO_T *nc; + + if (!name || strlen(name) > NC_MAX_NAME) + return NC_EBADNAME; + + LOG((3, "nc4_put_att_tc: ncid 0x%x varid %d name %s file_type %d " + "mem_type %d len %d", ncid, varid, name, file_type, mem_type, len)); + + /* The length needs to be positive (cast needed for braindead + systems with signed size_t). */ + if((unsigned long) len > X_INT_MAX) + return NC_EINVAL; + + /* Find metadata. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + { + if (mem_type == NC_UBYTE) + mem_type = NC_BYTE; + switch(mem_type) + { + case NC_BYTE: + return ncmpi_put_att_schar(nc->int_ncid, varid, name, + file_type, len, op); + case NC_CHAR: + return ncmpi_put_att_text(nc->int_ncid, varid, name, + len, op); + case NC_SHORT: + return ncmpi_put_att_short(nc->int_ncid, varid, name, + file_type, len, op); + case NC_INT: + if (mem_type_is_long) + return ncmpi_put_att_long(nc->int_ncid, varid, name, + file_type, len, op); + else + return ncmpi_put_att_int(nc->int_ncid, varid, name, + file_type, len, op); + case NC_FLOAT: + return ncmpi_put_att_float(nc->int_ncid, varid, name, + file_type, len, op); + case NC_DOUBLE: + return ncmpi_put_att_double(nc->int_ncid, varid, name, + file_type, len, op); + case NC_NAT: + default: + return NC_EBADTYPE; + } + } +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(nc->nc4_info); + + /* Otherwise, handle things the netcdf-4 way. */ + return nc4_put_att(ncid, nc, varid, name, file_type, mem_type, len, + mem_type_is_long, op); +} + +/* Read an attribute of any type, with type conversion. This may be + * called by any of the nc_get_att_* functions. */ +int +nc4_get_att_tc(int ncid, int varid, const char *name, nc_type mem_type, + int mem_type_is_long, void *ip) +{ + NC_FILE_INFO_T *nc; + + LOG((3, "nc4_get_att_tc: ncid 0x%x varid %d name %s mem_type %d", + ncid, varid, name, mem_type)); + + /* Find metadata. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + { + if (mem_type == NC_UBYTE) + mem_type = NC_BYTE; + switch(mem_type) + { + case NC_BYTE: + return ncmpi_get_att_schar(nc->int_ncid, varid, name, ip); + case NC_CHAR: + return ncmpi_get_att_text(nc->int_ncid, varid, name, ip); + case NC_SHORT: + return ncmpi_get_att_short(nc->int_ncid, varid, name, ip); + case NC_INT: + if (mem_type_is_long) + return ncmpi_get_att_long(nc->int_ncid, varid, name, ip); + else + return ncmpi_get_att_int(nc->int_ncid, varid, name, ip); + case NC_FLOAT: + return ncmpi_get_att_float(nc->int_ncid, varid, name, ip); + case NC_DOUBLE: + return ncmpi_get_att_double(nc->int_ncid, varid, name, ip); + case NC_NAT: + default: + return NC_EBADTYPE; + } + } +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(nc->nc4_info); + + return nc4_get_att(ncid, nc, varid, name, NULL, mem_type, + NULL, NULL, mem_type_is_long, ip); +} + +int +NC4_put_att(int ncid, int varid, const char *name, nc_type xtype, + size_t nelems, const void *value, nc_type memtype) +{ + return nc4_put_att_tc(ncid, varid, name, xtype, memtype, 0, nelems, value); +} + +int +NC4_get_att(int ncid, int varid, const char *name, void *value, nc_type memtype) +{ + return nc4_get_att_tc(ncid, varid, name, memtype, 0, value); +} diff --git a/extern/src_netcdf4/nc4dim.c b/extern/src_netcdf4/nc4dim.c new file mode 100644 index 0000000000000000000000000000000000000000..3651eb71baa1a9a82dd3b5aa22921471ed8eebb5 --- /dev/null +++ b/extern/src_netcdf4/nc4dim.c @@ -0,0 +1,401 @@ +/* + +This file is part of netcdf-4, a netCDF-like interface for HDF5, or a +HDF5 backend for netCDF, depending on your point of view. + +This file handles the nc4 dimension functions. + +Copyright 2003-5, University Corporation for Atmospheric Research. See +the COPYRIGHT file for copying and redistribution conditions. + +$Id: nc4dim.c,v 1.41 2010/05/25 17:54:23 dmh Exp $ +*/ + +#include "nc4internal.h" + +#ifdef USE_PNETCDF +#include +#endif + +/* Netcdf-4 files might have more than one unlimited dimension, but + return the first one anyway. */ +/* Note that this code is inconsistent with nc_inq */ +int +NC4_inq_unlimdim(int ncid, int *unlimdimidp) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp, *g; + NC_HDF5_FILE_INFO_T *h5; + NC_DIM_INFO_T *dim; + int found = 0; + int retval; + + LOG((2, "called nc_inq_unlimdim")); + + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_inq_unlimdim(nc->int_ncid, unlimdimidp); +#endif /* USE_PNETCDF */ + + /* Take care of netcdf-3 files. */ + assert(h5); + + /* According to netcdf-3 manual, return -1 if there is no unlimited + dimension. */ + *unlimdimidp = -1; + for (g = grp; g && !found; g = g->parent) + { + for (dim = g->dim; dim; dim = dim->next) + { + if (dim->unlimited) + { + *unlimdimidp = dim->dimid; + found++; + break; + } + } + } + + return NC_NOERR; +} + +/* Dimensions are defined in attributes attached to the appropriate + group in the data file. */ +int +NC4_def_dim(int ncid, const char *name, size_t len, int *idp) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_DIM_INFO_T *dim; + char norm_name[NC_MAX_NAME + 1]; + int retval = NC_NOERR; + + LOG((2, "nc_def_dim: ncid 0x%x name %s len %d", ncid, name, + (int)len)); + + /* Find our global metadata structure. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_def_dim(nc->int_ncid, name, len, idp); +#endif /* USE_PNETCDF */ + + /* Take care of netcdf-3 files. */ + assert(h5); + + assert(h5 && nc && grp); + + /* If the file is read-only, return an error. */ + if (h5->no_write) + return NC_EPERM; + + /* Check some stuff if strict nc3 rules are in effect. */ + if (h5->cmode & NC_CLASSIC_MODEL) + { + /* Only one limited dimenson for strict nc3. */ + if (len == NC_UNLIMITED) + for (dim = grp->dim; dim; dim = dim->next) + if (dim->unlimited) + return NC_EUNLIMIT; + + /* Must be in define mode for stict nc3. */ + if (!(h5->flags & NC_INDEF)) + return NC_ENOTINDEFINE; + } + + /* If it's not in define mode, enter define mode. */ + if (!(h5->flags & NC_INDEF)) + if ((retval = nc_redef(ncid))) + return retval; + + /* Make sure this is a valid netcdf name. */ + if ((retval = nc4_check_name(name, norm_name))) + return retval; + + /* For classic model: dim length has to fit in a 32-bit unsigned + * int, as permitted for 64-bit offset format. */ + if (h5->cmode & NC_CLASSIC_MODEL) + if(len > X_UINT_MAX) /* Backward compat */ + return NC_EDIMSIZE; + + /* Make sure the name is not already in use. */ + for (dim = grp->dim; dim; dim = dim->next) + if (!strncmp(dim->name, norm_name, NC_MAX_NAME)) + return NC_ENAMEINUSE; + + /* Add a dimension to the list. The ID must come from the file + * information, since dimids are visible in more than one group. */ + nc4_dim_list_add(&grp->dim); + grp->dim->dimid = grp->file->nc4_info->next_dimid++; + + /* Initialize the metadata for this dimension. */ + if (!(grp->dim->name = malloc((strlen(norm_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(grp->dim->name, norm_name); + grp->dim->len = len; + grp->dim->dirty++; + if (len == NC_UNLIMITED) + grp->dim->unlimited++; + + /* Pass back the dimid. */ + if (idp) + *idp = grp->dim->dimid; + + return retval; +} + +/* Given dim name, find its id. */ +int +NC4_inq_dimid(int ncid, const char *name, int *idp) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp, *g; + NC_HDF5_FILE_INFO_T *h5; + NC_DIM_INFO_T *dim; + char norm_name[NC_MAX_NAME + 1]; + int finished = 0; + int retval; + + LOG((2, "nc_inq_dimid: ncid 0x%x name %s", ncid, name)); + + /* Find metadata for this file. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_inq_dimid(nc->int_ncid, name, idp); +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(h5); + + assert(nc && grp); + + /* Normalize name. */ + if ((retval = nc4_normalize_name(name, norm_name))) + return retval; + + /* Go through each dim and check for a name match. */ + for (g = grp; g && !finished; g = g->parent) + for (dim = g->dim; dim; dim = dim->next) + if (!strncmp(dim->name, norm_name, NC_MAX_NAME)) + { + if (idp) + *idp = dim->dimid; + return NC_NOERR; + } + + return NC_EBADDIM; +} + +/* Find out name and len of a dim. For an unlimited dimension, the + length is the largest lenght so far written. If the name of lenp + pointers are NULL, they will be ignored. */ +int +NC4_inq_dim(int ncid, int dimid, char *name, size_t *lenp) +{ + NC_FILE_INFO_T *nc; + NC_HDF5_FILE_INFO_T *h5; + NC_GRP_INFO_T *grp, *dim_grp; + NC_DIM_INFO_T *dim; + int ret = NC_NOERR; + + LOG((2, "nc_inq_dim: ncid 0x%x dimid %d", ncid, dimid)); + + /* Find our global metadata structure. */ + if ((ret = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return ret; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + { + MPI_Offset mpi_len; + if ((ret = ncmpi_inq_dim(nc->int_ncid, dimid, name, &mpi_len))) + return ret; + if (lenp) + *lenp = mpi_len; + } +#endif /* USE_PNETCDF */ + + /* Take care of netcdf-3 files. */ + assert(h5); + + assert(nc && grp); + + /* Find the dimension and its home group. */ + if ((ret = nc4_find_dim(grp, dimid, &dim, &dim_grp))) + return ret; + assert(dim); + + /* Return the dimension name, if the caller wants it. */ + if (name && dim->name) + strcpy(name, dim->name); + + /* Return the dimension length, if the caller wants it. */ + if (lenp) + { + if (dim->unlimited) + { + /* Since this is an unlimited dimension, go to the file + and see how many records there are. Take the max number + of records from all the vars that share this + dimension. */ + *lenp = 0; + if ((ret = nc4_find_dim_len(dim_grp, dimid, &lenp))) + return ret; + } + else + { + if (dim->too_long) + { + ret = NC_EDIMSIZE; + *lenp = NC_MAX_UINT; + } + else + *lenp = dim->len; + } + } + + return ret; +} + +/* Rename a dimension, for those who like to prevaricate. */ +int +NC4_rename_dim(int ncid, int dimid, const char *name) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_DIM_INFO_T *dim; + char norm_name[NC_MAX_NAME + 1]; + int retval; + + if (!name) + return NC_EINVAL; + + LOG((2, "nc_rename_dim: ncid 0x%x dimid %d name %s", ncid, + dimid, name)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + assert(nc); + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_rename_dim(nc->int_ncid, dimid, name); +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 cases. */ + assert(h5); + assert(h5 && grp); + + /* Trying to write to a read-only file? No way, Jose! */ + if (h5->no_write) + return NC_EPERM; + + /* Make sure this is a valid netcdf name. */ + if ((retval = nc4_check_name(name, norm_name))) + return retval; + + /* Make sure the new name is not already in use in this group. */ + for (dim = grp->dim; dim; dim = dim->next) + if (!strncmp(dim->name, norm_name, NC_MAX_NAME)) + return NC_ENAMEINUSE; + + /* Find the dim. */ + for (dim = grp->dim; dim; dim = dim->next) + if (dim->dimid == dimid) + break; + if (!dim) + return NC_EBADDIM; + + /* If not in define mode, switch to it, unless the new name is + * shorter. (This is in accordance with the v3 interface.) */ +/* if (!(h5->flags & NC_INDEF) && strlen(name) > strlen(dim->name)) */ +/* { */ +/* if (h5->cmode & NC_CLASSIC_MODEL) */ +/* return NC_ENOTINDEFINE; */ +/* if ((retval = nc_redef(ncid))) */ +/* return retval; */ +/* } */ + + /* Save the old name, we'll need it to rename this object when we + * sync to HDF5 file. But if there already is an old_name saved, + * just stick with what we've got, since the user might be renaming + * the crap out of this thing, without ever syncing with the + * file. When the sync does take place, we only need the original + * name of the dim, not any of the intermediate ones. If the user + * could just make up his mind, we could all get on to writing some + * data... */ + if (!dim->old_name) + { + if (!(dim->old_name = malloc((strlen(dim->name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(dim->old_name, dim->name); + } + + /* Give the dimension its new name in metadata. UTF8 normalization + * has been done. */ + free(dim->name); + if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(dim->name, norm_name); + + return NC_NOERR; +} + +/* Returns an array of unlimited dimension ids.The user can get the + number of unlimited dimensions by first calling this with NULL for + the second pointer. +*/ +int +NC4_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp) +{ + NC_DIM_INFO_T *dim; + NC_GRP_INFO_T *grp; + NC_FILE_INFO_T *nc; + NC_HDF5_FILE_INFO_T *h5; + int num_unlim = 0; + int retval; + + LOG((2, "nc_inq_unlimdims: ncid 0x%x", ncid)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + + /* Get our dim info. */ + assert(h5); + { + for (dim=grp->dim; dim; dim=dim->next) + { + if (dim->unlimited) + { + if (unlimdimidsp) + unlimdimidsp[num_unlim] = dim->dimid; + num_unlim++; + } + } + } + + /* Give the number if the user wants it. */ + if (nunlimdimsp) + *nunlimdimsp = num_unlim; + + return NC_NOERR; +} + + diff --git a/extern/src_netcdf4/nc4dispatch.c b/extern/src_netcdf4/nc4dispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..ca316cba67b9e6eed725123d8ca549253edf10b4 --- /dev/null +++ b/extern/src_netcdf4/nc4dispatch.c @@ -0,0 +1,110 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libsrc4/nc4dispatch.c,v 1.5 2010/05/27 02:19:37 dmh Exp $ + *********************************************************************/ + +#include "config.h" +#include +#include "nc.h" +#include "ncdispatch.h" +#include "nc4dispatch.h" + +NC_Dispatch NC4_dispatcher = { + +NC_DISPATCH_NC4, + +NC4_new_nc, + +NC4_create, +NC4_open, + +NC4_redef, +NC4__enddef, +NC4_sync, +NC4_abort, +NC4_close, +NC4_set_fill, +NC4_inq_base_pe, +NC4_set_base_pe, +NC4_inq_format, + +NC4_inq, +NC4_inq_type, + +NC4_def_dim, +NC4_inq_dimid, +NC4_inq_dim, +NC4_inq_unlimdim, +NC4_rename_dim, + +NC4_inq_att, +NC4_inq_attid, +NC4_inq_attname, +NC4_rename_att, +NC4_del_att, +NC4_get_att, +NC4_put_att, + +NC4_def_var, +NC4_inq_varid, +NC4_rename_var, +NC4_get_vara, +NC4_put_vara, +NCDEFAULT_get_vars, +NCDEFAULT_put_vars, +NCDEFAULT_get_varm, +NCDEFAULT_put_varm, + +NC4_inq_var_all, + +NC4_show_metadata, +NC4_inq_unlimdims, + +NC4_var_par_access, + +NC4_inq_ncid, +NC4_inq_grps, +NC4_inq_grpname, +NC4_inq_grpname_full, +NC4_inq_grp_parent, +NC4_inq_grp_full_ncid, +NC4_inq_varids, +NC4_inq_dimids, +NC4_inq_typeids, +NC4_inq_type_equal, +NC4_def_grp, +NC4_inq_user_type, +NC4_inq_typeid, + +NC4_def_compound, +NC4_insert_compound, +NC4_insert_array_compound, +NC4_inq_compound_field, +NC4_inq_compound_fieldindex, +NC4_def_vlen, +NC4_put_vlen_element, +NC4_get_vlen_element, +NC4_def_enum, +NC4_insert_enum, +NC4_inq_enum_member, +NC4_inq_enum_ident, +NC4_def_opaque, +NC4_def_var_deflate, +NC4_def_var_fletcher32, +NC4_def_var_chunking, +NC4_def_var_fill, +NC4_def_var_endian, +NC4_set_var_chunk_cache, +NC4_get_var_chunk_cache, + +}; + +NC_Dispatch* NC4_dispatch_table = NULL; /* moved here from ddispatch.c */ + +int +NC4_initialize(void) +{ + NC4_dispatch_table = &NC4_dispatcher; + return NC_NOERR; +} diff --git a/extern/src_netcdf4/nc4dispatch.h b/extern/src_netcdf4/nc4dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..feea0aafe9ab2ebfbeaa4959f2552684cc4be0cc --- /dev/null +++ b/extern/src_netcdf4/nc4dispatch.h @@ -0,0 +1,271 @@ +/********************************************************************* + * Copyright 2010, UCAR/Unidata. See netcdf/COPYRIGHT file for copying + * and redistribution conditions. + * + * This header file contains the prototypes for the netCDF-4 versions + * of all the netCDF functions. + *********************************************************************/ + +#ifndef _NC4DISPATCH_H +#define _NC4DISPATCH_H + +#include "config.h" +#include /* size_t, ptrdiff_t */ +#include /* netcdf functions sometimes return system errors */ +#include "ncdispatch.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +extern int +NC4_create(const char *path, int cmode, + size_t initialsz, int basepe, size_t *chunksizehintp, + int useparallel, void* parameters, + NC_Dispatch*, NC**); + +extern int +NC4_open(const char *path, int mode, + int basepe, size_t *chunksizehintp, + int use_parallel, void* parameters, + NC_Dispatch*, NC**); + +extern int +NC4_new_nc(NC**); + +extern int +NC4_free_nc(NC*); + +extern int +NC4_redef(int ncid); + +extern int +NC4__enddef(int ncid, size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align); + +extern int +NC4_sync(int ncid); + +extern int +NC4_abort(int ncid); + +extern int +NC4_close(int ncid); + +extern int +NC4_set_fill(int ncid, int fillmode, int *old_modep); + +extern int +NC4_set_base_pe(int ncid, int pe); + +extern int +NC4_inq_base_pe(int ncid, int *pe); + +extern int +NC4_inq_format(int ncid, int *formatp); + +extern int +NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp); + +extern int +NC4_inq_type(int, nc_type, char *, size_t *); + +/* Begin _dim */ + +extern int +NC4_def_dim(int ncid, const char *name, size_t len, int *idp); + +extern int +NC4_inq_dimid(int ncid, const char *name, int *idp); + +extern int +NC4_inq_dim(int ncid, int dimid, char *name, size_t *lenp); + +extern int +NC4_inq_unlimdim(int ncid, int *unlimdimidp); + +extern int +NC4_rename_dim(int ncid, int dimid, const char *name); + +/* End _dim */ +/* Begin _att */ + +extern int +NC4_inq_att(int ncid, int varid, const char *name, + nc_type *xtypep, size_t *lenp); + +extern int +NC4_inq_attid(int ncid, int varid, const char *name, int *idp); + +extern int +NC4_inq_attname(int ncid, int varid, int attnum, char *name); + +extern int +NC4_rename_att(int ncid, int varid, const char *name, const char *newname); + +extern int +NC4_del_att(int ncid, int varid, const char*); + +/* End _att */ +/* Begin {put,get}_att */ + +extern int +NC4_get_att(int ncid, int varid, const char *name, void *value, nc_type); + +extern int +NC4_put_att(int ncid, int varid, const char *name, nc_type datatype, + size_t len, const void *value, nc_type); + +/* End {put,get}_att */ +/* Begin _var */ + +extern int +NC4_def_var(int ncid, const char *name, + nc_type xtype, int ndims, const int *dimidsp, int *varidp); + +extern int +NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp, + int *shufflep, int *deflatep, int *deflate_levelp, + int *fletcher32p, int *contiguousp, size_t *chunksizesp, + int *no_fill, void *fill_valuep, int *endiannessp, + int *options_maskp, int *pixels_per_blockp); + +extern int +NC4_inq_varid(int ncid, const char *name, int *varidp); + +extern int +NC4_rename_var(int ncid, int varid, const char *name); + +extern int +NC4_put_vara(int ncid, int varid, + const size_t *start, const size_t *count, + const void *value, nc_type); + +extern int +NC4_get_vara(int ncid, int varid, + const size_t *start, const size_t *count, + void *value, nc_type); + +/* End _var */ + +/* netCDF4 API only */ +extern int +NC4_var_par_access(int, int, int); + +extern int +NC4_inq_ncid(int, const char *, int *); + +extern int +NC4_inq_grps(int, int *, int *); + +extern int +NC4_inq_grpname(int, char *); + +extern int +NC4_inq_grpname_full(int, size_t *, char *); + +extern int +NC4_inq_grp_parent(int, int *); + +extern int +NC4_inq_grp_full_ncid(int, const char *, int *); + +extern int +NC4_inq_varids(int, int * nvars, int *); + +extern int +NC4_inq_dimids(int, int * ndims, int *, int); + +extern int +NC4_inq_typeids(int, int * ntypes, int *); + +extern int +NC4_inq_type_equal(int, nc_type, int, nc_type, int *); + +extern int +NC4_def_grp(int, const char *, int *); + +extern int +NC4_inq_user_type(int, nc_type, char *, size_t *, nc_type *, + size_t *, int *); + +extern int +NC4_def_compound(int, size_t, const char *, nc_type *); + +extern int +NC4_insert_compound(int, nc_type, const char *, size_t, nc_type); + +extern int +NC4_insert_array_compound(int, nc_type, const char *, size_t, + nc_type, int, const int *); + +extern int +NC4_inq_typeid(int, const char *, nc_type *); + +extern int +NC4_inq_compound_field(int, nc_type, int, char *, size_t *, + nc_type *, int *, int *); + +extern int +NC4_inq_compound_fieldindex(int, nc_type, const char *, int *); + +extern int +NC4_def_vlen(int, const char *, nc_type base_typeid, nc_type *); + +extern int +NC4_put_vlen_element(int, int, void *, size_t, const void *); + +extern int +NC4_get_vlen_element(int, int, const void *, size_t *, void *); + +extern int +NC4_def_enum(int, nc_type, const char *, nc_type *); + +extern int +NC4_insert_enum(int, nc_type, const char *, const void *); + +extern int +NC4_inq_enum_member(int, nc_type, int, char *, void *); + +extern int +NC4_inq_enum_ident(int, nc_type, long long, char *); + +extern int +NC4_def_opaque(int, size_t, const char *, nc_type *); + +extern int +NC4_def_var_deflate(int, int, int, int, int); + +extern int +NC4_def_var_fletcher32(int, int, int); + +extern int +NC4_def_var_chunking(int, int, int, const size_t *); + +extern int +NC4_def_var_fill(int, int, int, const void *); + +extern int +NC4_def_var_endian(int, int, int); + +extern int +NC4_set_var_chunk_cache(int, int, size_t, size_t, float); + +extern int +NC4_get_var_chunk_cache(int, int, size_t *, size_t *, float *); + +extern int +NC4_inq_unlimdims(int, int *, int *); + +extern int +NC4_show_metadata(int); + +extern int +NC4_initialize(void); + +#if defined(__cplusplus) +} +#endif + +#endif /*_NC4DISPATCH_H */ diff --git a/extern/src_netcdf4/nc4file.c b/extern/src_netcdf4/nc4file.c new file mode 100644 index 0000000000000000000000000000000000000000..bea85d8423f0e59af2d626e5131bfff12d2fb42a --- /dev/null +++ b/extern/src_netcdf4/nc4file.c @@ -0,0 +1,3203 @@ +/** \file +The netCDF-4 file functions. + +This file is part of netcdf-4, a netCDF-like interface for HDF5, or +a HDF5 backend for netCDF, depending on your point of view. + +Copyright 2003, University Corporation for Atmospheric Research. See +COPYRIGHT file for copying and redistribution conditions. +*/ + +#include "nc4internal.h" +#include "nc.h" +#include +#include "nc4dispatch.h" +#include "ncdispatch.h" + +#ifdef USE_HDF4 +#include +#endif + +#ifdef USE_PNETCDF +#include +#endif + +/* This is to track opened HDF5 objects to make sure they are + * closed. */ +#ifdef EXTRA_TESTS +extern int num_plists; +extern int num_spaces; +#endif /* EXTRA_TESTS */ + +#define MIN_DEFLATE_LEVEL 0 +#define MAX_DEFLATE_LEVEL 9 + +/* These are the special attributes added by the HDF5 dimension scale + * API. They will be ignored by netCDF-4. */ +#define REFERENCE_LIST "REFERENCE_LIST" +#define CLASS "CLASS" +#define DIMENSION_LIST "DIMENSION_LIST" +#define NAME "NAME" + +/* Forward */ +static int NC4_enddef(int ncid); +static int nc4_rec_read_types(NC_GRP_INFO_T *grp); +static int nc4_rec_read_vars(NC_GRP_INFO_T *grp); + +#ifdef IGNORE +/* This extern points to the pointer that holds the list of open + * netCDF files. */ +extern NC_FILE_INFO_T *nc_file; +#endif + +/* These are the default chunk cache sizes for HDF5 files created or + * opened with netCDF-4. */ +size_t nc4_chunk_cache_size = CHUNK_CACHE_SIZE; +size_t nc4_chunk_cache_nelems = CHUNK_CACHE_NELEMS; +float nc4_chunk_cache_preemption = CHUNK_CACHE_PREEMPTION; + +/* This is set by nc_set_default_format in libsrc/nc.c. */ +extern int default_create_format; + +/* To turn off HDF5 error messages, I have to catch an early + invocation of a netcdf function. */ +static int virgin = 1; + +/* For performance, fill this array only the first time, and keep it + * in global memory for each further use. */ +#define NUM_TYPES 12 +static hid_t native_type_constant[NUM_TYPES]; + +static char nc_type_name[NUM_TYPES][NC_MAX_NAME + 1] = {"char", "byte", "short", "int", "float", + "double", "ubyte", "ushort", "uint", + "int64", "uint64", "string"}; +int nc4_free_global_hdf_string_typeid(); + +/* Set chunk cache size. Only affects files opened/created *after* it + * is called. */ +int +nc_set_chunk_cache(size_t size, size_t nelems, float preemption) +{ + if (preemption < 0 || preemption > 1) + return NC_EINVAL; + nc4_chunk_cache_size = size; + nc4_chunk_cache_nelems = nelems; + nc4_chunk_cache_preemption = preemption; + return NC_NOERR; +} + +/* Get chunk cache size. Only affects files opened/created *after* it + * is called. */ +int +nc_get_chunk_cache(size_t *sizep, size_t *nelemsp, float *preemptionp) +{ + if (sizep) + *sizep = nc4_chunk_cache_size; + + if (nelemsp) + *nelemsp = nc4_chunk_cache_nelems; + + if (preemptionp) + *preemptionp = nc4_chunk_cache_preemption; + return NC_NOERR; +} + +/* Required for fortran to avoid size_t issues. */ +int +nc_set_chunk_cache_ints(int size, int nelems, int preemption) +{ + if (size <= 0 || nelems <= 0 || preemption < 0 || preemption > 100) + return NC_EINVAL; + nc4_chunk_cache_size = size; + nc4_chunk_cache_nelems = nelems; + nc4_chunk_cache_preemption = (float)preemption / 100; + return NC_NOERR; +} + +int +nc_get_chunk_cache_ints(int *sizep, int *nelemsp, int *preemptionp) +{ + if (sizep) + *sizep = (int)nc4_chunk_cache_size; + if (nelemsp) + *nelemsp = (int)nc4_chunk_cache_nelems; + if (preemptionp) + *preemptionp = (int)(nc4_chunk_cache_preemption * 100); + + return NC_NOERR; +} + +/* This will return the length of a netcdf data type in bytes. */ +int +nc4typelen(nc_type type) +{ + switch(type){ + case NC_BYTE: + case NC_CHAR: + case NC_UBYTE: + return 1; + case NC_USHORT: + case NC_SHORT: + return 2; + case NC_FLOAT: + case NC_INT: + case NC_UINT: + return 4; + case NC_DOUBLE: + case NC_INT64: + case NC_UINT64: + return 8; + } + return -1; +} + +/* Given a filename, check to see if it is a HDF5 file. */ +#define MAGIC_NUMBER_LEN 4 +#define NC_HDF5_FILE 1 +#define NC_HDF4_FILE 2 +static int +nc_check_for_hdf(const char *path, int use_parallel, MPI_Comm comm, MPI_Info info, + int *hdf_file) +{ + char blob[MAGIC_NUMBER_LEN]; + + assert(hdf_file && path); + LOG((3, "nc_check_for_hdf: path %s", path)); + +/* Get the 4-byte blob from the beginning of the file. Don't use posix + * for parallel, use the MPI functions instead. */ +#ifdef USE_PARALLEL + if (use_parallel) + { + MPI_File fh; + MPI_Status status; + int retval; + if ((retval = MPI_File_open(comm, (char *)path, MPI_MODE_RDONLY, + info, &fh)) != MPI_SUCCESS) + return NC_EPARINIT; + if ((retval = MPI_File_read(fh, blob, MAGIC_NUMBER_LEN, MPI_CHAR, + &status)) != MPI_SUCCESS) + return NC_EPARINIT; + if ((retval = MPI_File_close(&fh)) != MPI_SUCCESS) + return NC_EPARINIT; + } + else +#endif /* USE_PARALLEL */ + { + FILE *fp; + if (!(fp = fopen(path, "r")) || + fread(blob, MAGIC_NUMBER_LEN, 1, fp) != 1) + return errno; + fclose(fp); + } + + /* Ignore the first byte for HDF5. */ + if (blob[1] == 'H' && blob[2] == 'D' && blob[3] == 'F') + *hdf_file = NC_HDF5_FILE; + else if (!strncmp(blob, "\016\003\023\001", MAGIC_NUMBER_LEN)) + *hdf_file = NC_HDF4_FILE; + else + *hdf_file = 0; + + return NC_NOERR; +} + +/* Create a HDF5/netcdf-4 file. In this case, ncid has already been + * selected in ncfunc.c. */ +static int +nc4_create_file(const char *path, int cmode, MPI_Comm comm, MPI_Info info, + NC_FILE_INFO_T *nc) +{ + hid_t fcpl_id, fapl_id; + unsigned flags; + FILE *fp; + int retval = NC_NOERR; + int persist = 0; /* Should diskless try to persist its data into file?*/ + + if(cmode & NC_DISKLESS) + flags = H5F_ACC_TRUNC; + else if(cmode & NC_NOCLOBBER) + flags = H5F_ACC_EXCL; + else + flags = H5F_ACC_TRUNC; + + LOG((3, "nc4_create_file: path %s mode 0x%x", path, cmode)); + assert(nc && path); + + + /* If this file already exists, and NC_NOCLOBBER is specified, + return an error. */ + if (cmode & NC_DISKLESS) { + if(cmode & NC_WRITE) + persist = 1; + } else if ((cmode & NC_NOCLOBBER) && (fp = fopen(path, "r"))) { + fclose(fp); + return NC_EEXIST; + } + + /* Add necessary structs to hold netcdf-4 file data. */ + if ((retval = nc4_nc4f_list_add(nc, path, (NC_WRITE | cmode)))) + BAIL(retval); + assert(nc->nc4_info && nc->nc4_info->root_grp); + + /* Need this access plist to control how HDF5 handles open onjects + * on file close. (Setting H5F_CLOSE_SEMI will cause H5Fclose to + * fail if there are any open objects in the file. */ + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif +#ifdef EXTRA_TESTS + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI)) + BAIL(NC_EHDFERR); +#else + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) + BAIL(NC_EHDFERR); +#endif /* EXTRA_TESTS */ + +#ifdef USE_PARALLEL + /* If this is a parallel file create, set up the file creation + property list. */ + if ((cmode & NC_MPIIO) || (cmode & NC_MPIPOSIX)) + { + nc->nc4_info->parallel++; + if (cmode & NC_MPIIO) /* MPI/IO */ + { + LOG((4, "creating parallel file with MPI/IO")); + if (H5Pset_fapl_mpio(fapl_id, comm, info) < 0) + BAIL(NC_EPARINIT); + } + else /* MPI/POSIX */ + { + LOG((4, "creating parallel file with MPI/posix")); + if (H5Pset_fapl_mpiposix(fapl_id, comm, 0) < 0) + BAIL(NC_EPARINIT); + } + } +#else /* only set cache for non-parallel... */ + if(cmode & NC_DISKLESS) { + if (H5Pset_fapl_core(fapl_id, 4096, persist)) + BAIL(NC_EDISKLESS); + } + if (H5Pset_cache(fapl_id, 0, nc4_chunk_cache_nelems, nc4_chunk_cache_size, + nc4_chunk_cache_preemption) < 0) + BAIL(NC_EHDFERR); + LOG((4, "nc4_create_file: set HDF raw chunk cache to size %d nelems %d preemption %f", + nc4_chunk_cache_size, nc4_chunk_cache_nelems, nc4_chunk_cache_preemption)); +#endif /* USE_PARALLEL */ + + if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_18, H5F_LIBVER_18) < 0) + BAIL(NC_EHDFERR); + + /* Create the property list. */ + if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif + + /* Set latest_format in access propertly list and + * H5P_CRT_ORDER_TRACKED in the creation property list. This turns + * on HDF5 creation ordering. */ + if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED | + H5P_CRT_ORDER_INDEXED)) < 0) + BAIL(NC_EHDFERR); + if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED | + H5P_CRT_ORDER_INDEXED)) < 0) + BAIL(NC_EHDFERR); + + /* Create the file. */ + if ((nc->nc4_info->hdfid = H5Fcreate(path, flags, fcpl_id, fapl_id)) < 0) + BAIL(NC_EFILEMETA); + + /* Open the root group. */ + if ((nc->nc4_info->root_grp->hdf_grpid = H5Gopen2(nc->nc4_info->hdfid, "/", + H5P_DEFAULT)) < 0) + BAIL(NC_EFILEMETA); + + /* Release the property lists. */ + if (H5Pclose(fapl_id) < 0 || + H5Pclose(fcpl_id) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; + num_plists--; +#endif + + /* Define mode gets turned on automatically on create. */ + nc->nc4_info->flags |= NC_INDEF; + + return NC_NOERR; + + exit: + if (nc->nc4_info->hdfid > 0) H5Fclose(nc->nc4_info->hdfid); + return retval; +} + +/** \ingroup netcdf4 +Create a netCDF-4/HDF5 file. + +\param path The file name of the new file. +\param cmode The creation mode flag. +\param initialsz Ignored by this function. +\param basepe Ignored by this function. +\param chunksizehintp Ignored by this function. +\param use_parallel 0 for sequential, non-zero for parallel I/O. +\param mpidata pointer to struct holdind data for parallel I/O +layer. Ignored if NULL. +\param dispatch Pointer to the dispatch table for this file. +\param ncpp Pointer to start of linked list of open files. +\return NC_INVAL Invalid input (check cmode). +*/ +int +NC4_create(const char* path, int cmode, size_t initialsz, int basepe, + size_t *chunksizehintp, int use_parallel, void *mpidata, + NC_Dispatch *dispatch, NC **ncpp) +{ + NC_FILE_INFO_T *nc_file = NULL; +#ifdef USE_PARALLEL + MPI_Comm comm = 0; + MPI_Info info = 0; +#else + int comm = 0, info = 0; +#endif /* USE_PARALLEL */ + int res; + + assert(ncpp && path); + + LOG((1, "nc4_create_file: path %s cmode 0x%x comm %d info %d", + path, cmode, comm, info)); + +#ifdef USE_PARALLEL + if (mpidata) + { + comm = ((NC_MPI_INFO *)mpidata)->comm; + info = ((NC_MPI_INFO *)mpidata)->info; + } +#endif /* USE_PARALLEL */ + + /* If this is our first file, turn off HDF5 error messages. */ + if (virgin) + { + if (H5Eset_auto(NULL, NULL) < 0) + LOG((0, "Couldn't turn off HDF5 error messages!")); + LOG((1, "HDF5 error messages have been turned off.")); + virgin = 0; + } + + /* Check the cmode for validity. */ + if (cmode & ~(NC_NOCLOBBER | NC_64BIT_OFFSET + | NC_NETCDF4 | NC_CLASSIC_MODEL + | NC_SHARE | NC_MPIIO | NC_MPIPOSIX | NC_LOCK | NC_PNETCDF + | NC_DISKLESS + | NC_WRITE /* to support diskless persistence */ + ) + || (cmode & NC_MPIIO && cmode & NC_MPIPOSIX) + || (cmode & NC_64BIT_OFFSET && cmode & NC_NETCDF4) + || (cmode & (NC_MPIIO | NC_MPIPOSIX) && cmode & NC_DISKLESS) + ) + return NC_EINVAL; + + /* Allocate the storage for this file info struct, and fill it with + zeros. This add the file metadata to the front of the global + nc_file list. */ + if ((res = nc4_file_list_add(&nc_file, dispatch))) + return res; + + /* Apply default create format. */ + if (default_create_format == NC_FORMAT_64BIT) + cmode |= NC_64BIT_OFFSET; + else if (default_create_format == NC_FORMAT_NETCDF4) + cmode |= NC_NETCDF4; + else if (default_create_format == NC_FORMAT_NETCDF4_CLASSIC) + { + cmode |= NC_NETCDF4; + cmode |= NC_CLASSIC_MODEL; + } + LOG((2, "cmode after applying default format: 0x%x", cmode)); + + /* Check to see if we want a netcdf3 or netcdf4 file. Open it, and + call the appropriate nc*_create. */ + if (cmode & NC_NETCDF4) + { + nc_file->int_ncid = nc_file->ext_ncid; + res = nc4_create_file(path, cmode, comm, info, nc_file); + } +#ifdef USE_PNETCDF + else if (cmode & NC_PNETCDF) + { + nc_file->pnetcdf_file++; + res = ncmpi_create(comm, path, cmode, info, &(nc_file->int_ncid)); + } +#endif /* USE_PNETCDF */ + else + { + return NC_EINVAL; + } + + /* Delete this file list entry if there was a failure. */ + if (res) + { + if (nc_file) + nc4_file_list_del(nc_file); + } + else + *ncpp = (NC *)nc_file; + + return res; +} + +/* This function is called by read_dataset when a dimension scale + * dataset is encountered. It reads in the dimension data (creating a + * new NC_DIM_INFO_T object), and also checks to see if this is a + * dimension without a variable - that is, a coordinate dimension + * which does not have any coordinate data. */ +static int +read_scale(NC_GRP_INFO_T *grp, hid_t datasetid, char *obj_name, + hsize_t scale_size, hsize_t max_scale_size, + int *dim_without_var) +{ + /*char *start_of_len;*/ + char dimscale_name_att[NC_MAX_NAME + 1] = ""; + hid_t attid = 0; + int max_len; + int retval; + + /* Add a dimension for this scale. */ + if ((retval = nc4_dim_list_add(&grp->dim))) + return retval; + + /* Assign dimid and increment number of dimensions. */ + grp->dim->dimid = grp->file->nc4_info->next_dimid++; + grp->ndims++; + + /* Does this dataset have a hidden attribute that tells us its + * dimid? If so, read it. */ + H5E_BEGIN_TRY { + if ((attid = H5Aopen_by_name(datasetid, ".", NC_DIMID_ATT_NAME, + H5P_DEFAULT, H5P_DEFAULT)) > 0) + { + if (H5Aread(attid, H5T_NATIVE_INT, &grp->dim->dimid) < 0) + return NC_EHDFERR; + if (H5Aclose(attid) < 0) + return NC_EHDFERR; + } + } H5E_END_TRY; + + max_len = strlen(obj_name) > NC_MAX_NAME ? NC_MAX_NAME : strlen(obj_name); + if (!(grp->dim->name = malloc((max_len + 1) * sizeof(char)))) + return NC_ENOMEM; + strncpy(grp->dim->name, obj_name, max_len + 1); + if (SIZEOF_SIZE_T < 8 && scale_size > NC_MAX_UINT) + { + grp->dim->len = NC_MAX_UINT; + grp->dim->too_long = 1; + } + else + grp->dim->len = scale_size; + grp->dim->hdf_dimscaleid = datasetid; + + /* If the dimscale has an unlimited dimension, then this dimension + * is unlimited. */ + if (max_scale_size == H5S_UNLIMITED) + grp->dim->unlimited++; + + /* If the scale name is set to DIM_WITHOUT_VARIABLE, then this is a + * dimension, but not a variable. (If get_scale_name returns an + * error, just move on, there's no NAME.) */ + if (H5DSget_scale_name(datasetid, dimscale_name_att, NC_MAX_NAME) >= 0) + { + if (!strncmp(dimscale_name_att, DIM_WITHOUT_VARIABLE, + strlen(DIM_WITHOUT_VARIABLE))) + { + if (grp->dim->unlimited) + { + size_t len = 0, *lenp = &len; + if ((retval = nc4_find_dim_len(grp, grp->dim->dimid, &lenp))) + return retval; + grp->dim->len = *lenp; + } + (*dim_without_var)++; + } + } + + return NC_NOERR; +} + +/* This function reads the hacked in coordinates attribute I use for + * multi-dimensional coordinates. */ +static int +read_coord_dimids(NC_VAR_INFO_T *var) +{ + hid_t coord_att_typeid = -1, coord_attid = -1, spaceid = -1; + hssize_t coord_array_size; + int ret = 0; + + /* There is a hidden attribute telling us the ids of the + * dimensions that apply to this multi-dimensional coordinate + * variable. Read it. */ + if ((coord_attid = H5Aopen_name(var->hdf_datasetid, COORDINATES)) < 0) ret++; + if (!ret && (coord_att_typeid = H5Aget_type(coord_attid)) < 0) ret++; + if (!ret && H5Aread(coord_attid, coord_att_typeid, var->dimids) < 0) ret++; + LOG((4, "dimscale %s is multidimensional and has coords", var->name)); + + /* How many dimensions are there? */ + if ((spaceid = H5Aget_space(coord_attid)) < 0) ret++; +#ifdef EXTRA_TESTS + num_spaces++; +#endif + if ((coord_array_size = H5Sget_simple_extent_npoints(spaceid)) < 0) ret++; + + /* Malloc space to the array of pointers to dims. */ + + + /* Set my HDF5 IDs free! */ + if (spaceid >= 0 && H5Sclose(spaceid) < 0) ret++; +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (coord_att_typeid >= 0 && H5Tclose(coord_att_typeid) < 0) ret++; + if (coord_attid >= 0 && H5Aclose(coord_attid) < 0) ret++; + return ret ? NC_EATTMETA : NC_NOERR; +} + +/* This function is called when reading a file's metadata for each + * dimension scale attached to a variable.*/ +static herr_t +dimscale_visitor(hid_t did, unsigned dim, hid_t dsid, + void *dimscale_hdf5_objids) +{ + H5G_stat_t statbuf; + + /* Get more info on the dimscale object.*/ + if (H5Gget_objinfo(dsid, ".", 1, &statbuf) < 0) + return -1; + + /* Pass this information back to caller. */ +/* (*(HDF5_OBJID_T *)dimscale_hdf5_objids).fileno = statbuf.fileno; + (*(HDF5_OBJID_T *)dimscale_hdf5_objids).objno = statbuf.objno;*/ + (*(HDF5_OBJID_T *)dimscale_hdf5_objids).fileno[0] = statbuf.fileno[0]; + (*(HDF5_OBJID_T *)dimscale_hdf5_objids).fileno[1] = statbuf.fileno[1]; + (*(HDF5_OBJID_T *)dimscale_hdf5_objids).objno[0] = statbuf.objno[0]; + (*(HDF5_OBJID_T *)dimscale_hdf5_objids).objno[1] = statbuf.objno[1]; + return 0; +} + +/* Given an HDF5 type, set a pointer to netcdf type. */ +static int +get_netcdf_type(NC_HDF5_FILE_INFO_T *h5, hid_t native_typeid, + nc_type *xtype) +{ + NC_TYPE_INFO_T *type; + hid_t class; + htri_t is_str, equal = 0; + + assert(h5 && xtype); + + if ((class = H5Tget_class(native_typeid)) < 0) + return NC_EHDFERR; + + /* H5Tequal doesn't work with H5T_C_S1 for some reason. But + * H5Tget_class will return H5T_STRING if this is a string. */ + if (class == H5T_STRING) + { + if ((is_str = H5Tis_variable_str(native_typeid)) < 0) + return NC_EHDFERR; + if (is_str) + *xtype = NC_STRING; + else + *xtype = NC_CHAR; + return NC_NOERR; + } + else if (class == H5T_INTEGER || class == H5T_FLOAT) + { + /* For integers and floats, we don't have to worry about + * endianness if we compare native types. */ + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_SCHAR)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_BYTE; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_SHORT)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_SHORT; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_INT)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_INT; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_FLOAT)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_FLOAT; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_DOUBLE)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_DOUBLE; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_UCHAR)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_UBYTE; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_USHORT)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_USHORT; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_UINT)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_UINT; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_LLONG)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_INT64; + return NC_NOERR; + } + if ((equal = H5Tequal(native_typeid, H5T_NATIVE_ULLONG)) < 0) + return NC_EHDFERR; + if (equal) + { + *xtype = NC_UINT64; + return NC_NOERR; + } + } + + /* Maybe we already know about this type. */ + if (!equal) + if((type = nc4_rec_find_hdf_type(h5->root_grp, native_typeid))) + { + *xtype = type->nc_typeid; + return NC_NOERR; + } + + *xtype = NC_NAT; + return NC_EBADTYPID; +} + +/* Given an HDF5 type, set a pointer to netcdf type_info struct, + * either an existing one (for user-defined types) or a newly created + * one. */ +static int +get_type_info2(NC_HDF5_FILE_INFO_T *h5, hid_t datasetid, + nc_type *xtype, NC_TYPE_INFO_T **type_info) +{ + NC_TYPE_INFO_T *type; + htri_t is_str, equal = 0; + hid_t class, native_typeid, hdf_typeid; +#if 0 + nc_type my_nc_type = 0; +#endif + H5T_order_t order; + int endianness; + nc_type nc_type_constant[NUM_TYPES] = {NC_CHAR, NC_BYTE, NC_SHORT, NC_INT, NC_FLOAT, + NC_DOUBLE, NC_UBYTE, NC_USHORT, NC_UINT, + NC_INT64, NC_UINT64, NC_STRING}; + int type_size[NUM_TYPES] = {sizeof(char), sizeof(char), sizeof(short), + sizeof(int), sizeof(float), sizeof(double), + sizeof(unsigned char), sizeof(unsigned short), + sizeof(unsigned int), sizeof(long long), + sizeof(unsigned long long), 0}; + int t; + + assert(h5 && xtype && type_info); + + /* Because these N5T_NATIVE_* constants are actually function calls + * (!) in H5Tpublic.h, I can't initialize this array in the usual + * way, because at least some C compilers (like Irix) complain + * about calling functions when defining constants. So I have to do + * it like this. Note that there's no native types for char or + * string. Those are handled later. */ + if (!native_type_constant[1]) + { + native_type_constant[1] = H5T_NATIVE_SCHAR; + native_type_constant[2] = H5T_NATIVE_SHORT; + native_type_constant[3] = H5T_NATIVE_INT; + native_type_constant[4] = H5T_NATIVE_FLOAT; + native_type_constant[5] = H5T_NATIVE_DOUBLE; + native_type_constant[6] = H5T_NATIVE_UCHAR; + native_type_constant[7] = H5T_NATIVE_USHORT; + native_type_constant[8] = H5T_NATIVE_UINT; + native_type_constant[9] = H5T_NATIVE_LLONG; + native_type_constant[10] = H5T_NATIVE_ULLONG; + } + + /* Get the HDF5 typeid - we'll need it later. */ + if ((hdf_typeid = H5Dget_type(datasetid)) < 0) + return NC_EHDFERR; + + /* Get the native typeid. Will be equivalent to hdf_typeid when + * creating but not necessarily when reading, a variable. */ + if ((native_typeid = H5Tget_native_type(hdf_typeid, H5T_DIR_DEFAULT)) < 0) + return NC_EHDFERR; + + /* Is this type an integer, string, compound, or what? */ + if ((class = H5Tget_class(native_typeid)) < 0) + return NC_EHDFERR; + + /* Is this an atomic type? */ + if (class == H5T_STRING || class == H5T_INTEGER || class == H5T_FLOAT) + { + /* Allocate a phony NC_TYPE_INFO_T struct to hold type info. */ + if (!(*type_info = calloc(1, sizeof(NC_TYPE_INFO_T)))) + return NC_ENOMEM; + (*type_info)->class = class; + + /* H5Tequal doesn't work with H5T_C_S1 for some reason. But + * H5Tget_class will return H5T_STRING if this is a string. */ + if (class == H5T_STRING) + { + if ((is_str = H5Tis_variable_str(native_typeid)) < 0) + return NC_EHDFERR; + /* Make sure fixed-len strings will work like variable-len strings */ + if (is_str || H5Tget_size(hdf_typeid) > 1) + t = NUM_TYPES - 1; + else + t = 0; + } + else if (class == H5T_INTEGER || class == H5T_FLOAT) + { + for (t = 1; t < NUM_TYPES - 1; t++) + { + if ((equal = H5Tequal(native_typeid, native_type_constant[t])) < 0) + return NC_EHDFERR; + if (equal) + { +#if 0 + my_nc_type = nc_type_constant[t]; +#endif + break; + } + } + + /* Find out about endianness. */ + if (class == H5T_INTEGER) + { + if ((order = H5Tget_order(hdf_typeid)) < 0) + return NC_EHDFERR; + if (order == H5T_ORDER_LE) + endianness = NC_ENDIAN_LITTLE; + else if (order == H5T_ORDER_BE) + endianness = NC_ENDIAN_BIG; + else /* don't support H5T_ORDER_VAX, H5T_ORDER_MIXED, H5T_ORDER_NONE */ + return NC_EBADTYPE; + /* Copy this into the type_info struct. */ + (*type_info)->endianness = endianness; + } + } + *xtype = nc_type_constant[t]; + (*type_info)->nc_typeid = nc_type_constant[t]; + (*type_info)->size = type_size[t]; + if (!((*type_info)->name = malloc((strlen(nc_type_name[t]) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy((*type_info)->name, nc_type_name[t]); + (*type_info)->class = class; + (*type_info)->hdf_typeid = hdf_typeid; + (*type_info)->native_typeid = native_typeid; + (*type_info)->close_hdf_typeid = 1; + return NC_NOERR; + } + else + { + /* This is a user-defined type. */ + if((type = nc4_rec_find_hdf_type(h5->root_grp, native_typeid))) + { + *xtype = type->nc_typeid; + *type_info = type; + } + + /* The type entry in the array of user-defined types already has + * an open data typeid (and native typeid), so close the ones we + * opened above. */ + if (H5Tclose(native_typeid) < 0) + return NC_EHDFERR; + if (H5Tclose(hdf_typeid) < 0) + return NC_EHDFERR; + + if (type) + return NC_NOERR; + } + + *xtype = NC_NAT; + return NC_EBADTYPID; +} + +/* Read an attribute. */ +static int +read_hdf5_att(NC_GRP_INFO_T *grp, hid_t attid, NC_ATT_INFO_T *att) +{ + hid_t spaceid = 0, file_typeid = 0; + hsize_t dims[1]; /* netcdf attributes always 1-D. */ + int retval = NC_NOERR; + size_t type_size; + int att_ndims; + hssize_t att_npoints; + H5T_class_t att_class; + int fixed_len_string = 0; + size_t fixed_size = 0; + + assert(att->name); + LOG((5, "read_hdf5_att: att->attnum %d att->name %s " + "att->xtype %d att->len %d", att->attnum, att->name, + att->xtype, att->len)); + + /* Get type of attribute in file. */ + if ((file_typeid = H5Aget_type(attid)) < 0) + return NC_EATTMETA; + if ((att->native_typeid = H5Tget_native_type(file_typeid, H5T_DIR_DEFAULT)) < 0) + BAIL(NC_EHDFERR); + if ((att_class = H5Tget_class(att->native_typeid)) < 0) + BAIL(NC_EATTMETA); + if (att_class == H5T_STRING && !H5Tis_variable_str(att->native_typeid)) + { + fixed_len_string++; + if (!(fixed_size = H5Tget_size(att->native_typeid))) + BAIL(NC_EATTMETA); + } + if ((retval = get_netcdf_type(grp->file->nc4_info, att->native_typeid, &(att->xtype)))) + BAIL(retval); + + + /* Get len. */ + if ((spaceid = H5Aget_space(attid)) < 0) + BAIL(NC_EATTMETA); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + if ((att_ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) + BAIL(NC_EATTMETA); + if ((att_npoints = H5Sget_simple_extent_npoints(spaceid)) < 0) + BAIL(NC_EATTMETA); + + /* If both att_ndims and att_npoints are zero, then this is a + * zero length att. */ + if (att_ndims == 0 && att_npoints == 0) + { + dims[0] = 0; + } + else if (att->xtype == NC_STRING) { + dims[0] = att_npoints; + } + else if (att->xtype == NC_CHAR) + { + /* NC_CHAR attributes are written as a scalar in HDF5, of type + * H5T_C_S1, of variable length. */ + if (att_ndims == 0) + { + if (!(dims[0] = H5Tget_size(file_typeid))) + BAIL(NC_EATTMETA); + } + else + { + /* This is really a string type! */ + att->xtype = NC_STRING; + dims[0] = att_npoints; + } + } + else + { + /* All netcdf attributes are scalar or 1-D only. */ + if (att_ndims > 1) + BAIL(NC_EATTMETA); + + /* Read the size of this attribute. */ + if (H5Sget_simple_extent_dims(spaceid, dims, NULL) < 0) + BAIL(NC_EATTMETA); + } + + /* Tell the user what the length if this attribute is. */ + att->len = dims[0]; + + /* Allocate some memory if the len is not zero, and read the + attribute. */ + if (dims[0]) + { + if ((retval = nc4_get_typelen_mem(grp->file->nc4_info, att->xtype, 0, + &type_size))) + return retval; + if (att_class == H5T_VLEN) + { + if (!(att->vldata = malloc((unsigned int)(att->len * sizeof(hvl_t))))) + BAIL(NC_ENOMEM); + if (H5Aread(attid, att->native_typeid, att->vldata) < 0) + BAIL(NC_EATTMETA); + } + else if (att->xtype == NC_STRING) + { + if (!(att->stdata = calloc(att->len, sizeof(char *)))) + BAIL(NC_ENOMEM); + /* For a fixed length HDF5 string, the read requires + * contiguous memory. Meanwhile, the netCDF API requires that + * nc_free_string be called on string arrays, which would not + * work if one contiguous memory block were used. So here I + * convert the contiguous block of strings into an array of + * malloced strings (each string with its own malloc). Then I + * copy the data and free the contiguous memory. This + * involves copying the data, which is bad, but this only + * occurs for fixed length string attributes, and presumably + * these are small. (And netCDF-4 does not create them - it + * always uses variable length strings. */ + if (fixed_len_string) + { + int i; + char *contig_buf, *cur; + + /* Alloc space for the contiguous memory read. */ + if (!(contig_buf = malloc(att->len * fixed_size * sizeof(char)))) + BAIL(NC_ENOMEM); + + /* Read the fixed-len strings as one big block. */ + if (H5Aread(attid, att->native_typeid, contig_buf) < 0) + BAIL(NC_EATTMETA); + + /* Copy strings, one at a time, into their new home. Alloc + space for each string. The user will later free this + space with nc_free_string. */ + cur = contig_buf; + for (i = 0; i < att->len; i++) + { + if (!(att->stdata[i] = malloc(fixed_size))) + BAIL(NC_ENOMEM); + strncpy(att->stdata[i], cur, fixed_size); + cur += fixed_size; + } + + /* Free contiguous memory buffer. */ + free(contig_buf); + } + else + { + /* Read variable-length string atts. */ + if (H5Aread(attid, att->native_typeid, att->stdata) < 0) + BAIL(NC_EATTMETA); + } + } + else + { + if (!(att->data = malloc((unsigned int)(att->len * type_size)))) + BAIL(NC_ENOMEM); + if (H5Aread(attid, att->native_typeid, att->data) < 0) + BAIL(NC_EATTMETA); + } + } + + if (H5Tclose(file_typeid) < 0) + BAIL(NC_EHDFERR); + if (H5Sclose(spaceid) < 0) + return NC_EHDFERR; +#ifdef EXTRA_TESTS + num_spaces--; +#endif + + return NC_NOERR; + + exit: + if (H5Tclose(file_typeid) < 0) + BAIL2(NC_EHDFERR); + if (spaceid > 0 && H5Sclose(spaceid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + return retval; +} + +/* Read information about a user defined type from the HDF5 file, and + * stash it in the group's list of types. Return the netcdf typeid + * through a pointer, if caller desires it. */ +static int +read_type(NC_GRP_INFO_T *grp, char *type_name) +{ + NC_TYPE_INFO_T *type; + H5T_class_t class; + hid_t hdf_typeid, native_typeid = 0; + int nmembers; + hid_t member_hdf_typeid, base_hdf_typeid = 0; + char *member_name = NULL; + size_t type_size = 0, member_offset; + unsigned int m; + nc_type ud_type_type = NC_NAT, base_nc_type = NC_NAT, member_xtype; + htri_t ret; + int retval = NC_NOERR; + void *value; + int i; + + assert(grp && type_name); + + if (strlen(type_name) > NC_MAX_NAME) + return NC_EBADNAME; + + LOG((4, "read_type: type_name %s grp->name %s", type_name, grp->name)); + + if ((hdf_typeid = H5Topen2(grp->hdf_grpid, type_name, H5P_DEFAULT)) < 0) + return NC_EHDFERR; + + /* What is the native type for this platform? */ + if ((native_typeid = H5Tget_native_type(hdf_typeid, H5T_DIR_DEFAULT)) < 0) + return NC_EHDFERR; + + /* What is the size of this type on this platform. */ + if (!(type_size = H5Tget_size(native_typeid))) + return NC_EHDFERR; + LOG((5, "type_size %d", type_size)); + + /* What is the class of this type, compound, vlen, etc. */ + if ((class = H5Tget_class(hdf_typeid)) < 0) + return NC_EHDFERR; + switch (class) + { + case H5T_STRING: + ud_type_type = NC_STRING; + break; + case H5T_COMPOUND: + ud_type_type = NC_COMPOUND; + break; + case H5T_VLEN: + /* For conveninence we allow user to pass vlens of strings + * with null terminated strings. This means strings are + * treated slightly differently by the API, although they are + * really just VLENs of characters. */ + if ((ret = H5Tis_variable_str(hdf_typeid)) < 0) + return NC_EHDFERR; + if (ret) + ud_type_type = NC_STRING; + else + { + ud_type_type = NC_VLEN; + + /* Find the base type of this vlen (i.e. what is this a + * vlen of?) */ + if (!(base_hdf_typeid = H5Tget_super(native_typeid))) + return NC_EHDFERR; + + /* What size is this type? */ + if (!(type_size = H5Tget_size(base_hdf_typeid))) + return NC_EHDFERR; + + /* What is the netcdf corresponding type. */ + if ((retval = get_netcdf_type(grp->file->nc4_info, base_hdf_typeid, + &base_nc_type))) + return retval; + LOG((5, "base_hdf_typeid 0x%x type_size %d base_nc_type %d", + base_hdf_typeid, type_size, base_nc_type)); + } + break; + case H5T_OPAQUE: + ud_type_type = NC_OPAQUE; + /* What size is this type? */ + if (!(type_size = H5Tget_size(hdf_typeid))) + return NC_EHDFERR; + LOG((5, "type_size %d", type_size)); + break; + case H5T_ENUM: + ud_type_type = NC_ENUM; + + /* Find the base type of this enum (i.e. what is this a + * enum of?) */ + if (!(base_hdf_typeid = H5Tget_super(hdf_typeid))) + return NC_EHDFERR; + /* What size is this type? */ + if (!(type_size = H5Tget_size(base_hdf_typeid))) + return NC_EHDFERR; + /* What is the netcdf corresponding type. */ + if ((retval = get_netcdf_type(grp->file->nc4_info, base_hdf_typeid, + &base_nc_type))) + return retval; + LOG((5, "base_hdf_typeid 0x%x type_size %d base_nc_type %d", + base_hdf_typeid, type_size, base_nc_type)); + break; + default: + LOG((0, "unknown class")); + return NC_EBADCLASS; + } + + /* Add to the list for this new type, and get a local pointer to it. */ + if ((retval = nc4_type_list_add(&grp->type, &type))) + return retval; + assert(type); + + /* Remember info about this type. */ + type->nc_typeid = grp->file->nc4_info->next_typeid++; + type->size = type_size; + if (!(type->name = malloc((strlen(type_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(type->name, type_name); + type->class = ud_type_type; + type->base_nc_type = base_nc_type; + type->committed++; + type->hdf_typeid = hdf_typeid; + type->native_typeid = native_typeid; + + /* Read info about each member of this compound type. */ + if (ud_type_type == NC_COMPOUND) + { + if ((nmembers = H5Tget_nmembers(hdf_typeid)) < 0) + return NC_EHDFERR; + LOG((5, "compound type has %d members", nmembers)); + for (m = 0; m < nmembers; m++) + { + H5T_class_t mem_class; + hid_t member_native_typeid; + int ndims = 0, dim_size[NC_MAX_VAR_DIMS]; + hsize_t dims[NC_MAX_VAR_DIMS]; + int d; + + /* Get the typeid and native typeid of this member of the + * compound type. */ + if ((member_hdf_typeid = H5Tget_member_type(type->native_typeid, m)) < 0) + return NC_EHDFERR; + if ((member_native_typeid = H5Tget_native_type(member_hdf_typeid, H5T_DIR_DEFAULT)) < 0) + return NC_EHDFERR; + + /* Get the name of the member.*/ + member_name = H5Tget_member_name(type->native_typeid, m); + if (!member_name || strlen(member_name) > NC_MAX_NAME) + return NC_EBADNAME; + + /* Offset in bytes on *this* platform. */ + member_offset = H5Tget_member_offset(type->native_typeid, m); + + /* Get dimensional data if this member is an array of something. */ + if ((mem_class = H5Tget_class(member_hdf_typeid)) < 0) + return NC_EHDFERR; + if (mem_class == H5T_ARRAY) + { + if ((ndims = H5Tget_array_ndims(member_hdf_typeid)) < 0) + return NC_EHDFERR; + if (H5Tget_array_dims(member_hdf_typeid, dims, NULL) != ndims) + return NC_EHDFERR; + for (d = 0; d < ndims; d++) + dim_size[d] = dims[d]; + /* What is the netCDF typeid of this member? */ + if ((retval = get_netcdf_type(grp->file->nc4_info, H5Tget_super(member_hdf_typeid), + &member_xtype))) + return retval; + } + else + { + /* What is the netCDF typeid of this member? */ + if ((retval = get_netcdf_type(grp->file->nc4_info, member_native_typeid, + &member_xtype))) + return retval; + } + + /* Add this member to our list of fields in this compound type. */ + if (ndims) + { + if ((retval = nc4_field_list_add(&type->field, type->num_fields++, member_name, + member_offset, H5Tget_super(member_hdf_typeid), + H5Tget_super(member_native_typeid), + member_xtype, ndims, dim_size))) + return retval; + } + else + { + if ((retval = nc4_field_list_add(&type->field, type->num_fields++, member_name, + member_offset, member_hdf_typeid, member_native_typeid, + member_xtype, 0, NULL))) + return retval; + } + + /* HDF5 allocated this for us. */ + free(member_name); + } + } + else if (ud_type_type == NC_VLEN) + { + type->base_hdf_typeid = base_hdf_typeid; + } + else if (ud_type_type == NC_ENUM) + { + /* Remember the base HDF5 type for this enum. */ + type->base_hdf_typeid = base_hdf_typeid; + + /* Find out how many member are in the enum. */ + if ((type->num_enum_members = H5Tget_nmembers(hdf_typeid)) < 0) + return NC_EHDFERR; + + /* Allocate space for one value. */ + if (!(value = calloc(1, type_size))) + return NC_ENOMEM; + + /* Read each name and value defined in the enum. */ + for (i = 0; i < type->num_enum_members; i++) + { + /* Get the name and value from HDF5. */ + if (!(member_name = H5Tget_member_name(hdf_typeid, i))) + return NC_EHDFERR; + if (!member_name || strlen(member_name) > NC_MAX_NAME) + return NC_EBADNAME; + if (H5Tget_member_value(hdf_typeid, i, value) < 0) + return NC_EHDFERR; + + /* Insert new field into this type's list of fields. */ + if ((retval = nc4_enum_member_add(&type->enum_member, type->size, + member_name, value))) + return retval; + free(member_name); + } + + /* Free the tempory memory for one value, and the member name + * (which HDF5 allocated for us). */ + free(value); + } + + return retval; +} + +/* This function is called by read_dataset, (which is called by + * nc4_rec_read_metadata) when a netCDF variable is found in the + * file. This function reads in all the metadata about the var, + * including the attributes. */ +static int +read_var(NC_GRP_INFO_T *grp, hid_t datasetid, char *obj_name, + size_t ndims, int is_scale, int num_scales, hid_t access_pid) +{ + NC_VAR_INFO_T *var; + int natts, a, d; + + NC_ATT_INFO_T *att; + hid_t attid = 0; + char att_name[NC_MAX_HDF5_NAME + 1]; + +#define CD_NELEMS_ZLIB 1 +#define CD_NELEMS_SZIP 4 + H5Z_filter_t filter; + int num_filters; + unsigned int cd_values[CD_NELEMS_SZIP]; + size_t cd_nelems = CD_NELEMS_SZIP; + hid_t propid = 0; + H5D_fill_value_t fill_status; + H5D_layout_t layout; + hsize_t chunksize[NC_MAX_VAR_DIMS]; + int retval = NC_NOERR; + double rdcc_w0; + int f; + + assert(obj_name && grp); + LOG((4, "read_var: obj_name %s", obj_name)); + + /* Add a variable to the end of the group's var list. */ + if ((retval = nc4_var_list_add(&grp->var, &var))) + return retval; + + /* Fill in what we already know. */ + var->hdf_datasetid = datasetid; + var->varid = grp->nvars++; + var->created++; + var->ndims = ndims; + + /* We need some room to store information about dimensions for this + * var. */ + if (var->ndims) + { + if (!(var->dim = calloc(var->ndims, sizeof(NC_DIM_INFO_T *)))) + return NC_ENOMEM; + if (!(var->dimids = calloc(var->ndims, sizeof(int)))) + return NC_ENOMEM; + } + + /* Learn about current chunk cache settings. */ + if ((H5Pget_chunk_cache(access_pid, &(var->chunk_cache_nelems), + &(var->chunk_cache_size), &rdcc_w0)) < 0) + return NC_EHDFERR; + var->chunk_cache_preemption = rdcc_w0; + + /* Allocate space for the name. */ + if (!(var->name = malloc((strlen(obj_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + + /* Check for a weird case: a non-coordinate (and non-scalar) + * variable that has the same name as a dimension. It's legal in + * netcdf, and requires that the HDF5 dataset name be changed. */ + if (var->ndims && + !strncmp(obj_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND))) + { + if (strlen(obj_name) > NC_MAX_NAME) + return NC_EMAXNAME; + strcpy(var->name, &obj_name[strlen(NON_COORD_PREPEND)]); + } + else + strcpy(var->name, obj_name); + + /* Find out what filters are applied to this HDF5 dataset, + * fletcher32, deflate, and/or shuffle. All other filters are + * ignored. */ + if ((propid = H5Dget_create_plist(datasetid)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif /* EXTRA_TESTS */ + + /* Get the chunking info for non-scalar vars. */ + if ((layout = H5Pget_layout(propid)) < -1) + BAIL(NC_EHDFERR); + if (layout == H5D_CHUNKED) + { + if (H5Pget_chunk(propid, NC_MAX_VAR_DIMS, chunksize) < 0) + BAIL(NC_EHDFERR); + if (!(var->chunksizes = malloc(var->ndims * sizeof(size_t)))) + BAIL(NC_ENOMEM); + for (d = 0; d < var->ndims; d++) + var->chunksizes[d] = chunksize[d]; + } + else if (layout == H5D_CONTIGUOUS) + var->contiguous++; + + /* The possible values of filter (which is just an int) can be + * found in H5Zpublic.h. */ + if ((num_filters = H5Pget_nfilters(propid)) < 0) + BAIL(NC_EHDFERR); + for (f = 0; f < num_filters; f++) + { + if ((filter = H5Pget_filter2(propid, f, NULL, &cd_nelems, + cd_values, 0, NULL, NULL)) < 0) + BAIL(NC_EHDFERR); + switch (filter) + { + case H5Z_FILTER_SHUFFLE: + var->shuffle = 1; + break; + case H5Z_FILTER_FLETCHER32: + var->fletcher32 = 1; + break; + case H5Z_FILTER_DEFLATE: + var->deflate++; + if (cd_nelems != CD_NELEMS_ZLIB || + cd_values[0] > MAX_DEFLATE_LEVEL) + BAIL(NC_EHDFERR); + var->deflate_level = cd_values[0]; + break; + case H5Z_FILTER_SZIP: + var->deflate++; + if (cd_nelems != CD_NELEMS_SZIP) + BAIL(NC_EHDFERR); + var->options_mask = cd_values[0]; + var->pixels_per_block = cd_values[1]; + break; + default: + LOG((1, "Yikes! Unknown filter type found on dataset!")); + break; + } + } + + /* Learn all about the type of this variable. */ + if ((retval = get_type_info2(grp->file->nc4_info, datasetid, + &var->xtype, &var->type_info))) + BAIL(retval); + + /* Is there a fill value associated with this dataset? */ + if (H5Pfill_value_defined(propid, &fill_status) < 0) + BAIL(NC_EHDFERR); + + /* Get the fill value, if there is one defined. */ + if (fill_status == H5D_FILL_VALUE_USER_DEFINED) + { + /* Allocate space to hold the fill value. */ + if (!var->fill_value) + { + if (var->type_info->class == NC_VLEN) + { + if (!(var->fill_value = malloc(sizeof(nc_vlen_t)))) + BAIL(NC_ENOMEM); + } + else if (var->type_info->size) + { + if (!(var->fill_value = malloc(var->type_info->size))) + BAIL(NC_ENOMEM); + } + else + { + if (!(var->fill_value = malloc(sizeof(char *)))) + BAIL(NC_ENOMEM); + } + } + + /* Get the fill value from the HDF5 property lust. */ + if (H5Pget_fill_value(propid, var->type_info->native_typeid, + var->fill_value) < 0) + BAIL(NC_EHDFERR); + } + else + var->no_fill = 1; + + /* If it's a scale, mark it as such. If not, allocate space to + * remember whether the dimscale has been attached for each + * dimension. */ + if (is_scale) + { + assert(ndims); + var->dimscale++; + if (var->ndims > 1) + { + if ((retval = read_coord_dimids(var))) + BAIL(retval); + } + else + { + var->dimids[0] = grp->dim->dimid; + var->dim[0] = grp->dim; + } + } + else + if (num_scales && ndims && + !(var->dimscale_attached = calloc(ndims, sizeof(int)))) + BAIL(NC_ENOMEM); + + /* If this is not a scale, and has scales, iterate + * through them. (i.e. this is a variable that is not a + * coordinate variable) */ + if (!is_scale && num_scales) + { + /* Store id information allowing us to match hdf5 + * dimscales to netcdf dimensions. */ + if (!(var->dimscale_hdf5_objids = malloc(ndims * sizeof(struct hdf5_objid)))) + BAIL(NC_ENOMEM); + for (d = 0; d < var->ndims; d++) + { + LOG((5, "read_var: about to iterate over scales for dim %d", d)); + if (H5DSiterate_scales(var->hdf_datasetid, d, NULL, dimscale_visitor, + &(var->dimscale_hdf5_objids[d])) < 0) + BAIL(NC_EHDFERR); +/* LOG((5, "read_var: collected scale info for dim %d " + "var %s fileno[0] %d objno[0] %d fileno[1] %d objno[1] %d", + d, var->name, var->dimscale_hdf5_objids[d].fileno[0], + var->dimscale_hdf5_objids[d].objno[0], + var->dimscale_hdf5_objids[d].fileno[1], + var->dimscale_hdf5_objids[d].objno[1]));*/ + var->dimscale_attached[d]++; + } + } + + /* Now read all the attributes of this variable, ignoring the + ones that hold HDF5 dimension scale information. */ + if ((natts = H5Aget_num_attrs(var->hdf_datasetid)) < 0) + BAIL(NC_EATTMETA); + for (a = 0; a < natts; a++) + { + /* Close the attribute and try to move on with our + * lives. Like bits through the network port, so + * flows the Days of Our Lives! */ + if (attid && H5Aclose(attid) < 0) + BAIL(NC_EHDFERR); + + /* Open the att and get its name. */ + if ((attid = H5Aopen_idx(var->hdf_datasetid, (unsigned int)a)) < 0) + BAIL(NC_EATTMETA); + if (H5Aget_name(attid, NC_MAX_HDF5_NAME, att_name) < 0) + BAIL(NC_EATTMETA); + LOG((4, "read_var: a %d att_name %s", a, att_name)); + + /* Should we ignore this attribute? */ + if (strcmp(att_name, REFERENCE_LIST) && + strcmp(att_name, CLASS) && + strcmp(att_name, DIMENSION_LIST) && + strcmp(att_name, NAME) && + strcmp(att_name, COORDINATES)) + { + /* Is this the hidden attribute that holds the netCDF + * dimension id for a coordinate variable? */ + if (!strcmp(att_name, NC_DIMID_ATT_NAME)) + { + + } + else + { + /* Add to the end of the list of atts for this var. */ + if ((retval = nc4_att_list_add(&var->att))) + BAIL(retval); + for (att = var->att; att->next; att = att->next) + ; + + /* Fill in the information we know. */ + att->attnum = var->natts++; + if (!(att->name = malloc((strlen(att_name) + 1) * sizeof(char)))) + BAIL(NC_ENOMEM); + strcpy(att->name, att_name); + + /* Read the rest of the info about the att, + * including its values. */ + if ((retval = read_hdf5_att(grp, attid, att))) + BAIL(retval); + + att->created++; + } /* endif not HDF5 att */ + } + } /* next attribute */ + + /* Is this a deflated variable with a chunksize greater than the + * current cache size? */ + if ((retval = nc4_adjust_var_cache(grp, var))) + BAIL(retval); + + exit: + if (propid > 0 && H5Pclose(propid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; +#endif + if (attid > 0 && H5Aclose(attid) < 0) + BAIL2(NC_EHDFERR); + return retval; +} + +/* This function is called by nc4_rec_read_metadata to read all the + * group level attributes (the NC_GLOBAL atts for this group). */ +static int +read_grp_atts(NC_GRP_INFO_T *grp) +{ + hid_t attid = 0; + hsize_t num_obj, i; + NC_ATT_INFO_T *att; + NC_TYPE_INFO_T *type; + char obj_name[NC_MAX_HDF5_NAME + 1]; + int max_len; + int retval = NC_NOERR; + + num_obj = H5Aget_num_attrs(grp->hdf_grpid); + for (i = 0; i < num_obj; i++) + { + if (attid > 0) + H5Aclose(attid); + if ((attid = H5Aopen_idx(grp->hdf_grpid, (unsigned int)i)) < 0) + BAIL(NC_EATTMETA); + if (H5Aget_name(attid, NC_MAX_NAME + 1, obj_name) < 0) + BAIL(NC_EATTMETA); + LOG((3, "reading attribute of _netCDF group, named %s", obj_name)); + + /* This may be an attribute telling us that strict netcdf-3 + * rules are in effect. If so, we will make note of the fact, + * but not add this attribute to the metadata. It's not a user + * attribute, but an internal netcdf-4 one. */ + if (!strcmp(obj_name, NC3_STRICT_ATT_NAME)) + grp->file->nc4_info->cmode |= NC_CLASSIC_MODEL; + else + { + /* Add an att struct at the end of the list, and then go to it. */ + if ((retval = nc4_att_list_add(&grp->att))) + BAIL(retval); + for (att = grp->att; att->next; att = att->next) + ; + + /* Add the info about this attribute. */ + max_len = strlen(obj_name) > NC_MAX_NAME ? NC_MAX_NAME : strlen(obj_name); + if (!(att->name = malloc((max_len + 1) * sizeof(char)))) + BAIL(NC_ENOMEM); + strncpy(att->name, obj_name, max_len); + att->name[max_len] = 0; + att->attnum = grp->natts++; + if ((retval = read_hdf5_att(grp, attid, att))) + BAIL(retval); + att->created++; + if ((retval = nc4_find_type(grp->file->nc4_info, att->xtype, &type))) + BAIL(retval); + if (type) + att->class = type->class; + } + } + + exit: + if (attid > 0 && H5Aclose(attid) < 0) + BAIL2(NC_EHDFERR); + return retval; +} + +/* This function is called when nc4_rec_read_vars encounters an HDF5 + * dataset when reading a file. */ +static int +read_dataset(NC_GRP_INFO_T *grp, char *obj_name) +{ + hid_t datasetid = 0; + hid_t spaceid = 0, access_pid = 0; + int ndims; + hsize_t dims[NC_MAX_DIMS], max_dims[NC_MAX_DIMS]; + int is_scale = 0; + int dim_without_var = 0; + int num_scales = 0; + int retval = NC_NOERR; + + /* Open this dataset. */ + if ((datasetid = H5Dopen2(grp->hdf_grpid, obj_name, H5P_DEFAULT)) < 0) + BAIL(NC_EVARMETA); + + /* Get the current chunk cache settings. */ + if ((access_pid = H5Dget_access_plist(datasetid)) < 0) + BAIL(NC_EVARMETA); +#ifdef EXTRA_TESTS + num_plists++; +#endif + + /* Get the dimension information for this dataset. */ + if ((spaceid = H5Dget_space(datasetid)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) + BAIL(NC_EHDFERR); + if (ndims > NC_MAX_DIMS) + BAIL(NC_EMAXDIMS); + if (H5Sget_simple_extent_dims(spaceid, dims, max_dims) < 0) + BAIL(NC_EHDFERR); + + /* Is this a dimscale? */ + if ((is_scale = H5DSis_scale(datasetid)) < 0) + BAIL(NC_EHDFERR); + if (is_scale) + { + /* Read the scale information. */ + if ((retval = read_scale(grp, datasetid, obj_name, dims[0], + max_dims[0], &dim_without_var))) + BAIL(retval); + } + else + { + /* Find out how many scales are attached to this + * dataset. H5DSget_num_scales returns an error if there are no + * scales, so convert a negative return value to zero. */ + num_scales = H5DSget_num_scales(datasetid, 0); + if (num_scales < 0) + num_scales = 0; + } + + /* Add a var to the linked list, and get its metadata, + * unless this is one of those funny dimscales that are a + * dimension in netCDF but not a variable. (Spooky!) */ + if (!dim_without_var) + if ((retval = read_var(grp, datasetid, obj_name, ndims, + is_scale, num_scales, access_pid))) + BAIL(retval); + + if (access_pid && H5Pclose(access_pid) < 0) + BAIL2(retval); +#ifdef EXTRA_TESTS + num_plists--; +#endif + if (spaceid && H5Sclose(spaceid) < 0) + BAIL2(retval); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + return NC_NOERR; + + exit: + if (access_pid && H5Pclose(access_pid) < 0) + BAIL2(retval); +#ifdef EXTRA_TESTS + num_plists--; +#endif + if (datasetid && H5Dclose(datasetid) < 0) + BAIL2(retval); + if (spaceid && H5Sclose(spaceid) <0) + BAIL2(retval); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + return retval; +} + +/* Given index, get the HDF5 name of an object and the class of the + * object (group, type, dataset, etc.). This function will try to use + * creation ordering, but if that fails it will use default + * (i.e. alphabetical) ordering. (This is necessary to read existing + * HDF5 archives without creation ordering). */ +/* static int */ +/* get_name_by_idx(NC_HDF5_FILE_INFO_T *h5, hid_t hdf_grpid, int i, */ +/* int *obj_class, char *obj_name) */ +/* { */ +/* H5O_info_t obj_info; */ +/* H5_index_t idx_field = H5_INDEX_CRT_ORDER; */ +/* ssize_t size; */ +/* herr_t res; */ + +/* /\* These HDF5 macros prevent an HDF5 error message when a */ +/* * non-creation-ordered HDF5 file is opened. *\/ */ +/* H5E_BEGIN_TRY { */ +/* res = H5Oget_info_by_idx(hdf_grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, */ +/* i, &obj_info, H5P_DEFAULT); */ +/* } H5E_END_TRY; */ + +/* /\* Creation ordering not available, so make sure this file is */ +/* * opened for read-only access. This is a plain old HDF5 file being */ +/* * read by netCDF-4. *\/ */ +/* if (res < 0) */ +/* { */ +/* if (H5Oget_info_by_idx(hdf_grpid, ".", H5_INDEX_NAME, H5_ITER_INC, */ +/* i, &obj_info, H5P_DEFAULT) < 0) */ +/* return NC_EHDFERR; */ +/* if (!h5->no_write) */ +/* return NC_ECANTWRITE; */ +/* h5->ignore_creationorder = 1; */ +/* idx_field = H5_INDEX_NAME; */ +/* } */ + +/* *obj_class = obj_info.type; */ +/* if ((size = H5Lget_name_by_idx(hdf_grpid, ".", idx_field, H5_ITER_INC, i, */ +/* NULL, 0, H5P_DEFAULT)) < 0) */ +/* return NC_EHDFERR; */ +/* if (size > NC_MAX_NAME) */ +/* return NC_EMAXNAME; */ +/* if (H5Lget_name_by_idx(hdf_grpid, ".", idx_field, H5_ITER_INC, i, */ +/* obj_name, size+1, H5P_DEFAULT) < 0) */ +/* return NC_EHDFERR; */ + +/* LOG((4, "get_name_by_idx: encountered HDF5 object obj_name %s", obj_name)); */ + +/* return NC_NOERR; */ +/* } */ + +#define USE_ITERATE_CODE +#ifdef USE_ITERATE_CODE + +static int +nc4_rec_read_types_cb(hid_t grpid, const char *name, const H5L_info_t *info, + void *_op_data) +{ + hid_t oid=-1; + H5I_type_t otype=-1; + char oname[NC_MAX_NAME + 1]; + NC_GRP_INFO_T *child_grp; + NC_GRP_INFO_T *grp = (NC_GRP_INFO_T *) (_op_data); + NC_HDF5_FILE_INFO_T *h5 = grp->file->nc4_info; + + /* Open this critter. */ + if ((oid = H5Oopen(grpid, name, H5P_DEFAULT)) < 0) + return H5_ITER_ERROR; + + if ((otype = H5Iget_type( oid ))<0) { + H5Oclose(oid); + return H5_ITER_ERROR; + } + H5Oclose(oid); + + strncpy(oname, name, NC_MAX_NAME); + + /* Deal with groups and types; ignore the rest. */ + if (otype == H5I_GROUP) + { + LOG((3, "found group %s", oname)); + if (nc4_grp_list_add(&(grp->children), h5->next_nc_grpid++, + grp, grp->file, oname, &child_grp)) + return H5_ITER_ERROR; + + if (nc4_rec_read_types(child_grp)) + return H5_ITER_ERROR; + } + else if (otype == H5I_DATATYPE) + { + LOG((3, "found datatype %s", oname)); + if (read_type(grp, oname)) + return H5_ITER_ERROR; + } + + return (H5_ITER_CONT); +} + +static int +nc4_rec_read_types(NC_GRP_INFO_T *grp) +{ + hsize_t idx=0; + int res = 0; + hid_t pid = 0; + unsigned crt_order_flags = 0; + NC_HDF5_FILE_INFO_T *h5 = grp->file->nc4_info; + + assert(grp && grp->name); + LOG((3, "nc4_rec_read_types: grp->name %s", grp->name)); + + /* Open this HDF5 group and retain its grpid. It will remain open + * with HDF5 until this file is nc_closed. */ + if (!grp->hdf_grpid) + { + if (grp->parent) + { + if ((grp->hdf_grpid = H5Gopen2(grp->parent->hdf_grpid, + grp->name, H5P_DEFAULT)) < 0) + return NC_EHDFERR; + } + else + { + if ((grp->hdf_grpid = H5Gopen2(grp->file->nc4_info->hdfid, + "/", H5P_DEFAULT)) < 0) + return NC_EHDFERR; + } + } + assert(grp->hdf_grpid > 0); + + pid = H5Gget_create_plist(grp->hdf_grpid); + H5Pget_link_creation_order(pid, &crt_order_flags); + H5Pclose(pid); + + crt_order_flags = crt_order_flags & H5_INDEX_CRT_ORDER; + + if (crt_order_flags == H5_INDEX_CRT_ORDER) + { + res = H5Literate(grp->hdf_grpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, + &idx, nc4_rec_read_types_cb, (void *)grp); + } else + { + /* Without creation ordering, file must be read-only. */ + if (!idx && !h5->no_write) + return NC_ECANTWRITE; + + res = H5Literate(grp->hdf_grpid, H5_INDEX_NAME, H5_ITER_INC, + &idx, nc4_rec_read_types_cb, (void *)grp); + } + if (res<0) + return NC_EHDFERR; + return NC_NOERR; /* everything worked! */ +} + +static int +nc4_rec_read_vars_cb(hid_t grpid, const char *name, const H5L_info_t *info, + void *_op_data) +{ + hid_t oid=-1; + H5I_type_t otype=-1; + char oname[NC_MAX_NAME + 1]; + NC_GRP_INFO_T *child_grp; + NC_GRP_INFO_T *grp = (NC_GRP_INFO_T *) (_op_data); +#if 0 + NC_HDF5_FILE_INFO_T *h5 = grp->file->nc4_info; +#endif + + memset(oname, 0, NC_MAX_NAME); + /* Open this critter. */ + if ((oid = H5Oopen(grpid, name, H5P_DEFAULT)) < 0) + return H5_ITER_ERROR; + + if ((otype = H5Iget_type( oid ))<0) { + H5Oclose(oid); + return H5_ITER_ERROR; + } + H5Oclose(oid); + + strncpy(oname, name, NC_MAX_NAME); + + /* Deal with datasets. */ + switch(otype) + { + case H5I_GROUP: + LOG((3, "re-encountering group %s", oname)); + + /* The NC_GROUP_INFO_T for this group already exists. Find it. */ + for (child_grp = grp->children; child_grp; child_grp = child_grp->next) + if (!strcmp(child_grp->name, oname)) + break; + if (!child_grp) + return H5_ITER_ERROR; + + /* Recursively read the child group's vars. */ + if (nc4_rec_read_vars(child_grp)) + return H5_ITER_ERROR; + break; + case H5I_DATASET: + LOG((3, "found dataset %s", oname)); + + /* Learn all about this dataset, which may be a dimscale + * (i.e. dimension metadata), or real data. */ + if (read_dataset(grp, oname)) + return H5_ITER_ERROR; + break; + case H5I_DATATYPE: + LOG((3, "already handled type %s", oname)); + break; + default: + LOG((0, "Unknown object class %d in nc4_rec_read_vars!", otype)); + } + return (H5_ITER_CONT); +} + +static int +nc4_rec_read_vars(NC_GRP_INFO_T *grp) +{ + hsize_t idx = 0; + int retval = NC_NOERR; + int res = 0; + hid_t pid = 0; + unsigned crt_order_flags = 0; + NC_HDF5_FILE_INFO_T *h5 = grp->file->nc4_info; + + assert(grp && grp->name && grp->hdf_grpid > 0); + LOG((3, "nc4_rec_read_vars: grp->name %s", grp->name)); + + pid = H5Gget_create_plist(grp->hdf_grpid); + H5Pget_link_creation_order(pid, &crt_order_flags); + H5Pclose(pid); + + crt_order_flags = crt_order_flags & H5_INDEX_CRT_ORDER; + + if (crt_order_flags == H5_INDEX_CRT_ORDER) + { + res = H5Literate(grp->hdf_grpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, + &idx, nc4_rec_read_vars_cb, (void *)grp); + } else + { + /* Without creation ordering, file must be read-only. */ + if (!idx && !h5->no_write) + return NC_ECANTWRITE; + + res = H5Literate(grp->hdf_grpid, H5_INDEX_NAME, H5_ITER_INC, + &idx, nc4_rec_read_vars_cb, (void *)grp); + } + if (res<0) + return NC_EHDFERR; + + /* Scan the group for global (i.e. group-level) attributes. */ + if ((retval = read_grp_atts(grp))) + return retval; + + return NC_NOERR; /* everything worked! */ +} + +#else + +/** \internal +This struct is used to pass information back from the callback +function used with H5Literate. +*/ +struct nc_hdf5_link_info +{ + char name[NC_MAX_NAME + 1]; + H5I_type_t obj_type; +}; + +/* This is a callback function for H5Literate(). + +The parameters of this callback function have the following values or +meanings: + +g_id Group that serves as root of the iteration; same value as the +H5Lvisit group_id parameter + +name Name of link, relative to g_id, being examined at current step of +the iteration + +info H5L_info_t struct containing information regarding that link + +op_data User-defined pointer to data required by the application in +processing the link; a pass-through of the op_data pointer provided +with the H5Lvisit function call + +*/ +static herr_t +visit_link(hid_t g_id, const char *name, const H5L_info_t *info, + void *op_data) +{ + /* A positive return value causes the visit iterator to immediately + * return that positive value, indicating short-circuit + * success. The iterator can be restarted at the next group + * member. */ + int ret = 1; + hid_t id; + + /* Get the name, truncating at NC_MAX_NAME. */ + strncpy(((struct nc_hdf5_link_info *)op_data)->name, name, + NC_MAX_NAME); + + /* Open this critter. */ + if ((id = H5Oopen_by_addr(g_id, info->u.address)) < 0) + return NC_EHDFERR; + + /* Is this critter a group, type, data, attribute, or what? */ + if ((((struct nc_hdf5_link_info *)op_data)->obj_type = H5Iget_type(id)) < 0) + ret = NC_EHDFERR; + + /* Close the critter to release resouces. */ + if (H5Oclose(id) < 0) + return NC_EHDFERR; + + return ret; +} + +/* Iterate over one link in the group at a time, returning + * link_info. The creation_ordering and idx pointers keep track of + * whether creation ordering works and the most recently examined + * link. */ +static int +nc4_iterate_link(int *ordering_checked, int *creation_ordering, + hid_t grpid, hsize_t *idx, struct nc_hdf5_link_info *link_info) +{ + int res = 0; + + if (*creation_ordering) + { + /* These HDF5 macros prevent an HDF5 error message when a + * non-creation-ordered HDF5 file is opened. */ + H5E_BEGIN_TRY { + res = H5Literate(grpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, + idx, visit_link, (void *)link_info); + if (res < 0 && *ordering_checked) + return NC_EHDFERR; + } H5E_END_TRY; + } + + if (!*creation_ordering || res < 0) + { + if (H5Literate(grpid, H5_INDEX_NAME, H5_ITER_INC, idx, + visit_link, link_info) != 1) + return NC_EHDFERR; + /* If it didn't work with creation ordering, but did without, + * then we don't have creation ordering. */ + *creation_ordering = 0; + } + + *ordering_checked = 1; + return NC_NOERR; +} + +/* Recursively open groups and read types. */ +int +nc4_rec_read_types(NC_GRP_INFO_T *grp) +{ + hsize_t num_obj, i; + NC_HDF5_FILE_INFO_T *h5 = grp->file->nc4_info; + NC_GRP_INFO_T *child_grp; + hsize_t idx = 0; + struct nc_hdf5_link_info link_info; + int ordering_checked = 0; + int creation_ordering = 1; /* Assume we have it. */ + int retval = NC_NOERR; + + assert(grp && grp->name); + LOG((3, "nc4_rec_read_types: grp->name %s", grp->name)); + + /* Open this HDF5 group and retain its grpid. It will remain open + * with HDF5 until this file is nc_closed. */ + if (!grp->hdf_grpid) + { + if (grp->parent) + { + if ((grp->hdf_grpid = H5Gopen2(grp->parent->hdf_grpid, + grp->name, H5P_DEFAULT)) < 0) + return NC_EHDFERR; + } + else + { + if ((grp->hdf_grpid = H5Gopen2(grp->file->nc4_info->hdfid, + "/", H5P_DEFAULT)) < 0) + return NC_EHDFERR; + } + } + assert(grp->hdf_grpid > 0); + + /* How many objects in this group? */ + if (H5Gget_num_objs(grp->hdf_grpid, &num_obj) < 0) + return NC_EVARMETA; + + /* For each object in the group... */ + for (i = 0; i < num_obj; i++) + { + if ((retval = nc4_iterate_link(&ordering_checked, &creation_ordering, + grp->hdf_grpid, &idx, &link_info))) + return retval; + + /* Without creation ordering, file must be read-only. */ + if (!i && !creation_ordering && !h5->no_write) + return NC_ECANTWRITE; + + /* Deal with groups and types; ignore the rest. */ + if (link_info.obj_type == H5I_GROUP) + { + LOG((3, "found group %s", link_info.name)); + if ((retval = nc4_grp_list_add(&(grp->children), h5->next_nc_grpid++, + grp, grp->file, link_info.name, &child_grp))) + return retval; + if ((retval = nc4_rec_read_types(child_grp))) + return retval; + } + else if (link_info.obj_type == H5I_DATATYPE) + { + LOG((3, "found datatype %s", link_info.name)); + if ((retval = read_type(grp, link_info.name))) + return retval; + } + } + + return NC_NOERR; /* everything worked! */ +} + +/* This function recursively reads all the var and attribute metadata + in a HDF5 group, and creates and fills in the netCDF-4 global + metadata structure. */ +int +nc4_rec_read_vars(NC_GRP_INFO_T *grp) +{ + hsize_t num_obj, i; + NC_GRP_INFO_T *child_grp; + struct nc_hdf5_link_info link_info; + hsize_t idx = 0; + int ordering_checked = 0; + int creation_ordering = 1; /* Assume we have it. */ + int retval = NC_NOERR; + + assert(grp && grp->name && grp->hdf_grpid > 0); + LOG((3, "nc4_rec_read_vars: grp->name %s", grp->name)); + + /* How many objects in this group? */ + if (H5Gget_num_objs(grp->hdf_grpid, &num_obj) < 0) + return NC_EVARMETA; + + /* For each object in the group... */ + for (i = 0; i < num_obj; i++) + { + if ((retval = nc4_iterate_link(&ordering_checked, &creation_ordering, + grp->hdf_grpid, &idx, &link_info))) + return retval; + + /* Deal with datasets. */ + switch(link_info.obj_type) + { + case H5I_GROUP: + LOG((3, "re-encountering group %s", link_info.name)); + + /* The NC_GROUP_INFO_T for this group already exists. Find it. */ + for (child_grp = grp->children; child_grp; child_grp = child_grp->next) + if (!strcmp(child_grp->name, link_info.name)) + break; + if (!child_grp) + return NC_EHDFERR; + + /* Recursively read the child group's vars. */ + if ((retval = nc4_rec_read_vars(child_grp))) + return retval; + break; + case H5I_DATASET: + LOG((3, "found dataset %s", link_info.name)); + + /* Learn all about this dataset, which may be a dimscale + * (i.e. dimension metadata), or real data. */ + if ((retval = read_dataset(grp, link_info.name))) + return retval; + break; + case H5I_DATATYPE: + LOG((3, "already handled type %s", link_info.name)); + break; + default: + LOG((0, "Unknown object class %d in nc4_rec_read_vars!", + link_info.obj_type)); + } + } + + /* Scan the group for global (i.e. group-level) attributes. */ + if ((retval = read_grp_atts(grp))) + return retval; + + return NC_NOERR; /* everything worked! */ +} +#endif + +/* Open a netcdf-4 file. Things have already been kicked off in + * ncfunc.c in nc_open, but here the netCDF-4 part of opening a file + * is handled. */ +static int +nc4_open_file(const char *path, int mode, MPI_Comm comm, + MPI_Info info, NC_FILE_INFO_T *nc) +{ + hid_t fapl_id = H5P_DEFAULT; + unsigned flags = (mode & NC_WRITE) ? + H5F_ACC_RDWR : H5F_ACC_RDONLY; + int retval; + + LOG((3, "nc4_open_file: path %s mode %d", path, mode)); + assert(path && nc); + + /* Stop diskless open in its tracks */ + if(mode & NC_DISKLESS) + return NC_EDISKLESS; + + /* Add necessary structs to hold netcdf-4 file data. */ + if ((retval = nc4_nc4f_list_add(nc, path, mode))) + BAIL(retval); + assert(nc->nc4_info && nc->nc4_info->root_grp); + + /* Need this access plist to control how HDF5 handles open onjects + * on file close. (Setting H5F_CLOSE_SEMI will cause H5Fclose to + * fail if there are any open objects in the file. */ + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif +#ifdef EXTRA_TESTS + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI)) + BAIL(NC_EHDFERR); +#else + if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) + BAIL(NC_EHDFERR); +#endif + +#ifdef USE_PARALLEL + /* If this is a parallel file create, set up the file creation + property list. */ + if (mode & NC_MPIIO || mode & NC_MPIPOSIX) + { + nc->nc4_info->parallel++; + if (mode & NC_MPIIO) /* MPI/IO */ + { + LOG((4, "opening parallel file with MPI/IO")); + if (H5Pset_fapl_mpio(fapl_id, comm, info) < 0) + BAIL(NC_EPARINIT); + } + else /* MPI/POSIX */ + { + LOG((4, "opening parallel file with MPI/posix")); + if (H5Pset_fapl_mpiposix(fapl_id, comm, 0) < 0) + BAIL(NC_EPARINIT); + } + } +#else /* only set cache for non-parallel. */ + if (H5Pset_cache(fapl_id, 0, nc4_chunk_cache_nelems, nc4_chunk_cache_size, + nc4_chunk_cache_preemption) < 0) + BAIL(NC_EHDFERR); + LOG((4, "nc4_open_file: set HDF raw chunk cache to size %d nelems %d preemption %f", + nc4_chunk_cache_size, nc4_chunk_cache_nelems, nc4_chunk_cache_preemption)); +#endif /* USE_PARALLEL */ + + /* The NetCDF-3.x prototype contains an mode option NC_SHARE for + multiple processes accessing the dataset concurrently. As there + is no HDF5 equivalent, NC_SHARE is treated as NC_NOWRITE. */ + if ((nc->nc4_info->hdfid = H5Fopen(path, flags, fapl_id)) < 0) + BAIL(NC_EHDFERR); + + /* Does the mode specify that this file is read-only? */ + if ((mode & NC_WRITE) == 0) + nc->nc4_info->no_write++; + + /* Now read in all the metadata. Some types and dimscale + * information may be difficult to resolve here, if, for example, a + * dataset of user-defined type is encountered before the + * definition of that type. */ + if ((retval = nc4_rec_read_types(nc->nc4_info->root_grp))) + BAIL(retval); + if ((retval = nc4_rec_read_vars(nc->nc4_info->root_grp))) + BAIL(retval); + + /* Now figure out which netCDF dims are indicated by the dimscale + * information. */ + if ((retval = nc4_rec_match_dimscales(nc->nc4_info->root_grp))) + BAIL(retval); + +#ifdef LOGGING + /* This will print out the names, types, lens, etc of the vars and + atts in the file, if the logging level is 2 or greater. */ + log_metadata_nc(nc); +#endif + + /* Close the property list. */ + if (H5Pclose(fapl_id) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; +#endif + + return NC_NOERR; + + exit: + if (fapl_id != H5P_DEFAULT) H5Pclose(fapl_id); +#ifdef EXTRA_TESTS + num_plists--; +#endif + if (nc->nc4_info->hdfid > 0) H5Fclose(nc->nc4_info->hdfid); + if (nc->nc4_info) free(nc->nc4_info); + return retval; +} + +/* Given an HDF4 type, set a pointer to netcdf type. */ +#ifdef USE_HDF4 +static int +get_netcdf_type_from_hdf4(NC_HDF5_FILE_INFO_T *h5, int32 hdf4_typeid, + nc_type *xtype, NC_TYPE_INFO_T *type_info) +{ + int t; + assert(h5 && xtype); + + switch(hdf4_typeid) + { + case DFNT_CHAR: + *xtype = NC_CHAR; + t = 0; + break; + case DFNT_UCHAR: + case DFNT_UINT8: + *xtype = NC_UBYTE; + t = 6; + break; + case DFNT_INT8: + *xtype = NC_BYTE; + t = 1; + break; + case DFNT_INT16: + *xtype = NC_SHORT; + t = 2; + break; + case DFNT_UINT16: + *xtype = NC_USHORT; + t = 7; + break; + case DFNT_INT32: + *xtype = NC_INT; + t = 3; + break; + case DFNT_UINT32: + *xtype = NC_UINT; + t = 8; + break; + case DFNT_FLOAT32: + *xtype = NC_FLOAT; + t = 4; + break; + case DFNT_FLOAT64: + *xtype = NC_DOUBLE; + t = 5; + break; + default: + *xtype = NC_NAT; + return NC_EBADTYPID; + } + + if (type_info) + { + if (hdf4_typeid == DFNT_FLOAT32 || hdf4_typeid == DFNT_FLOAT64) + type_info->class = H5T_FLOAT; + else if (hdf4_typeid == DFNT_CHAR) + type_info->class = H5T_STRING; + else + type_info->class = H5T_INTEGER; + type_info->endianness = NC_ENDIAN_BIG; + type_info->nc_typeid = *xtype; + if (type_info->name) + free(type_info->name); + if (!(type_info->name = malloc((strlen(nc_type_name[t]) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(type_info->name, nc_type_name[t]); + } + + return NC_NOERR; +} +#endif /* USE_HDF4 */ + +/* Open a HDF4 file. Things have already been kicked off in nc_open, + * but here the netCDF-4 part of opening a file is handled. */ +static int +nc4_open_hdf4_file(const char *path, int mode, NC_FILE_INFO_T *nc) +{ +#ifdef USE_HDF4 + NC_HDF5_FILE_INFO_T *h5; + NC_GRP_INFO_T *grp; + NC_ATT_INFO_T *att; + NC_VAR_INFO_T *var; + int32 num_datasets, num_gatts; + int32 rank; + int v, d, a; + int retval; + + LOG((3, "nc4_open_hdf4_file: path %s mode %d", path, mode)); + assert(path && nc); + + /* Must be read-only access to hdf4 files. */ + if (mode & NC_WRITE) + return NC_EINVAL; + + /* Add necessary structs to hold netcdf-4 file data. */ + if ((retval = nc4_nc4f_list_add(nc, path, mode))) + return retval; + assert(nc->nc4_info && nc->nc4_info->root_grp); + h5 = nc->nc4_info; + h5->hdf4++; + grp = h5->root_grp; + h5->no_write++; + + /* Open the file and initialize SD interface. */ + if ((h5->sdid = SDstart(path, DFACC_READ)) == FAIL) + return NC_EHDFERR; + + /* Learn how many datasets and global atts we have. */ + if (SDfileinfo(h5->sdid, &num_datasets, &num_gatts)) + return NC_EHDFERR; + + /* Read the atts. */ + for (a = 0; a < num_gatts; a++) + { + int32 att_data_type, att_count; + size_t att_type_size; + + /* Add to the end of the list of atts for this var. */ + if ((retval = nc4_att_list_add(&h5->root_grp->att))) + return retval; + for (att = h5->root_grp->att; att->next; att = att->next) + ; + att->attnum = grp->natts++; + att->created++; + + /* Learn about this attribute. */ + if (!(att->name = malloc(NC_MAX_HDF4_NAME * sizeof(char)))) + return NC_ENOMEM; + if (SDattrinfo(h5->sdid, a, att->name, &att_data_type, &att_count)) + return NC_EATTMETA; + if ((retval = get_netcdf_type_from_hdf4(h5, att_data_type, + &att->xtype, NULL))) + return retval; + att->len = att_count; + + /* Allocate memory to hold the data. */ + if ((retval = nc4_get_typelen_mem(h5, att->xtype, 0, &att_type_size))) + return retval; + if (!(att->data = malloc(att_type_size * att->len))) + return NC_ENOMEM; + + /* Read the data. */ + if (SDreadattr(h5->sdid, a, att->data)) + return NC_EHDFERR; + } + + /* Read each dataset. */ + for (v = 0; v < num_datasets; v++) + { + int32 data_type, num_atts; + int32 dimsize[NC_MAX_DIMS]; + size_t var_type_size; + int a; + + /* Add a variable to the end of the group's var list. */ + if ((retval = nc4_var_list_add(&grp->var, &var))) + return retval; + var->varid = grp->nvars++; + var->created = 1; + var->written_to = 1; + + /* Open this dataset in HDF4 file. */ + if ((var->sdsid = SDselect(h5->sdid, v)) == FAIL) + return NC_EVARMETA; + + /* Get shape, name, type, and attribute info about this dataset. */ + if (!(var->name = malloc(NC_MAX_HDF4_NAME + 1))) + return NC_ENOMEM; + if (SDgetinfo(var->sdsid, var->name, &rank, dimsize, &data_type, &num_atts)) + return NC_EVARMETA; + var->ndims = rank; + var->hdf4_data_type = data_type; + + /* Fill special type_info struct for variable type information. */ + if (!(var->type_info = calloc(1, sizeof(NC_TYPE_INFO_T)))) + return NC_ENOMEM; + if ((retval = get_netcdf_type_from_hdf4(h5, data_type, &var->xtype, var->type_info))) + return retval; + if ((retval = nc4_get_typelen_mem(h5, var->xtype, 0, &var_type_size))) + return retval; + var->type_info->size = var_type_size; + LOG((3, "reading HDF4 dataset %s, rank %d netCDF type %d", var->name, + rank, var->xtype)); + + /* Get the fill value. */ + if (!(var->fill_value = malloc(var_type_size))) + return NC_ENOMEM; + if (SDgetfillvalue(var->sdsid, var->fill_value)) + { + /* Whoops! No fill value! */ + free(var->fill_value); + var->fill_value = NULL; + } + + /* Allocate storage for dimension info in this variable. */ + if (var->ndims) + { + if (!(var->dim = malloc(sizeof(NC_DIM_INFO_T *) * var->ndims))) + return NC_ENOMEM; + if (!(var->dimids = malloc(sizeof(int) * var->ndims))) + return NC_ENOMEM; + } + + /* Find its dimensions. */ + for (d = 0; d < var->ndims; d++) + { + int32 dimid, dim_len, dim_data_type, dim_num_attrs; + char dim_name[NC_MAX_NAME + 1]; + NC_DIM_INFO_T *dim; + + if ((dimid = SDgetdimid(var->sdsid, d)) == FAIL) + return NC_EDIMMETA; + if (SDdiminfo(dimid, dim_name, &dim_len, &dim_data_type, + &dim_num_attrs)) + return NC_EDIMMETA; + + /* Do we already have this dimension? HDF4 explicitly uses + * the name to tell. */ + for (dim = grp->dim; dim; dim = dim->next) + if (!strcmp(dim->name, dim_name)) + break; + + /* If we didn't find this dimension, add one. */ + if (!dim) + { + LOG((4, "adding dimension %s for HDF4 dataset %s", + dim_name, var->name)); + if ((retval = nc4_dim_list_add(&grp->dim))) + return retval; + grp->ndims++; + dim = grp->dim; + dim->dimid = grp->file->nc4_info->next_dimid++; + if (strlen(dim_name) > NC_MAX_HDF4_NAME) + return NC_EMAXNAME; + if (!(dim->name = malloc(NC_MAX_HDF4_NAME + 1))) + return NC_ENOMEM; + strcpy(dim->name, dim_name); + if (dim_len) + dim->len = dim_len; + else + dim->len = *dimsize; + } + + /* Tell the variable the id of this dimension. */ + var->dimids[d] = dim->dimid; + } + + /* Read the atts. */ + for (a = 0; a < num_atts; a++) + { + int32 att_data_type, att_count; + size_t att_type_size; + + /* Add to the end of the list of atts for this var. */ + if ((retval = nc4_att_list_add(&var->att))) + return retval; + for (att = var->att; att->next; att = att->next) + ; + att->attnum = var->natts++; + att->created++; + + /* Learn about this attribute. */ + if (!(att->name = malloc(NC_MAX_HDF4_NAME * sizeof(char)))) + return NC_ENOMEM; + if (SDattrinfo(var->sdsid, a, att->name, &att_data_type, &att_count)) + return NC_EATTMETA; + if ((retval = get_netcdf_type_from_hdf4(h5, att_data_type, + &att->xtype, NULL))) + return retval; + att->len = att_count; + + /* Allocate memory to hold the data. */ + if ((retval = nc4_get_typelen_mem(h5, att->xtype, 0, &att_type_size))) + return retval; + if (!(att->data = malloc(att_type_size * att->len))) + return NC_ENOMEM; + + /* Read the data. */ + if (SDreadattr(var->sdsid, a, att->data)) + return NC_EHDFERR; + } + } /* next var */ + +#ifdef LOGGING + /* This will print out the names, types, lens, etc of the vars and + atts in the file, if the logging level is 2 or greater. */ + log_metadata_nc(h5->root_grp->file); +#endif + return NC_NOERR; +#endif /* USE_HDF4 */ + return NC_ENOTBUILT; +} + +int +NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, + int use_parallel, void *mpidata, NC_Dispatch *dispatch, NC **ncpp) +{ + int hdf_file = 0; + NC_FILE_INFO_T *nc_file; +#ifdef USE_PARALLEL + MPI_Comm comm = 0; + MPI_Info info = 0; +#else + int comm = 0, info = 0; +#endif /* USE_PARALLEL */ + int res; + + assert(ncpp && path); + + LOG((1, "nc_open_file: path %s mode %d comm %d info %d", + path, mode, comm, info)); + +#ifdef USE_PARALLEL + if (mpidata) + { + NC_MPI_INFO *nmi = (NC_MPI_INFO *)mpidata; + comm = nmi->comm; info = nmi->info; + } +#endif /* USE_PARALLEL */ + + /* If this is our first file, turn off HDF5 error messages. */ + if (virgin) + { + if (H5Eset_auto(NULL, NULL) < 0) + LOG((0, "Couldn't turn off HDF5 error messages!")); + LOG((1, "HDF5 error messages turned off!")); + virgin = 0; + } + + /* Check the mode for validity. First make sure only certain bits + * are turned on. Also MPI I/O and MPI POSIX cannot both be + * selected at once. */ + if (mode & ~(NC_WRITE | NC_SHARE | NC_MPIIO | NC_MPIPOSIX | + NC_PNETCDF | NC_NOCLOBBER | NC_NETCDF4 | NC_CLASSIC_MODEL) || + (mode & NC_MPIIO && mode & NC_MPIPOSIX)) + return NC_EINVAL; + + /* Figure out if this is a hdf4 or hdf5 file. */ + if ((res = nc_check_for_hdf(path, use_parallel, comm, info, &hdf_file))) + return res; + + /* Allocate the storage for this file info struct, and fill it with + zeros. */ + if ((res = nc4_file_list_add(&nc_file,dispatch))) + return res; + + /* Depending on the type of file, open it. */ + if (hdf_file == NC_HDF5_FILE) + { + nc_file->int_ncid = nc_file->ext_ncid; + res = nc4_open_file(path, mode, comm, info, nc_file); + } + else if (hdf_file == NC_HDF4_FILE) + { + nc_file->int_ncid = nc_file->ext_ncid; + res = nc4_open_hdf4_file(path, mode, nc_file); + } +#ifdef USE_PNETCDF + else if (mode & NC_PNETCDF) + { + int pnetcdf_nvars, i; + + res = ncmpi_open(comm, path, mode, info, &(nc_file->int_ncid)); + nc_file->pnetcdf_file++; + + /* Default to independent access, like netCDF-4/HDF5 files. */ + if (!res) + res = ncmpi_begin_indep_data(nc_file->int_ncid); + + /* I need to keep track of the ndims of each var to translate + * start, count, and stride arrays to MPI_Offset type. */ + if (!res) + { + res = ncmpi_inq_nvars(nc_file->int_ncid, &pnetcdf_nvars); + for (i = 0; i < pnetcdf_nvars; i++) + res = ncmpi_inq_varndims(nc_file->int_ncid, i, + &(nc_file->pnetcdf_ndims[i])); + + } + } +#endif /* USE_PNETCDF */ + else /* netcdf */ + { + assert(0); + } + + /* If it succeeds, pass back the new ncid. Otherwise, remove this + file from the list. */ + if (res) + { + if(nc_file != NULL) nc4_file_list_del(nc_file); + } + else + { + *ncpp = (NC*)nc_file; + } + + return res; +} + +/* Unfortunately HDF only allows specification of fill value only when + a dataset is created. Whereas in netcdf, you first create the + variable and then (optionally) specify the fill value. To + accomplish this in HDF5 I have to delete the dataset, and recreate + it, with the fill value specified. */ +int +NC4_set_fill(int ncid, int fillmode, int *old_modep) +{ + NC_FILE_INFO_T *nc; + + LOG((2, "nc_set_fill: ncid 0x%x fillmode %d", ncid, fillmode)); + + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + + /* Is this a netcdf-3 file? */ + assert(nc->nc4_info); + + /* Trying to set fill on a read-only file? You sicken me! */ + if (nc->nc4_info->no_write) + return NC_EPERM; + + /* Did you pass me some weird fillmode? */ + if (fillmode != NC_FILL && fillmode != NC_NOFILL) + return NC_EINVAL; + + /* If the user wants to know, tell him what the old mode was. */ + if (old_modep) + *old_modep = nc->nc4_info->fill_mode; + + nc->nc4_info->fill_mode = fillmode; + + return NC_NOERR; +} + +/* Put the file back in redef mode. This is done automatically for + * netcdf-4 files, if the user forgets. */ +int +NC4_redef(int ncid) +{ + NC_FILE_INFO_T *nc; + + LOG((1, "nc_redef: ncid 0x%x", ncid)); + + /* Find this file's metadata. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_redef(nc->int_ncid); +#endif /* USE_PNETCDF */ + + /* Handle netcdf-3 files. */ + assert(nc->nc4_info); + + /* If we're already in define mode, return an error. */ + if (nc->nc4_info->flags & NC_INDEF) + return NC_EINDEFINE; + + /* If the file is read-only, return an error. */ + if (nc->nc4_info->no_write) + return NC_EPERM; + + /* Set define mode. */ + nc->nc4_info->flags |= NC_INDEF; + + /* For nc_abort, we need to remember if we're in define mode as a + redef. */ + nc->nc4_info->redef++; + + return NC_NOERR; +} + +/* For netcdf-4 files, this just calls nc_enddef, ignoring the extra + * parameters. */ +int +NC4__enddef(int ncid, size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align) +{ + if (!nc4_find_nc_file(ncid)) + return NC_EBADID; + + return NC4_enddef(ncid); +} + +/* Take the file out of define mode. This is called automatically for + * netcdf-4 files, if the user forgets. */ +static int NC4_enddef(int ncid) +{ + NC_FILE_INFO_T *nc; + + LOG((1, "nc_enddef: ncid 0x%x", ncid)); + + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + if (nc->pnetcdf_file) + { + int res; + res = ncmpi_enddef(nc->int_ncid); + if (!res) + { + if (nc->pnetcdf_access_mode == NC_INDEPENDENT) + res = ncmpi_begin_indep_data(nc->int_ncid); + } + return res; + } +#endif /* USE_PNETCDF */ + + /* Take care of netcdf-3 files. */ + assert(nc->nc4_info); + + return nc4_enddef_netcdf4_file(nc->nc4_info); +} + +/* This function will write all changed metadata, and (someday) reread + * all metadata from the file. */ +static int +sync_netcdf4_file(NC_HDF5_FILE_INFO_T *h5) +{ + int retval; + + assert(h5); + LOG((3, "sync_netcdf4_file")); + + /* If we're in define mode, that's an error, for strict nc3 rules, + * otherwise, end define mode. */ + if (h5->flags & NC_INDEF) + { + if (h5->cmode & NC_CLASSIC_MODEL) + return NC_EINDEFINE; + + /* Turn define mode off. */ + h5->flags ^= NC_INDEF; + + /* Redef mode needs to be tracked seperately for nc_abort. */ + h5->redef = 0; + } + +#ifdef LOGGING + /* This will print out the names, types, lens, etc of the vars and + atts in the file, if the logging level is 2 or greater. */ + log_metadata_nc(h5->root_grp->file); +#endif + + /* Write any metadata that has changed. */ + if (!(h5->cmode & NC_NOWRITE)) + { + if ((retval = nc4_rec_write_types(h5->root_grp))) + return retval; + if ((retval = nc4_rec_write_metadata(h5->root_grp))) + return retval; + } + + H5Fflush(h5->hdfid, H5F_SCOPE_GLOBAL); + + /* Reread all the metadata. */ + /*if ((retval = nc4_rec_read_metadata(grp))) + return retval;*/ + + return retval; +} + +/* Flushes all buffers associated with the file, after writing all + changed metadata. This may only be called in data mode. */ +int +NC4_sync(int ncid) +{ + NC_FILE_INFO_T *nc; + int retval; + + LOG((2, "nc_sync: ncid 0x%x", ncid)); + + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_sync(nc->int_ncid); +#endif /* USE_PNETCDF */ + + /* Take care of netcdf-3 files. */ + assert(nc->nc4_info); + + /* If we're in define mode, we can't sync. */ + if (nc->nc4_info && nc->nc4_info->flags & NC_INDEF) + { + if (nc->nc4_info->cmode & NC_CLASSIC_MODEL) + return NC_EINDEFINE; + if ((retval = nc_enddef(ncid))) + return retval; + } + + return sync_netcdf4_file(nc->nc4_info); +} + +/* This function will free all allocated metadata memory, and close + the HDF5 file. The group that is passed in must be the root group + of the file. */ +static int +close_netcdf4_file(NC_HDF5_FILE_INFO_T *h5, int abort) +{ + int retval; + + assert(h5 && h5->root_grp); + LOG((3, "close_netcdf4_file: h5->path %s abort %d", + h5->path, abort)); + + /* According to the docs, always end define mode on close. */ + if (h5->flags & NC_INDEF) + h5->flags ^= NC_INDEF; + + /* Sync the file, unless we're aborting, or this is a read-only + * file. */ + if (!h5->no_write && !abort) + if ((retval = sync_netcdf4_file(h5))) + return retval; + + /* Delete all the list contents for vars, dims, and atts, in each + * group. */ + if ((retval = nc4_rec_grp_del(&h5->root_grp, h5->root_grp))) + return retval; + + /* Close hdf file. */ + if (h5->hdf4) + { +#ifdef USE_HDF4 + if (SDend(h5->sdid)) + return NC_EHDFERR; +#endif /* USE_HDF4 */ + } + else + { + if (H5Fclose(h5->hdfid) < 0) + { + int nobjs; + nobjs = H5Fget_obj_count(h5->hdfid, H5F_OBJ_ALL); + /* Apparently we can get an error even when nobjs == 0 */ + if(nobjs < 0) { + return NC_EHDFERR; + } else if(nobjs > 0) { +#ifdef LOGGING + /* If the close doesn't work, probably there are still some HDF5 + * objects open, which means there's a bug in the library. So + * print out some info on to help the poor programmer figure it + * out. */ + LOG((0, "There are %d HDF5 objects open!", nobjs)); +#endif + return NC_EHDFERR; + } + } +/* if (H5garbage_collect() < 0) + return NC_EHDFERR; */ + } + + /* Delete the memory for the path, if it's been allocated. */ + if (h5->path) + free(h5->path); + + /* Free the nc4_info struct. */ + free(h5); + return NC_NOERR; +} + +/* From the netcdf-3 docs: The function nc_abort just closes the + netCDF dataset, if not in define mode. If the dataset is being + created and is still in define mode, the dataset is deleted. If + define mode was entered by a call to nc_redef, the netCDF dataset + is restored to its state before definition mode was entered and the + dataset is closed. */ +int +NC4_abort(int ncid) +{ + NC_FILE_INFO_T *nc; + int delete_file = 0; + char path[NC_MAX_NAME + 1]; + int retval = NC_NOERR; + + LOG((2, "nc_abort: ncid 0x%x", ncid)); + + /* Find metadata for this file. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_abort(nc->int_ncid); +#endif /* USE_PNETCDF */ + + /* If this is a netcdf-3 file, let the netcdf-3 library handle it. */ + assert(nc->nc4_info); + + /* If we're in define mode, but not redefing the file, delete it. */ + if (nc->nc4_info->flags & NC_INDEF && !nc->nc4_info->redef) + { + delete_file++; + strcpy(path, nc->nc4_info->path); + /*strcpy(path, nc->path);*/ + } + + /* Free any resources the netcdf-4 library has for this file's + * metadata. */ + if ((retval = close_netcdf4_file(nc->nc4_info, 1))) + return retval; + + /* Delete the file, if we should. */ + if (delete_file) + remove(path); + + /* Delete this entry from our list of open files. */ + nc4_file_list_del(nc); + + return retval; +} + +/* Close the netcdf file, writing any changes first. */ +int +NC4_close(int ncid) +{ + NC_GRP_INFO_T *grp; + NC_FILE_INFO_T *nc; + NC_HDF5_FILE_INFO_T *h5; + int retval; + + LOG((1, "nc_close: ncid 0x%x", ncid)); + + /* Find our metadata for this file. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_close(nc->int_ncid); +#endif /* USE_PNETCDF */ + + assert(h5 && nc); + + /* This must be the root group. */ + if (grp->parent) + return NC_EBADGRPID; + + /* Call the nc4 close. */ + if ((retval = close_netcdf4_file(grp->file->nc4_info, 0))) + return retval; + + /* Delete this entry from our list of open files. */ + if (nc->path) + free(nc->path); + nc4_file_list_del(nc); + + /* Reset the ncid numbers if there are no more files open. */ + if(count_NCList() == 0) + nc4_file_list_free(); + + return NC_NOERR; +} + +/* It's possible for any of these pointers to be NULL, in which case + don't try to figure out that value. */ +int +NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp) +{ + NC_FILE_INFO_T *nc; + NC_HDF5_FILE_INFO_T *h5; + NC_GRP_INFO_T *grp; + NC_DIM_INFO_T *dim; + NC_ATT_INFO_T *att; + NC_VAR_INFO_T *var; + int retval; + + LOG((2, "nc_inq: ncid 0x%x", ncid)); + + /* Find file metadata. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_inq(nc->int_ncid, ndimsp, nvarsp, nattsp, unlimdimidp); +#endif /* USE_PNETCDF */ + + /* Netcdf-3 files are already taken care of. */ + assert(h5 && grp && nc); + + /* Count the number of dims, vars, and global atts. */ + if (ndimsp) + { + *ndimsp = 0; + for (dim = grp->dim; dim; dim = dim->next) + (*ndimsp)++; + } + if (nvarsp) + { + *nvarsp = 0; + for (var = grp->var; var; var= var->next) + (*nvarsp)++; + } + if (nattsp) + { + *nattsp = 0; + for (att = grp->att; att; att = att->next) + (*nattsp)++; + } + + if (unlimdimidp) + { + /* Default, no unlimited dimension */ + int found = 0; + *unlimdimidp = -1; + + /* If there's more than one unlimited dim, which was not possible + with netcdf-3, then only the last unlimited one will be reported + back in xtendimp. */ + /* Note that this code is inconsistent with nc_inq_unlimid() */ + for (dim = grp->dim; dim; dim = dim->next) + if (dim->unlimited) + { + *unlimdimidp = dim->dimid; + break; + } + } + + return NC_NOERR; +} + + +/* This function will do the enddef stuff for a netcdf-4 file. */ +int +nc4_enddef_netcdf4_file(NC_HDF5_FILE_INFO_T *h5) +{ + assert(h5); + LOG((3, "nc4_enddef_netcdf4_file")); + + /* If we're not in define mode, return an error. */ + if (!(h5->flags & NC_INDEF)) + return NC_ENOTINDEFINE; + + /* Turn define mode off. */ + h5->flags ^= NC_INDEF; + + /* Redef mode needs to be tracked seperately for nc_abort. */ + h5->redef = 0; + + return sync_netcdf4_file(h5); +} + +#ifdef EXTRA_TESTS +int +nc_exit() +{ + if (num_plists || num_spaces) + return NC_EHDFERR; + + return NC_NOERR; +} +#endif /* EXTRA_TESTS */ + +#ifdef USE_PARALLEL +int +nc_use_parallel_enabled() +{ + return 0; +} +#endif /* USE_PARALLEL */ + + diff --git a/extern/src_netcdf4/nc4grp.c b/extern/src_netcdf4/nc4grp.c new file mode 100644 index 0000000000000000000000000000000000000000..93b269c0fce9093ed71638aaf82e68df1c04f6fe --- /dev/null +++ b/extern/src_netcdf4/nc4grp.c @@ -0,0 +1,440 @@ +/* +This file is part of netcdf-4, a netCDF-like interface for HDF5, or a +HDF5 backend for netCDF, depending on your point of view. + +This file handles the nc4 groups. + +Copyright 2005, University Corporation for Atmospheric Research. See +netcdf-4/docs/COPYRIGHT file for copying and redistribution +conditions. + +$Id: nc4grp.c,v 1.44 2010/05/25 17:54:23 dmh Exp $ +*/ + +#include "nc4internal.h" +#include "nc4dispatch.h" + +/* Create a group. It's ncid is returned in the new_ncid pointer. */ +int +NC4_def_grp(int parent_ncid, const char *name, int *new_ncid) +{ + NC_GRP_INFO_T *grp, *g; + NC_HDF5_FILE_INFO_T *h5; + char norm_name[NC_MAX_NAME + 1]; + int retval; + + LOG((2, "nc_def_grp: parent_ncid 0x%x name %s", parent_ncid, name)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(parent_ncid, &grp, &h5))) + return retval; + if (!h5) + return NC_ENOTNC4; + + /* Check and normalize the name. */ + if ((retval = nc4_check_name(name, norm_name))) + return retval; + + /* Check that this name is not in use as a var, grp, or type. */ + if ((retval = nc4_check_dup_name(grp, norm_name))) + return retval; + + /* No groups in netcdf-3! */ + if (h5->cmode & NC_CLASSIC_MODEL) + return NC_ESTRICTNC3; + + /* If it's not in define mode, switch to define mode. */ + if (!(h5->flags & NC_INDEF)) + if ((retval = NC4_redef(parent_ncid))) + return retval; + + /* Update internal lists to reflect new group. The actual HDF5 + * group creation will be done when metadata is written by a + * sync. */ + if ((retval = nc4_grp_list_add(&(grp->children), h5->next_nc_grpid, + grp, grp->file, norm_name, &g))) + return retval; + if (new_ncid) + *new_ncid = grp->file->ext_ncid | h5->next_nc_grpid; + h5->next_nc_grpid++; + + return NC_NOERR; +} + +/* Given an ncid and group name (NULL gets root group), return + * the ncid of that group. */ +int +NC4_inq_ncid(int ncid, const char *name, int *grp_ncid) +{ + NC_GRP_INFO_T *grp, *g; + NC_HDF5_FILE_INFO_T *h5; + char norm_name[NC_MAX_NAME + 1]; + int retval; + + LOG((2, "nc_inq_ncid: ncid 0x%x name %s", ncid, name)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + + /* Groups only work with netCDF-4/HDF5 files... */ + if (!h5) + return NC_ENOTNC4; + + /* Normalize name. */ + if ((retval = nc4_normalize_name(name, norm_name))) + return retval; + + /* Look through groups for one of this name. */ + for (g = grp->children; g; g = g->next) + if (!strcmp(norm_name, g->name)) /* found it! */ + { + if (grp_ncid) + *grp_ncid = grp->file->ext_ncid | g->nc_grpid; + return NC_NOERR; + } + + /* If we got here, we didn't find the named group. */ + return NC_ENOGRP; +} + +/* Given a location id, return the number of groups it contains, and + * an array of their locids. */ +int +NC4_inq_grps(int ncid, int *numgrps, int *ncids) +{ + NC_GRP_INFO_T *grp, *g; + NC_HDF5_FILE_INFO_T *h5; + int num = 0; + int retval; + + LOG((2, "nc_inq_grps: ncid 0x%x", ncid)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + + /* For netCDF-3 files, just report zero groups. */ + if (!h5) + { + if (numgrps) + *numgrps = 0; + return NC_NOERR; + } + + /* Count the number of groups in this group. */ + for (g = grp->children; g; g = g->next) + { + if (ncids) + { + /* Combine the nc_grpid in a bitwise or with the ext_ncid, + * which allows the returned ncid to carry both file and + * group information. */ + *ncids = g->nc_grpid | g->file->ext_ncid; + ncids++; + } + num++; + } + + if (numgrps) + *numgrps = num; + + return NC_NOERR; +} + +/* Given locid, find name of group. (Root group is named "/".) */ +int +NC4_inq_grpname(int ncid, char *name) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + int retval; + + LOG((2, "nc_inq_grpname: ncid 0x%x", ncid)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + if (name) + { + if (!h5) + strcpy(name, "/"); + else + strcpy(name, grp->name); + } + + return NC_NOERR; +} + +/* Find the full path name to the group represented by ncid. Either + * pointer argument may be NULL; pass a NULL for the third parameter + * to get the length of the full path name. The length will not + * include room for a null pointer. */ +int +NC4_inq_grpname_full(int ncid, size_t *lenp, char *full_name) +{ + char *name, grp_name[NC_MAX_NAME + 1]; + int g, id = ncid, parent_id, *gid; + int i, ret = NC_NOERR; + + /* How many generations? */ + for (g = 0; !nc_inq_grp_parent(id, &parent_id); g++, id = parent_id) + ; + + /* Allocate storage. */ + if (!(name = malloc((g + 1) * (NC_MAX_NAME + 1) + 1))) + return NC_ENOMEM; + if (!(gid = malloc((g + 1) * sizeof(int)))) + { + free(name); + return NC_ENOMEM; + } + assert(name && gid); + + /* Always start with a "/" for the root group. */ + strcpy(name, "/"); + + /* Get the ncids for all generations. */ + gid[0] = ncid; + for (i = 1; i < g && !ret; i++) + ret = nc_inq_grp_parent(gid[i - 1], &gid[i]); + + /* Assemble the full name. */ + for (i = g - 1; !ret && i >= 0 && !ret; i--) + { + if ((ret = nc_inq_grpname(gid[i], grp_name))) + break; + strcat(name, grp_name); + if (i) + strcat(name, "/"); + } + + /* Give the user the length of the name, if he wants it. */ + if (!ret && lenp) + *lenp = strlen(name); + + /* Give the user the name, if he wants it. */ + if (!ret && full_name) + strcpy(full_name, name); + + free(gid); + free(name); + + return ret; +} + +/* Find the parent ncid of a group. For the root group, return + * NC_ENOGRP error. *Now* I know what kind of tinfoil hat wearing nut + * job would call this function with a NULL pointer for parent_ncid - + * Russ Rew!! */ +int +NC4_inq_grp_parent(int ncid, int *parent_ncid) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + int retval; + + LOG((2, "nc_inq_grp_parent: ncid 0x%x", ncid)); + + /* Find info for this file and group. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + + /* Groups only work with netCDF-4/HDF5 files... */ + if (!h5) + return NC_ENOGRP; + + /* Set the parent ncid, if there is one. */ + if (grp->parent) + { + if (parent_ncid) + *parent_ncid = grp->file->ext_ncid | grp->parent->nc_grpid; + } + else + return NC_ENOGRP; + + return NC_NOERR; +} + +/* Given a full name and ncid, find group ncid. */ +int +NC4_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + int id1 = ncid, id2; + char *cp, *full_name_cpy; + int ret; + + if (!full_name) + return NC_EINVAL; + + /* Find info for this file and group, and set pointer to each. */ + if ((ret = nc4_find_grp_h5(ncid, &grp, &h5))) + return ret; + + /* Copy full_name because strtok messes with the value it works + * with, and we don't want to mess up full_name. */ + if (!(full_name_cpy = malloc(strlen(full_name) + 1))) + return NC_ENOMEM; + strcpy(full_name_cpy, full_name); + + /* Get the first part of the name. */ + if (!(cp = strtok(full_name_cpy, "/"))) + { + /* If "/" is passed, and this is the root group, return the root + * group id. */ + if (!grp->parent) + id2 = ncid; + else + { + free(full_name_cpy); + return NC_ENOGRP; + } + } + else + { + /* Keep parsing the string. */ + for (; cp; id1 = id2) + { + if ((ret = nc_inq_grp_ncid(id1, cp, &id2))) + { + free(full_name_cpy); + return ret; + } + cp = strtok(NULL, "/"); + } + } + + /* Give the user the requested value. */ + if (grp_ncid) + *grp_ncid = id2; + + free(full_name_cpy); + + return NC_NOERR; +} + +/* Get a list of ids for all the variables in a group. */ +int +NC4_inq_varids(int ncid, int *nvars, int *varids) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + int v, num_vars = 0; + int retval; + + LOG((2, "nc_inq_varids: ncid 0x%x", ncid)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + + if (!h5) + { + /* If this is a netcdf-3 file, there is only one group, the root + * group, and its vars have ids 0 thru nvars - 1. */ + if ((retval = nc_inq(ncid, NULL, &num_vars, NULL, NULL))) + return retval; + if (varids) + for (v = 0; v < num_vars; v++) + varids[v] = v; + } + else + { + /* This is a netCDF-4 group. Round up them doggies and count + * 'em. The list is in correct (i.e. creation) order. */ + if (grp->var) + { + for (var = grp->var; var; var = var->next) + { + if (varids) + varids[num_vars] = var->varid; + num_vars++; + } + } + } + + /* If the user wants to know how many vars in the group, tell + * him. */ + if (nvars) + *nvars = num_vars; + + return NC_NOERR; +} + +/* This is the comparison function used for sorting dim ids. Integer + comparison: returns negative if b > a and positive if a > b. */ +int int_cmp(const void *a, const void *b) +{ + const int *ia = (const int *)a; + const int *ib = (const int *)b; + return *ia - *ib; +} + +/* Find all dimids for a location. This finds all dimensions in a + * group, with or without any of its parents, depending on last + * parameter. */ +int +NC4_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents) +{ + NC_GRP_INFO_T *grp, *g; + NC_HDF5_FILE_INFO_T *h5; + NC_DIM_INFO_T *dim; + int d, num = 0; + int retval; + + LOG((2, "nc_inq_dimids: ncid 0x%x include_parents: %d", ncid, + include_parents)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + + if (!h5) + { + /* If this is a netcdf-3 file, then the dimids are going to be 0 + * thru ndims-1, so just provide them. */ + if ((retval = nc_inq(ncid, &num, NULL, NULL, NULL))) + return retval; + if (dimids) + for (d = 0; d < num; d++) + dimids[d] = d; + } + else + { + /* First count them. */ + for (dim = grp->dim; dim; dim = dim->next) + num++; + if (include_parents) + for (g = grp->parent; g; g = g->parent) + for (dim = g->dim; dim; dim = dim->next) + num++; + + /* If the user wants the dimension ids, get them. */ + if (dimids) + { + int n = 0; + + /* Get dimension ids from this group. */ + for (dim = grp->dim; dim; dim = dim->next) + dimids[n++] = dim->dimid; + + /* Get dimension ids from parent groups. */ + if (include_parents) + for (g = grp->parent; g; g = g->parent) + for (dim = g->dim; dim; dim = dim->next) + dimids[n++] = dim->dimid; + + qsort(dimids, num, sizeof(int), int_cmp); + } + } + + /* If the user wants the number of dims, give it. */ + if (ndims) + *ndims = num; + + return NC_NOERR; +} + diff --git a/extern/src_netcdf4/nc4hdf.c b/extern/src_netcdf4/nc4hdf.c new file mode 100644 index 0000000000000000000000000000000000000000..5153a68452a7dd206ce7b42922e336b7241ec586 --- /dev/null +++ b/extern/src_netcdf4/nc4hdf.c @@ -0,0 +1,4041 @@ +/* + This file is part of netcdf-4, a netCDF-like interface for HDF5, or a + HDF5 backend for netCDF, depending on your point of view. + + This file contains functions internal to the netcdf4 library. None of + the functions in this file are exposed in the exetnal API. These + functions handle the HDF interface. + + Copyright 2003, University Corporation for Atmospheric + Research. See the COPYRIGHT file for copying and redistribution + conditions. + + $Id: nc4hdf.c,v 1.273 2010/05/27 21:34:14 dmh Exp $ +*/ + +#include "config.h" +#include "nc4internal.h" +#include +#include + +#ifdef IGNORE +extern NC_FILE_INFO_T *nc_file; +#endif + +#define NC3_STRICT_ATT_NAME "_nc3_strict" + +/* This is to track opened HDF5 objects to make sure they are + * closed. */ +#ifdef EXTRA_TESTS +int num_plists; +int num_spaces; +#endif /* EXTRA_TESTS */ + +/* This function is needed to handle one special case: what if the + * user defines a dim, writes metadata, then goes back into define + * mode and adds a coordinate var for the already existing dim. In + * that case, I need to recreate the dim's dimension scale dataset, + * and then I need to go to every var in the file which uses that + * dimension, and attach the new dimension scale. */ +static int +rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid) +{ + NC_VAR_INFO_T *var; + NC_GRP_INFO_T *child_grp; + int d; + int retval; + + assert(grp && grp->name && dimid >= 0 && dimscaleid >= 0); + LOG((3, "rec_reattach_scales: grp->name %s", grp->name)); + + /* If there are any child groups, attach dimscale there, if needed. */ + for (child_grp = grp->children; child_grp; child_grp = child_grp->next) + if ((retval = rec_reattach_scales(child_grp, dimid, dimscaleid))) + return retval; + + /* Find any vars that use this dimension id. */ + for (var = grp->var; var; var = var->next) + for (d = 0; d < var->ndims; d++) + if (var->dimids[d] == dimid && !var->dimscale) + { + LOG((2, "rec_reattach_scaled: attaching scale for dimid %d to var %s", + var->dimids[d], var->name)); + if (var->created) + { + if (H5DSattach_scale(var->hdf_datasetid, dimscaleid, d) < 0) + return NC_EHDFERR; + var->dimscale_attached[d]++; + } + } + + return NC_NOERR; +} + +/* This function is needed to handle one special case: what if the + * user defines a dim, writes metadata, then goes back into define + * mode and adds a coordinate var for the already existing dim. In + * that case, I need to recreate the dim's dimension scale dataset, + * and then I need to go to every var in the file which uses that + * dimension, and attach the new dimension scale. */ +static int +rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid) +{ + NC_VAR_INFO_T *var; + NC_GRP_INFO_T *child_grp; + int d; + int retval; + + assert(grp && grp->name && dimid >= 0 && dimscaleid >= 0); + LOG((3, "rec_detach_scales: grp->name %s", grp->name)); + + /* If there are any child groups, attach dimscale there, if needed. */ + for (child_grp = grp->children; child_grp; child_grp = child_grp->next) + if ((retval = rec_detach_scales(child_grp, dimid, dimscaleid))) + return retval; + + /* If there are no vars, we are done. */ + if (!grp->var) + return NC_NOERR; + + /* Find any (already created) vars that use this dimension id. Go + * through the list backwards to accomdate a HDF5 bug. */ + for (var = grp->var; var->next; var = var->next) + ; + + for ( ; var; var = var->prev) + for (d = 0; d < var->ndims; d++) + if (var->dimids[d] == dimid && !var->dimscale) + { + LOG((2, "rec_detach_scales: detaching scale for dimid %d to var %s", + var->dimids[d], var->name)); + if (var->created) + { + if (var->dimscale_attached[d]) + { + if (H5DSdetach_scale(var->hdf_datasetid, dimscaleid, d) < 0) + return NC_EHDFERR; + var->dimscale_attached[d] = 0; + } + } + } + + return NC_NOERR; +} + +/* Open the dataset and leave it open. */ +int +nc4_open_var_grp2(NC_GRP_INFO_T *grp, int varid, hid_t *dataset) +{ + NC_VAR_INFO_T *var; + + /* Find the requested varid. */ + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + break; + if (!var) + return NC_ENOTVAR; + + /* Open this dataset if necessary. */ + if (!var->hdf_datasetid) + if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name, + H5P_DEFAULT)) < 0) + return NC_ENOTVAR; + + *dataset = var->hdf_datasetid; + + return NC_NOERR; +} + +/* Write or read one element of data. + + Oh, better far to live and die + Under the brave black flag I fly, + Than play a sanctimonious part, + With a pirate head and a pirate heart. + + Away to the cheating world go you, + Where pirates all are well-to-do. + But I'll be true to the song I sing, + And live and die a Pirate king. +*/ +int +nc4_pg_var1(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, + const size_t *indexp, nc_type xtype, int is_long, void *ip) +{ + NC_GRP_INFO_T *grp; + NC_VAR_INFO_T *var; + int i; + size_t start[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; + int retval; + + /* Find file and var, cause I need the number of dims. */ + assert(nc); + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; + assert(grp && var && var->name); + + /* Set up the count and start arrays. */ + for (i=0; indims; i++) + { + start[i] = indexp[i]; + count[i] = 1; + } + + /* Get or put this data. */ + if (pg == GET) + return nc4_get_vara(nc, ncid, varid, start, count, xtype, + is_long, ip); + else + return nc4_put_vara(nc, ncid, varid, start, count, xtype, + is_long, ip); +} + +/* Get the default fill value for an atomic type. Memory for + * fill_value must already be allocated, or you are DOOMED!!!*/ +int +nc4_get_default_fill_value(NC_TYPE_INFO_T *type_info, void *fill_value) +{ + switch (type_info->nc_typeid) + { + case NC_BYTE: + *(signed char *)fill_value = NC_FILL_BYTE; + break; + case NC_CHAR: + *(char *)fill_value = NC_FILL_CHAR; + break; + case NC_SHORT: + *(short *)fill_value = NC_FILL_SHORT; + break; + case NC_INT: + *(int *)fill_value = NC_FILL_INT; + break; + case NC_FLOAT: + *(float *)fill_value = NC_FILL_FLOAT; + break; + case NC_DOUBLE: + *(double *)fill_value = NC_FILL_DOUBLE; + break; + case NC_UBYTE: + *(unsigned char *)fill_value = NC_FILL_UBYTE; + break; + case NC_USHORT: + *(unsigned short *)fill_value = NC_FILL_USHORT; + break; + case NC_UINT: + *(unsigned int *)fill_value = NC_FILL_UINT; + break; + case NC_INT64: + *(long long *)fill_value = NC_FILL_INT64; + break; + case NC_UINT64: + *(unsigned long long *)fill_value = NC_FILL_UINT64; + break; + case NC_STRING: + strcpy((char *)fill_value, ""); + break; + default: + return NC_EINVAL; + } + + return NC_NOERR; +} + +/* What fill value should be used for a variable? */ +static int +get_fill_value(NC_HDF5_FILE_INFO_T *h5, NC_VAR_INFO_T *var, void **fillp) +{ + size_t size; + int retval; + + /* Find out how much space we need for this type's fill value. */ + if ((retval = nc4_get_typelen_mem(h5, var->xtype, 0, &size))) + return retval; + + /* Strings have a size of one for the empty sting (to hold the + * null), otherwise the length of the users fill_value string, plus + * one. */ + if (var->xtype == NC_STRING) + { + size = 1; + } + + /* Allocate the space. VLENS are different, of course. */ + if (var->type_info->class == NC_VLEN) + { + if (!((*fillp) = malloc(sizeof(nc_vlen_t)))) + return NC_ENOMEM; + } + else + { + if (!((*fillp) = malloc(size))) + return NC_ENOMEM; + } + + /* If the user has set a fill_value for this var, use, otherwise + * find the default fill value. */ + if (var->fill_value) + { + LOG((4, "Found a fill value for var %s", var->name)); + if (var->type_info->class == NC_VLEN) + { + nc_vlen_t *in_vlen = (nc_vlen_t *)(var->fill_value), *fv_vlen = (nc_vlen_t *)(*fillp); + fv_vlen->len = in_vlen->len; + if (!(fv_vlen->p = malloc(size * in_vlen->len))) + return NC_ENOMEM; + memcpy(fv_vlen->p, in_vlen->p, in_vlen->len * size); + } + else if (var->xtype == NC_STRING) + { + if (!(*(char **)fillp = malloc((strlen((char *)var->fill_value) + 1) * + sizeof(char)))) + return NC_ENOMEM; + strcpy(*(char **)fillp, (char *)var->fill_value); + } + else + memcpy((*fillp), var->fill_value, size); + } + else + { + if ((nc4_get_default_fill_value(var->type_info, *fillp))) + { + free(*fillp); + *fillp = NULL; + } + } + + return NC_NOERR; +} + +/* Given a netcdf type, return appropriate HDF typeid. */ +int +nc4_get_hdf_typeid(NC_HDF5_FILE_INFO_T *h5, nc_type xtype, + hid_t *hdf_typeid, int endianness) +{ + NC_TYPE_INFO_T *type; + hid_t typeid = 0; + int retval = NC_NOERR; + + assert(hdf_typeid && h5); + + *hdf_typeid = -1; + switch (xtype) + { + case NC_NAT: /* NAT = 'Not A Type' (c.f. NaN) */ + return NC_EBADTYPE; + case NC_BYTE: /* signed 1 byte integer */ + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_STD_I8LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_STD_I8BE; + else + *hdf_typeid = H5T_NATIVE_SCHAR; + break; + case NC_CHAR: /* ISO/ASCII character */ + if ((typeid = H5Tcopy(H5T_C_S1)) < 0) + return NC_EHDFERR; + if (H5Tset_strpad(typeid, H5T_STR_NULLTERM) < 0) + BAIL(NC_EVARMETA); + *hdf_typeid = typeid; + break; + case NC_SHORT: /* signed 2 byte integer */ + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_STD_I16LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_STD_I16BE; + else + *hdf_typeid = H5T_NATIVE_SHORT; + break; + case NC_INT: + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_STD_I32LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_STD_I32BE; + else + *hdf_typeid = H5T_NATIVE_INT; + break; + case NC_FLOAT: + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_IEEE_F32LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_IEEE_F32BE; + else + *hdf_typeid = H5T_NATIVE_FLOAT; + break; + case NC_DOUBLE: + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_IEEE_F64LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_IEEE_F64BE; + else + *hdf_typeid = H5T_NATIVE_DOUBLE; + break; + case NC_UBYTE: + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_STD_U8LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_STD_U8BE; + else + *hdf_typeid = H5T_NATIVE_UCHAR; + break; + case NC_USHORT: + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_STD_U16LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_STD_U16BE; + else + *hdf_typeid = H5T_NATIVE_USHORT; + break; + case NC_UINT: + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_STD_U32LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_STD_U32BE; + else + *hdf_typeid = H5T_NATIVE_UINT; + break; + case NC_INT64: + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_STD_I64LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_STD_I64BE; + else + *hdf_typeid = H5T_NATIVE_LLONG; + break; + case NC_UINT64: + if (endianness == NC_ENDIAN_LITTLE) + *hdf_typeid = H5T_STD_U64LE; + else if (endianness == NC_ENDIAN_BIG) + *hdf_typeid = H5T_STD_U64BE; + else + *hdf_typeid = H5T_NATIVE_ULLONG; + break; + case NC_STRING: + if ((typeid = H5Tcopy(H5T_C_S1)) < 0) + return NC_EHDFERR; + if (H5Tset_size(typeid, H5T_VARIABLE) < 0) + return NC_EHDFERR; + *hdf_typeid = typeid; + break; + default: + /* Maybe this is a user defined type? */ + if (!nc4_find_type(h5, xtype, &type)) + { + if (!type) + return NC_EBADTYPE; + *hdf_typeid = type->hdf_typeid; + } + } + + if (*hdf_typeid == -1) + return NC_EBADTYPE; + + return NC_NOERR; + + exit: + if (xtype == NC_CHAR && typeid > 0 && H5Tclose(typeid) < 0) + BAIL2(NC_EHDFERR); + return retval; +} + +/* Do some common check for nc4_put_vara and nc4_get_vara. These + * checks have to be done when both reading and writing data. */ +static int +check_for_vara(nc_type *mem_nc_type, NC_VAR_INFO_T *var, NC_HDF5_FILE_INFO_T *h5) +{ + int retval; + + /* If mem_nc_type is NC_NAT, it means we want to use the file type + * as the mem type as well. */ + assert(mem_nc_type); + if (*mem_nc_type == NC_NAT) + *mem_nc_type = var->xtype; + assert(*mem_nc_type); + + /* No NC_CHAR conversions, you pervert! */ + if (var->xtype != *mem_nc_type && + (var->xtype == NC_CHAR || *mem_nc_type == NC_CHAR)) + return NC_ECHAR; + + /* If we're in define mode, we can't read or write data. */ + if (h5->flags & NC_INDEF) + { + if (h5->cmode & NC_CLASSIC_MODEL) + return NC_EINDEFINE; + if ((retval = nc4_enddef_netcdf4_file(h5))) + return retval; + } + + return NC_NOERR; +} + +#ifdef LOGGING +/* Print some debug info about dimensions to the log. */ +static void +log_dim_info(NC_VAR_INFO_T *var, hsize_t *fdims, hsize_t *fmaxdims, + hsize_t *start, hsize_t *count) +{ + int d2; + + /* Print some debugging info... */ + LOG((4, "nc4_put_vara: var name %s ndims %d", var->name, var->ndims)); + LOG((4, "File space, and requested:")); + for (d2 = 0; d2 < var->ndims; d2++) + { + LOG((4, "fdims[%d]=%Ld fmaxdims[%d]=%Ld", d2, fdims[d2], d2, + fmaxdims[d2])); + LOG((4, "start[%d]=%Ld count[%d]=%Ld", d2, start[d2], d2, count[d2])); + } +} +#endif /* LOGGING */ + +#ifdef USE_PARALLEL +static int +set_par_access(NC_HDF5_FILE_INFO_T *h5, NC_VAR_INFO_T *var, hid_t xfer_plistid) +{ + H5FD_mpio_xfer_t hdf5_xfer_mode; + + /* If netcdf is built with parallel I/O, then parallel access can + * be used, and, if this file was opened or created for parallel + * access, we need to set the transfer mode. */ + if (h5->parallel) + { + /* Decide on collective or independent. */ + hdf5_xfer_mode = (var->parallel_access != NC_INDEPENDENT) ? + H5FD_MPIO_COLLECTIVE : H5FD_MPIO_INDEPENDENT; + + /* Set the mode in the transfer property list. */ + if (H5Pset_dxpl_mpio(xfer_plistid, hdf5_xfer_mode) < 0) + return NC_EPARINIT; + + LOG((4, "hdf5_xfer_mode: %d H5FD_MPIO_COLLECTIVE: %d H5FD_MPIO_INDEPENDENT: %d", + (int)hdf5_xfer_mode, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_INDEPENDENT)); + } + return NC_NOERR; +} +#endif + +/* Write an array of data to a variable. When it comes right down to + * it, this is what netCDF-4 is all about, this is *the* function, the + * big enchilda, the grand poo-bah, the alpha dog, the head honcho, + * the big cheese, the mighty kahuna, the top bananna, the high + * muckity-muck, numero uno. Well, you get the idea. */ +int +nc4_put_vara(NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp, + const size_t *countp, nc_type mem_nc_type, int is_long, void *data) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim; + + hid_t file_spaceid = 0, mem_spaceid = 0, xfer_plistid = 0; + size_t file_type_size; + + hsize_t *xtend_size = NULL, count[NC_MAX_VAR_DIMS]; + hsize_t fdims[NC_MAX_VAR_DIMS], fmaxdims[NC_MAX_VAR_DIMS]; + hsize_t start[NC_MAX_VAR_DIMS]; + int need_to_extend = 0; + int scalar = 0, retval = NC_NOERR, range_error = 0, i, d2; + void *bufr = NULL; +#ifndef HDF5_CONVERT + int need_to_convert = 0; + size_t len = 1; +#endif +#ifdef HDF5_CONVERT + hid_t mem_typeid = 0; +#endif + int no_data=0 ; + + /* Find our metadata for this file, group, and var. */ + assert(nc); + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; + h5 = nc->nc4_info; + assert(grp && h5 && var && var->name); + + LOG((3, "nc4_put_vara: var->name %s mem_nc_type %d is_long %d", + var->name, mem_nc_type, is_long)); + + /* Check some stuff about the type and the file. If the file must + * be switched from define mode, it happens here. */ + if ((retval = check_for_vara(&mem_nc_type, var, h5))) + return retval; + + /* Convert from size_t and ptrdiff_t to hssize_t, and hsize_t. */ + for (i = 0; i < var->ndims; i++) + { + start[i] = startp[i]; + count[i] = countp[i]; + } + + /* Open this dataset if necessary, also checking for a weird case: + * a non-coordinate (and non-scalar) variable that has the same + * name as a dimension. */ + if (var->hdf5_name && strlen(var->hdf5_name) >= strlen(NON_COORD_PREPEND) && + strncmp(var->hdf5_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND)) == 0 && + var->ndims) + if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->hdf5_name, + H5P_DEFAULT)) < 0) + return NC_ENOTVAR; + if (!var->hdf_datasetid) + if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name, + H5P_DEFAULT)) < 0) + return NC_ENOTVAR; + + /* Get file space of data. */ + if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + + /* Check to ensure the user selection is + * valid. H5Sget_simple_extent_dims gets the sizes of all the dims + * and put them in fdims. */ + if (H5Sget_simple_extent_dims(file_spaceid, fdims, fmaxdims) < 0) + BAIL(NC_EHDFERR); + +#ifdef LOGGING + log_dim_info(var, fdims, fmaxdims, start, count); +#endif + + /* Check dimension bounds. Remember that unlimited dimnsions can + * put data beyond their current length. */ + for (d2 = 0; d2 < var->ndims; d2++) + { + for (dim = grp->dim; dim; dim = dim->next) + { + if (dim->dimid == var->dimids[d2]) + { + if (!dim->unlimited) + { + if (start[d2] >= (hssize_t)fdims[d2]) + BAIL_QUIET(NC_EINVALCOORDS); + if (start[d2] + count[d2] > fdims[d2]) + BAIL_QUIET(NC_EEDGE); + } + } + } + } + + + /* A little quirk: if any of the count values are zero, then + return success and forget about it. */ + + for (d2 = 0; d2 < var->ndims; d2++) + if (count[d2] != 0) no_data++ ; +/* goto exit; */ + + /* Now you would think that no one would be crazy enough to write + a scalar dataspace with one of the array function calls, but you + would be wrong. So let's check to see if the dataset is + scalar. If it is, we won't try to set up a hyperslab. */ + if (H5Sget_simple_extent_type(file_spaceid) == H5S_SCALAR) + { + if ((mem_spaceid = H5Screate(H5S_SCALAR)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + scalar++; + } + else + { + if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET, start, NULL, + count, NULL) < 0) + BAIL(NC_EHDFERR); + + /* Create a space for the memory, just big enough to hold the slab + we want. */ + if ((mem_spaceid = H5Screate_simple(var->ndims, count, NULL)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + + /* Later on, we will need to know the size of this type in the + * file. */ + if ((retval = nc4_get_typelen_mem(h5, var->xtype, 0, &file_type_size))) + return retval; + +#ifndef HDF5_CONVERT + /* Are we going to convert any data? (No converting of compound or + * opaque types.) */ + if ((mem_nc_type != var->xtype || (var->xtype == NC_INT && is_long)) && + mem_nc_type != NC_COMPOUND && mem_nc_type != NC_OPAQUE) + { + /* We must convert - allocate a buffer. */ + need_to_convert++; + if (var->ndims) + for (d2=0; d2ndims; d2++) + len *= countp[d2]; + LOG((4, "converting data for var %s type=%d len=%d", var->name, + var->xtype, len)); + + /* If we're reading, we need bufr to have enough memory to store + * the data in the file. If we're writing, we need bufr to be + * big enough to hold all the data in the file's type. */ + if (!(bufr = malloc(len * file_type_size))) + BAIL(NC_ENOMEM); + } + else +#endif /* ifndef HDF5_CONVERT */ + bufr = data; + +#ifdef HDF5_CONVERT + /* Get the HDF type of the data in memory. */ + if ((retval = nc4_get_hdf_typeid(h5, mem_nc_type, &mem_typeid, + var->type_info->endianness))) + BAIL(retval); +#endif + + /* Create the data transfer property list. */ + if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif + + /* Apply the callback function which will detect range + * errors. Which one to call depends on the length of the + * destination buffer type. */ +#ifdef HDF5_CONVERT + if (H5Pset_type_conv_cb(xfer_plistid, except_func, &range_error) < 0) + BAIL(NC_EHDFERR); +#endif + +#ifdef USE_PARALLEL + /* Set up parallel I/O, if needed. */ + if ((retval = set_par_access(h5, var, xfer_plistid))) + BAIL(retval); +#endif + + /* Read/write this hyperslab into memory. */ + /* Does the dataset have to be extended? If it's already + extended to the required size, it will do no harm to reextend + it to that size. */ + if (var->ndims) + { + if (!(xtend_size = malloc(var->ndims * sizeof(hsize_t)))) + BAIL(NC_ENOMEM); + for (d2 = 0; d2 < var->ndims; d2++) + { + if ((retval = nc4_find_dim(grp, var->dimids[d2], &dim, NULL))) + BAIL(retval); + if (dim->unlimited) + { + if (start[d2] + count[d2] > fdims[d2]) + { + xtend_size[d2] = start[d2] + count[d2]; + need_to_extend++; + } + else + xtend_size[d2] = fdims[d2]; + + if (start[d2] + count[d2] > dim->len) + { + dim->len = start[d2] + count[d2]; + dim->extended++; + } + } + else + { + xtend_size[d2] = dim->len; + } + } + + /* If we need to extend it, we also need a new file_spaceid + to reflect the new size of the space. */ + if (need_to_extend) + { + LOG((4, "extending dataset")); + if (H5Dextend(var->hdf_datasetid, xtend_size) < 0) + BAIL(NC_EHDFERR); + if (file_spaceid > 0 && H5Sclose(file_spaceid) < 0) + BAIL2(NC_EHDFERR); + if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET, + start, NULL, count, NULL) < 0) + BAIL(NC_EHDFERR); + } + } + +#ifndef HDF5_CONVERT + /* Do we need to convert the data? */ + if (need_to_convert) + { + if ((retval = nc4_convert_type(data, bufr, mem_nc_type, var->xtype, + len, &range_error, var->fill_value, + (h5->cmode & NC_CLASSIC_MODEL), is_long, 0))) + BAIL(retval); + } +#endif + + /* Write the data. At last! */ + LOG((4, "about to H5Dwrite datasetid 0x%x mem_spaceid 0x%x " + "file_spaceid 0x%x", var->hdf_datasetid, mem_spaceid, file_spaceid)); +/* + if (no_data==0) + { + H5Sselect_none(mem_spaceid); + H5Sselect_none(file_spaceid); + bufr=NULL ; + } +*/ +/* if (no_data!=0) */ + if (H5Dwrite(var->hdf_datasetid, var->type_info->hdf_typeid, + mem_spaceid, file_spaceid, xfer_plistid, bufr) < 0) + BAIL(NC_EHDFERR); + + + /* Remember that we have written to this var so that Fill Value + * can't be set for it. */ + if (!var->written_to) + var->written_to++; + + /* For strict netcdf-3 rules, ignore erange errors between UBYTE + * and BYTE types. */ + if ((h5->cmode & NC_CLASSIC_MODEL) && + (var->xtype == NC_UBYTE || var->xtype == NC_BYTE) && + (mem_nc_type == NC_UBYTE || mem_nc_type == NC_BYTE) && + range_error) + range_error = 0; + + exit: + if (file_spaceid > 0 && H5Sclose(file_spaceid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (mem_spaceid > 0 && H5Sclose(mem_spaceid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (xfer_plistid && (H5Pclose(xfer_plistid) < 0)) + BAIL2(NC_EPARINIT); +#ifdef EXTRA_TESTS + num_plists--; +#endif +#ifndef HDF5_CONVERT + if (need_to_convert) free(bufr); +#endif + if (xtend_size) free(xtend_size); + + /* If there was an error return it, otherwise return any potential + range error value. If none, return NC_NOERR as usual.*/ + if (retval) + return retval; + if (range_error) + return NC_ERANGE; + return NC_NOERR; +} + +int +nc4_get_vara(NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp, + const size_t *countp, nc_type mem_nc_type, int is_long, void *data) +{ + NC_GRP_INFO_T *grp, *g; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim; + + hid_t file_spaceid = 0, mem_spaceid = 0; + hid_t xfer_plistid = 0; + hid_t hdf_datasetid; + size_t file_type_size; + + hsize_t *xtend_size = NULL, count[NC_MAX_VAR_DIMS]; + hsize_t fdims[NC_MAX_VAR_DIMS], fmaxdims[NC_MAX_VAR_DIMS]; + hsize_t start[NC_MAX_VAR_DIMS]; + void *fillvalue = NULL; + int no_read = 0, provide_fill = 0; + int fill_value_size[NC_MAX_VAR_DIMS]; + int scalar = 0, retval = NC_NOERR, range_error = 0, i, d2; + void *bufr = NULL; + int break_it; +#ifndef HDF5_CONVERT + int need_to_convert = 0; + size_t len = 1; +#endif + + /* Find our metadata for this file, group, and var. */ + assert(nc); + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; + h5 = nc->nc4_info; + assert(grp && h5 && var && var->name); + + LOG((3, "nc4_get_vara: var->name %s mem_nc_type %d is_long %d", + var->name, mem_nc_type, is_long)); + + /* Check some stuff about the type and the file. */ + if ((retval = check_for_vara(&mem_nc_type, var, h5))) + return retval; + + /* Convert from size_t and ptrdiff_t to hssize_t, and hsize_t. */ + for (i = 0; i < var->ndims; i++) + { + start[i] = startp[i]; + count[i] = countp[i]; + } + + /* Open this dataset if necessary, also checking for a weird case: + * a non-coordinate (and non-scalar) variable that has the same + * name as a dimension. */ + if (var->hdf5_name && strlen(var->hdf5_name) >= strlen(NON_COORD_PREPEND) && + strncmp(var->hdf5_name, NON_COORD_PREPEND, strlen(NON_COORD_PREPEND)) == 0 && + var->ndims) + if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->hdf5_name, + H5P_DEFAULT)) < 0) + return NC_ENOTVAR; + if (!var->hdf_datasetid) + if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name, + H5P_DEFAULT)) < 0) + return NC_ENOTVAR; + + /* Get file space of data. */ + if ((file_spaceid = H5Dget_space(var->hdf_datasetid)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + + /* Check to ensure the user selection is + * valid. H5Sget_simple_extent_dims gets the sizes of all the dims + * and put them in fdims. */ + if (H5Sget_simple_extent_dims(file_spaceid, fdims, fmaxdims) < 0) + BAIL(NC_EHDFERR); + +#ifdef LOGGING + log_dim_info(var, fdims, fmaxdims, start, count); +#endif + + /* Check dimension bounds. Remember that unlimited dimnsions can + * put data beyond their current length. */ + for (d2 = 0, break_it = 0; d2 < var->ndims; d2++) + { + for (g = grp; g && !break_it; g = g->parent) + for (dim = g->dim; dim; dim = dim->next) + { + if (dim->dimid == var->dimids[d2]) + { + if (!dim->unlimited) + { + if (start[d2] >= (hssize_t)fdims[d2]) + BAIL_QUIET(NC_EINVALCOORDS); + if (start[d2] + count[d2] > fdims[d2]) + BAIL_QUIET(NC_EEDGE); + } + if (dim->unlimited) + { + size_t ulen; + + /* We can't go beyond the latgest current extent of + the unlimited dim. */ + if ((retval = nc_inq_dimlen(ncid, dim->dimid, &ulen))) + BAIL(retval); + + /* Check for out of bound requests. */ + if (start[d2] >= (hssize_t)ulen && count[d2]) + BAIL_QUIET(NC_EINVALCOORDS); + if (start[d2] + count[d2] > ulen) + BAIL_QUIET(NC_EEDGE); + + /* THings get a little tricky here. If we're getting + a GET request beyond the end of this var's + current length in an unlimited dimension, we'll + later need to return the fill value for the + variable. */ + if (start[d2] >= (hssize_t)fdims[d2]) + fill_value_size[d2] = count[d2]; + else if (start[d2] + count[d2] > fdims[d2]) + fill_value_size[d2] = count[d2] - (fdims[d2] - start[d2]); + else + fill_value_size[d2] = 0; + count[d2] -= fill_value_size[d2]; + if (fill_value_size[d2]) + provide_fill++; + } + else + fill_value_size[d2] = count[d2]; + } + } + } + + /* A little quirk: if any of the count values are zero, don't + * read. */ + for (d2 = 0; d2 < var->ndims; d2++) + if (count[d2] == 0) + no_read++; + + /* Later on, we will need to know the size of this type in the + * file. */ + if ((retval = nc4_get_typelen_mem(h5, var->xtype, 0, &file_type_size))) + return retval; + + if (!no_read) + { + /* Now you would think that no one would be crazy enough to write + a scalar dataspace with one of the array function calls, but you + would be wrong. So let's check to see if the dataset is + scalar. If it is, we won't try to set up a hyperslab. */ + if (H5Sget_simple_extent_type(file_spaceid) == H5S_SCALAR) + { + if ((mem_spaceid = H5Screate(H5S_SCALAR)) < 0) + BAIL(NC_EHDFERR); + scalar++; +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + else + { + if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET, + start, NULL, count, NULL) < 0) + BAIL(NC_EHDFERR); + /* Create a space for the memory, just big enough to hold the slab + we want. */ + if ((mem_spaceid = H5Screate_simple(var->ndims, count, NULL)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + + /* Fix bug when reading HDF5 files with variable of type + * fixed-length string. We need to make it look like a + * variable-length string, because that's all netCDF-4 data + * model supports, lacking anonymous dimensions. So + * variable-length strings are in allocated memory that user has + * to free, which we allocate here. */ + if(var->type_info->class == H5T_STRING && + H5Tget_size(var->type_info->hdf_typeid) > 1 && + !H5Tis_variable_str(var->type_info->hdf_typeid)) { + hsize_t fstring_len; + if ((fstring_len = H5Tget_size(var->type_info->hdf_typeid)) < 0) + BAIL(NC_EHDFERR); + if (!(*(char **)data = malloc(1 + fstring_len))) + BAIL(NC_ENOMEM); + bufr = *(char **)data; + } + +#ifndef HDF5_CONVERT + /* Are we going to convert any data? (No converting of compound or + * opaque types.) */ + if ((mem_nc_type != var->xtype || (var->xtype == NC_INT && is_long)) && + mem_nc_type != NC_COMPOUND && mem_nc_type != NC_OPAQUE) + { + /* We must convert - allocate a buffer. */ + need_to_convert++; + if (var->ndims) + for (d2 = 0; d2 < var->ndims; d2++) + len *= countp[d2]; + LOG((4, "converting data for var %s type=%d len=%d", var->name, + var->xtype, len)); + + /* If we're reading, we need bufr to have enough memory to store + * the data in the file. If we're writing, we need bufr to be + * big enough to hold all the data in the file's type. */ + if (!(bufr = malloc(len * file_type_size))) + BAIL(NC_ENOMEM); + } + else +#endif /* ifndef HDF5_CONVERT */ + if(!bufr) + bufr = data; + + /* Get the HDF type of the data in memory. */ +#ifdef HDF5_CONVERT + if ((retval = nc4_get_hdf_typeid(h5, mem_nc_type, &mem_typeid, + var->type_info->endianness))) + BAIL(retval); +#endif + + /* Create the data transfer property list. */ + if ((xfer_plistid = H5Pcreate(H5P_DATASET_XFER)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif + +#ifdef HDF5_CONVERT + /* Apply the callback function which will detect range + * errors. Which one to call depends on the length of the + * destination buffer type. */ + if (H5Pset_type_conv_cb(xfer_plistid, except_func, &range_error) < 0) + BAIL(NC_EHDFERR); +#endif + +#ifdef USE_PARALLEL + /* Set up parallel I/O, if needed. */ + if ((retval = set_par_access(h5, var, xfer_plistid))) + BAIL(retval); +#endif + + /* Read this hyperslab into memory. */ + LOG((5, "About to H5Dread some data...")); + if (H5Dread(var->hdf_datasetid, var->type_info->native_typeid, + mem_spaceid, file_spaceid, xfer_plistid, bufr) < 0) + BAIL(NC_EHDFERR); + +#ifndef HDF5_CONVERT + /* Eventually the block below will go away. Right now it's + needed to support conversions between int/float, and range + checking converted data in the netcdf way. These features are + being added to HDF5 at the HDF5 World Hall of Coding right + now, by a staff of thousands of programming gnomes. */ + if (need_to_convert) + { + if ((retval = nc4_convert_type(bufr, data, var->xtype, mem_nc_type, + len, &range_error, var->fill_value, + (h5->cmode & NC_CLASSIC_MODEL), 0, is_long))) + BAIL(retval); + + /* For strict netcdf-3 rules, ignore erange errors between UBYTE + * and BYTE types. */ + if ((h5->cmode & NC_CLASSIC_MODEL) && + (var->xtype == NC_UBYTE || var->xtype == NC_BYTE) && + (mem_nc_type == NC_UBYTE || mem_nc_type == NC_BYTE) && + range_error) + range_error = 0; + } +#endif + + /* For strict netcdf-3 rules, ignore erange errors between UBYTE + * and BYTE types. */ + if ((h5->cmode & NC_CLASSIC_MODEL) && + (var->xtype == NC_UBYTE || var->xtype == NC_BYTE) && + (mem_nc_type == NC_UBYTE || mem_nc_type == NC_BYTE) && + range_error) + range_error = 0; + + } /* endif ! no_read */ + + /* Now we need to fake up any further data that was asked for, + using the fill values instead. First skip past the data we + just read, if any. */ + if (!scalar && provide_fill) + { + void *filldata; + size_t real_data_size = 0; + size_t fill_len; + + /* Skip past the real data we've already read. */ + if (!no_read) + for (real_data_size = file_type_size, d2 = 0; d2 < var->ndims; d2++) + real_data_size *= (count[d2] - start[d2]); + + /* Get the fill value from the HDF5 variable. Memory will be + * allocated. */ + if (get_fill_value(h5, var, &fillvalue) < 0) + BAIL(NC_EHDFERR); + + /* How many fill values do we need? */ + for (fill_len = 1, d2 = 0; d2 < var->ndims; d2++) + fill_len *= (fill_value_size[d2] ? fill_value_size[d2] : 1); + + /* Copy the fill value into the rest of the data buffer. */ + filldata = (char *)data + real_data_size; + for (i = 0; i < fill_len; i++) + { + if (var->xtype == NC_STRING) + { + if (!(*(char **)filldata = malloc(sizeof(*(char **)fillvalue)))) + return NC_ENOMEM; + strcpy(*(char **)filldata, *(char **)fillvalue); + } + else + { + memcpy(filldata, fillvalue, file_type_size); + filldata = (char *)filldata + file_type_size; + } + } + } + + exit: +/** if (var->xtype == NC_CHAR && mem_typeid > 0 && H5Tclose(mem_typeid) < 0) + BAIL2(NC_EHDFERR);*/ + if (file_spaceid > 0) + { + if (H5Sclose(file_spaceid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + } + if (mem_spaceid > 0) + { + if (H5Sclose(mem_spaceid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + } + if (xfer_plistid > 0) + { + if (H5Pclose(xfer_plistid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; +#endif + } +#ifndef HDF5_CONVERT + if (need_to_convert) + free(bufr); +#endif + if (xtend_size) + free(xtend_size); + if (fillvalue) + { + if (var->xtype == NC_STRING) + { + if (nc_free_string(1, (char **)fillvalue)) + return NC_ENOMEM; + } + else + free(fillvalue); + } + + /* If there was an error return it, otherwise return any potential + range error value. If none, return NC_NOERR as usual.*/ + if (retval) + return retval; + if (range_error) + return NC_ERANGE; + return NC_NOERR; +} + +/* This function is a bit of a hack. Turns out that HDF5 dimension + * scales cannot themselves have scales attached. This leaves + * multidimensional coordinate variables hosed. So this function + * writes a special attribute for such a variable, which has the ids + * of all the dimensions for that coordinate variable. This sucks, + * really. But that's the way the cookie crumbles. Better luck next + * time. This function also contains a new way of dealing with HDF5 + * error handling, abandoning the BAIL macros for a more organic and + * natural approach, made with whole grains, and locally-grown + * vegetables. */ +static int +write_coord_dimids(NC_VAR_INFO_T *var) +{ + hsize_t coords_len[1]; + hid_t c_spaceid = -1, c_attid = -1; + int ret = 0; + + /* Write our attribute. */ + coords_len[0] = var->ndims; + if ((c_spaceid = H5Screate_simple(1, coords_len, coords_len)) < 0) ret++; +#ifdef EXTRA_TESTS + num_spaces++; +#endif + if (!ret && (c_attid = H5Acreate(var->hdf_datasetid, COORDINATES, H5T_NATIVE_INT, + c_spaceid, H5P_DEFAULT)) < 0) ret++; + if (!ret && H5Awrite(c_attid, H5T_NATIVE_INT, var->dimids) < 0) ret++; + + /* Close up shop. */ + if (c_spaceid > 0 && H5Sclose(c_spaceid) < 0) ret++; +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (c_attid > 0 && H5Aclose(c_attid) < 0) ret++; + return ret ? NC_EHDFERR : 0; +} + +/* Write a special attribute for the netCDF-4 dimension ID. */ +static int +write_netcdf4_dimid(hid_t datasetid, int dimid) +{ + hid_t dimid_spaceid, dimid_attid; + + /* Create the space. */ + if ((dimid_spaceid = H5Screate(H5S_SCALAR)) < 0) + return NC_EHDFERR; +#ifdef EXTRA_TESTS + num_spaces++; +#endif + + /* Does the attribute already exist? If so, don't try to create it. */ + H5E_BEGIN_TRY { + dimid_attid = H5Aopen_by_name(datasetid, ".", NC_DIMID_ATT_NAME, + H5P_DEFAULT, H5P_DEFAULT); + } H5E_END_TRY; + + /* Create the attribute if needed. */ + if (dimid_attid < 0) + if ((dimid_attid = H5Acreate(datasetid, NC_DIMID_ATT_NAME, + H5T_NATIVE_INT, dimid_spaceid, H5P_DEFAULT)) < 0) + return NC_EHDFERR; + + /* Write it. */ + LOG((4, "write_netcdf4_dimid: writting secret dimid %d", dimid)); + if (H5Awrite(dimid_attid, H5T_NATIVE_INT, &dimid) < 0) + return NC_EHDFERR; + + /* Close stuff*/ + if (H5Sclose(dimid_spaceid) < 0) + return NC_EHDFERR; +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (H5Aclose(dimid_attid) < 0) + return NC_EHDFERR; + + return NC_NOERR; +} + +/* This function creates the HDF5 dataset for a variabale. */ +static int +var_create_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, int write_dimid) +{ + NC_GRP_INFO_T *g; + hid_t plistid = 0, access_plistid = 0, typeid = 0, spaceid = 0; + hsize_t *chunksize = NULL, *dimsize = NULL, *maxdimsize = NULL; + int d; + NC_DIM_INFO_T *dim = NULL; + void *fillp = NULL; + int dims_found = 0; + int set_chunksizes = 0; + char *name_to_use; + int retval = NC_NOERR; + + LOG((3, "var_create_dataset: name %s", var->name)); + + /* Scalar or not, we need a creation property list. */ + if ((plistid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif + if ((access_plistid = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif + + /* Find the HDF5 type of the dataset. */ + if ((retval = nc4_get_hdf_typeid(grp->file->nc4_info, var->xtype, &typeid, + var->type_info->endianness))) + BAIL(retval); + + /* Figure out what fill value to set, if any. */ + if (!var->no_fill) + { + if ((retval = get_fill_value(grp->file->nc4_info, var, &fillp))) + BAIL(retval); + + /* If there is a fill value, set it. */ + if (fillp) + { + if (var->xtype == NC_STRING) + { + if (H5Pset_fill_value(plistid, typeid, &fillp) < 0) + BAIL(NC_EHDFERR); + free((char *)fillp); + } + else + { + /* The fill value set in HDF5 must always be presented as + * a native type, even if the endianness for this dataset + * is non-native. HDF5 will translate the fill value to + * the target endiannesss. */ + hid_t fill_typeid; + if ((retval = nc4_get_hdf_typeid(grp->file->nc4_info, var->xtype, &fill_typeid, + NC_ENDIAN_NATIVE))) + BAIL(retval); + if (H5Pset_fill_value(plistid, fill_typeid, fillp) < 0) + BAIL(NC_EHDFERR); + if (var->type_info->class == NC_VLEN) + nc_free_vlen((nc_vlen_t *)fillp); + else + free(fillp); + if (var->type_info->nc_typeid == NC_STRING || var->type_info->nc_typeid == NC_CHAR) + if (H5Tclose(fill_typeid) < 0) + BAIL(NC_EHDFERR); + } + } + } else { + /* Required to truly turn HDF5 fill values off */ + if(H5Pset_fill_time(plistid,H5D_FILL_TIME_NEVER) < 0) + BAIL(NC_EHDFERR); + } + + /* If the user wants to shuffle the data, set that up now. */ + if (var->shuffle) + if (H5Pset_shuffle(plistid) < 0) + BAIL(NC_EHDFERR); + + /* If the user wants to deflate the data, set that up now. */ + if (var->deflate) + if (H5Pset_deflate(plistid, var->deflate_level) < 0) + BAIL(NC_EHDFERR); + + /* Szip? NO! We don't want anyone to produce szipped netCDF files! */ +/* #ifdef USE_SZIP */ +/* if (var->options_mask) */ +/* if (H5Pset_szip(plistid, var->options_mask, var->bits_per_pixel) < 0) */ +/* BAIL(NC_EHDFERR); */ +/* #endif */ + + /* If the user wants to fletcher error correcton, set that up now. */ + if (var->fletcher32) + if (H5Pset_fletcher32(plistid) < 0) + BAIL(NC_EHDFERR); + + /* If ndims non-zero, get info for all dimensions. We look up the + dimids and get the len of each dimension. We need this to create + the space for the dataset. In netCDF a dimension length of zero + means an unlimited dimension. */ + if (var->ndims) + { + int unlimdim = 0; + + /* Check to see if any unlimited dimensions are used in this var. */ + for (d = 0; d < var->ndims; d++) + if (var->dim[d]->unlimited) + unlimdim++; + + /* If there are no unlimited dims, and no filters, and the user + * has not specified chunksizes, use contiguous variable for + * better performance. */ + if (!unlimdim && !var->shuffle && !var->deflate && !var->options_mask && + !var->fletcher32 && !var->chunksizes[0]) + var->contiguous = 1; + + if (!(dimsize = malloc(var->ndims * sizeof(hsize_t)))) + BAIL(NC_ENOMEM); + if (!(maxdimsize = malloc(var->ndims * sizeof(hsize_t)))) + BAIL(NC_ENOMEM); + if (!(chunksize = malloc(var->ndims * sizeof(hsize_t)))) + BAIL(NC_ENOMEM); +/* for (d = 0; d < var->ndims; d++) + dimsize[d] = var->dim[d]->unlimited ? NC_HDF5_UNLIMITED_DIMSIZE : var->dim[d]->len; + maxdimsize[d] = var->dim[d]->unlimited ? H5S_UNLIMITED : (hsize_t)var->dim[d]->len; + chunksize[d] = var->chunksizes[d];*/ + + for (d = 0; d < var->ndims; d++) + for (g = grp; g && (dims_found < var->ndims); g = g->parent) + for (dim = g->dim; dim; dim = dim->next) + if (dim->dimid == var->dimids[d]) + { + dimsize[d] = dim->unlimited ? NC_HDF5_UNLIMITED_DIMSIZE : dim->len; + maxdimsize[d] = dim->unlimited ? H5S_UNLIMITED : (hsize_t)dim->len; + if (var->chunksizes[d]) + chunksize[d] = var->chunksizes[d]; + else + { + size_t type_size; + if (var->type_info->nc_typeid == NC_STRING) + type_size = sizeof(char *); + else + type_size = var->type_info->size; + + /* Unlimited dim always gets chunksize of 1. */ + if (dim->unlimited) + chunksize[d] = 1; + else + chunksize[d] = pow((double)DEFAULT_CHUNK_SIZE/type_size, + 1/(double)(var->ndims - unlimdim)); + + /* If the chunksize is greater than the dim + * length, make it the dim length. */ + if (!dim->unlimited && chunksize[d] > dim->len) + chunksize[d] = dim->len; + set_chunksizes++; + } + + if (!var->contiguous && !var->chunksizes[d]) + var->chunksizes[d] = chunksize[d]; + dims_found++; + break; + } + + if (var->contiguous) + { + if (H5Pset_layout(plistid, H5D_CONTIGUOUS) < 0) + BAIL(NC_EHDFERR); + } + else + { + if (H5Pset_chunk(plistid, var->ndims, chunksize) < 0) + BAIL(NC_EHDFERR); + } + + /* Create the dataspace. */ + if ((spaceid = H5Screate_simple(var->ndims, dimsize, maxdimsize)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + else + { + if ((spaceid = H5Screate(H5S_SCALAR)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + + /* Turn on creation order tracking. */ + if (H5Pset_attr_creation_order(plistid, H5P_CRT_ORDER_TRACKED| + H5P_CRT_ORDER_INDEXED) < 0) + BAIL(NC_EHDFERR); + + /* Set per-var chunk cache. */ + if (var->chunk_cache_size) + if (H5Pset_chunk_cache(access_plistid, var->chunk_cache_nelems, + var->chunk_cache_size, var->chunk_cache_preemption) < 0) + BAIL(NC_EHDFERR); + + /* At long last, create the dataset. */ + name_to_use = var->hdf5_name ? var->hdf5_name : var->name; + LOG((4, "var_create_dataset: about to H5Dcreate dataset %s of type 0x%x", + name_to_use, typeid)); + if ((var->hdf_datasetid = H5Dcreate2(grp->hdf_grpid, name_to_use, typeid, + spaceid, H5P_DEFAULT, plistid, access_plistid)) < 0) + BAIL(NC_EHDFERR); + var->created++; + var->dirty = 0; + + /* If this is a dimscale, mark it as such in the HDF5 file. Also + * find the dimension info and store the dataset id of the dimscale + * dataset. */ + if (var->dimscale) + { + if (H5DSset_scale(var->hdf_datasetid, var->name) < 0) + BAIL(NC_EHDFERR); + for (dim = grp->dim; dim; dim = dim->next) + if (strcmp(dim->name, var->name) == 0) + { + dim->hdf_dimscaleid = var->hdf_datasetid; + break; + } + + /* Make sure we found a dimension, and gave it a dimscale id. */ + if (!dim || !dim->hdf_dimscaleid) + BAIL(NC_EDIMMETA); + + /* If this is a multidimensional coordinate variable, write a + * coordinates attribute. */ + if (var->ndims > 1) + if ((retval = write_coord_dimids(var))) + BAIL(retval); + + /* If desired, write the netCDF dimid. */ + if (write_dimid) + if ((retval = write_netcdf4_dimid(var->hdf_datasetid, + var->dimids[0]))) + BAIL(retval); + + } + + exit: + if (var->type_info->nc_typeid == NC_STRING || var->type_info->nc_typeid == NC_CHAR) + if (typeid > 0 && H5Tclose(typeid) < 0) + BAIL2(NC_EHDFERR); + if (plistid > 0 && H5Pclose(plistid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; +#endif + if (access_plistid > 0 && H5Pclose(access_plistid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; +#endif + if (spaceid > 0 && H5Sclose(spaceid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (maxdimsize) free(maxdimsize); + if (dimsize) free(dimsize); + if (chunksize) free(chunksize); + return retval; +} + +/* Adjust the chunk cache of a var for better performance. */ +int +nc4_adjust_var_cache(NC_GRP_INFO_T *grp, NC_VAR_INFO_T * var) +{ + size_t chunk_size_bytes = 1; + int d; + int retval; + + /* Nothing to be done. */ + if (var->contiguous) + return NC_NOERR; +#ifdef USE_PARALLEL + return NC_NOERR; +#endif + + /* How many bytes in the chunk? */ + for (d = 0; d < var->ndims; d++) + chunk_size_bytes *= var->chunksizes[d]; + if (var->type_info->size) + chunk_size_bytes *= var->type_info->size; + else + chunk_size_bytes *= sizeof(char *); + + /* If the chunk cache is too small, and the user has not changed + * the default value of the chunk cache size, then increase the + * size of the cache. */ + if (var->chunk_cache_size == CHUNK_CACHE_SIZE) + if (chunk_size_bytes > var->chunk_cache_size) + { + var->chunk_cache_size = chunk_size_bytes * DEFAULT_CHUNKS_IN_CACHE; + if (var->chunk_cache_size > MAX_DEFAULT_CACHE_SIZE) + var->chunk_cache_size = MAX_DEFAULT_CACHE_SIZE; + if ((retval = nc4_reopen_dataset(grp, var))) + return retval; + } + + return NC_NOERR; +} + +/* Read or write an attribute. */ +static int +put_att_grpa(NC_GRP_INFO_T *grp, int varid, NC_ATT_INFO_T *att) +{ + hid_t datasetid = 0, locid; + hid_t attid = 0, spaceid = 0, file_typeid = 0; + hsize_t dims[1]; /* netcdf attributes always 1-D. */ + int retval = NC_NOERR; + void *data; + int phoney_data = 99; + + assert(att->name); + LOG((3, "put_att_grpa: varid %d att->attnum %d att->name %s " + "att->xtype %d att->len %d", varid, att->attnum, att->name, + att->xtype, att->len)); + + /* If the file is read-only, return an error. */ + if (grp->file->nc4_info->no_write) + return NC_EPERM; + + /* Get the hid to attach the attribute to, or read it from. */ + if (varid == NC_GLOBAL) + locid = grp->hdf_grpid; + else + { + if ((retval = nc4_open_var_grp2(grp, varid, &datasetid))) + BAIL(retval); + locid = datasetid; + } + + /* Delete the att if it exists already. */ + H5E_BEGIN_TRY { + H5Adelete(locid, att->name); + } H5E_END_TRY; + + /* Get the length ready, and find the HDF type we'll be + * writing. */ + dims[0] = att->len; + if ((retval = nc4_get_hdf_typeid(grp->file->nc4_info, att->xtype, + &file_typeid, 0))) + BAIL(retval); + + /* Even if the length is zero, HDF5 won't let me write with a + * NULL pointer. So if the length of the att is zero, point to + * some phoney data (which won't be written anyway.)*/ + if (!dims[0]) + data = &phoney_data; + else if (att->data) + data = att->data; + else if (att->stdata) + data = att->stdata; + else + data = att->vldata; + + /* NC_CHAR types require some extra work. The space ID is set to + * scalar, and the type is told how long the string is. If it's + * really zero length, set the size to 1. (The fact that it's + * really zero will be marked by the NULL dataspace, but HDF5 + * doesn't allow me to set the size of the type to zero.)*/ + if (att->xtype == NC_CHAR) + { + size_t string_size = dims[0]; + if (!string_size) + { + string_size = 1; + if ((spaceid = H5Screate(H5S_NULL)) < 0) + BAIL(NC_EATTMETA); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + else + { + if ((spaceid = H5Screate(H5S_SCALAR)) < 0) + BAIL(NC_EATTMETA); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + if (H5Tset_size(file_typeid, string_size) < 0) + BAIL(NC_EATTMETA); + if (H5Tset_strpad(file_typeid, H5T_STR_NULLTERM) < 0) + BAIL(NC_EATTMETA); + } + else + { + if (!att->len) + { + if ((spaceid = H5Screate(H5S_NULL)) < 0) + BAIL(NC_EATTMETA); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + else + { + if ((spaceid = H5Screate_simple(1, dims, NULL)) < 0) + BAIL(NC_EATTMETA); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + } + } + if ((attid = H5Acreate(locid, att->name, file_typeid, spaceid, + H5P_DEFAULT)) < 0) + BAIL(NC_EATTMETA); + + /* Write the values, (even if length is zero). */ + if (H5Awrite(attid, file_typeid, data) < 0) + BAIL(NC_EATTMETA); + + exit: + if (att->xtype == NC_CHAR || att->xtype == NC_STRING) + if (file_typeid && H5Tclose(file_typeid)) + BAIL2(NC_EHDFERR); + if (attid > 0 && H5Aclose(attid) < 0) + BAIL2(NC_EHDFERR); + if (spaceid > 0 && H5Sclose(spaceid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + return retval; +} + +/* Create a HDF5 defined type from a NC_TYPE_INFO_T struct, and commit + * it to the file. */ +static int +commit_type(NC_GRP_INFO_T *grp, NC_TYPE_INFO_T *type) +{ + NC_FIELD_INFO_T *field; + NC_ENUM_MEMBER_INFO_T *enum_m; + hid_t hdf_base_typeid, hdf_typeid; + int retval; + + assert(grp && type); + + /* Did we already record this type? */ + if (type->committed) + return NC_NOERR; + + /* Is this a compound type? */ + if (type->class == NC_COMPOUND) + { + if ((type->hdf_typeid = H5Tcreate(H5T_COMPOUND, type->size)) < 0) + return NC_EHDFERR; + LOG((4, "creating compound type %s hdf_typeid 0x%x", type->name, + type->hdf_typeid)); + for (field = type->field; field; field = field->next) + { + if ((retval = nc4_get_hdf_typeid(grp->file->nc4_info, field->nctype, + &hdf_base_typeid, type->endianness))) + return retval; + /* If this is an array, create a special array type. */ + if (field->ndims) + { + int d; + hsize_t dims[NC_MAX_DIMS]; + for (d = 0; d < field->ndims; d++) + dims[d] = field->dim_size[d]; + if ((hdf_typeid = H5Tarray_create(hdf_base_typeid, field->ndims, + dims, NULL)) < 0) + return NC_EHDFERR; + } + else + hdf_typeid = hdf_base_typeid; + LOG((4, "inserting field %s offset %d hdf_typeid 0x%x", field->name, + field->offset, hdf_typeid)); + if (H5Tinsert(type->hdf_typeid, field->name, field->offset, + hdf_typeid) < 0) + return NC_EHDFERR; + if (field->ndims && H5Tclose(hdf_typeid) < 0) + return NC_EHDFERR; + } + } + else if (type->class == NC_VLEN) + { + /* Find the HDF typeid of the base type of this vlen. */ + if ((retval = nc4_get_hdf_typeid(grp->file->nc4_info, type->base_nc_type, + &type->base_hdf_typeid, type->endianness))) + return retval; + + /* Create a vlen type. */ + if ((type->hdf_typeid = H5Tvlen_create(type->base_hdf_typeid)) < 0) + return NC_EHDFERR; + } + else if (type->class == NC_OPAQUE) + { + /* Create the opaque type. */ + if ((type->hdf_typeid = H5Tcreate(H5T_OPAQUE, type->size)) < 0) + return NC_EHDFERR; + } + else if (type->class == NC_ENUM) + { + if (!type->enum_member) + return NC_EINVAL; + + /* Find the HDF typeid of the base type of this enum. */ + if ((retval = nc4_get_hdf_typeid(grp->file->nc4_info, type->base_nc_type, + &type->base_hdf_typeid, type->endianness))) + return retval; + + /* Create an enum type. */ + if ((type->hdf_typeid = H5Tenum_create(type->base_hdf_typeid)) < 0) + return NC_EHDFERR; + + /* Add all the members to the HDF5 type. */ + for (enum_m = type->enum_member; enum_m; enum_m = enum_m->next) + if (H5Tenum_insert(type->hdf_typeid, enum_m->name, + enum_m->value) < 0) + return NC_EHDFERR; + } + else + { + LOG((0, "Unknown class: %d", type->class)); + return NC_EBADTYPE; + } + + /* Commit the type. */ + if (H5Tcommit(grp->hdf_grpid, type->name, type->hdf_typeid) < 0) + return NC_EHDFERR; + type->committed++; + LOG((4, "just committed type %s, HDF typeid: 0x%x", type->name, + type->hdf_typeid)); + + /* Later we will always use the native typeid. In this case, it is + * a copy of the same type pointed to by hdf_typeid, but it's + * easier to maintain a copy. */ + if ((type->native_typeid = H5Tget_native_type(type->hdf_typeid, + H5T_DIR_DEFAULT)) < 0) + return NC_EHDFERR; + + return NC_NOERR; +} + +/* Write an attribute, with value 1, to indicate that strict NC3 rules + * apply to this file. */ +static int +write_nc3_strict_att(hid_t hdf_grpid) +{ + hid_t attid = 0, spaceid = 0; + int one = 1, num, a; + char att_name[NC_MAX_NAME + 1]; + int retval = NC_NOERR; + + /* If the attribute already exists, call that a success and return + * NC_NOERR. */ + if ((num = H5Aget_num_attrs(hdf_grpid)) < 0) + return NC_EHDFERR; + for (a = 0; a < num; a++) + { + if ((attid = H5Aopen_idx(hdf_grpid, (unsigned int)a)) < 0) + BAIL(NC_EHDFERR); + if (H5Aget_name(attid, NC_MAX_HDF5_NAME, att_name) < 0) + BAIL(NC_EHDFERR); + if (!strcmp(att_name, NC3_STRICT_ATT_NAME)) + { + if (H5Aclose(attid) < 0) + return NC_EFILEMETA; + return NC_NOERR; + } + } + + /* Create the attribute to mark this as a file that needs to obey + * strict netcdf-3 rules. */ + if ((spaceid = H5Screate(H5S_SCALAR)) < 0) + BAIL(NC_EFILEMETA); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + if ((attid = H5Acreate(hdf_grpid, NC3_STRICT_ATT_NAME, + H5T_NATIVE_INT, spaceid, H5P_DEFAULT)) < 0) + BAIL(NC_EFILEMETA); + if (H5Awrite(attid, H5T_NATIVE_INT, &one) < 0) + BAIL(NC_EFILEMETA); + + exit: + if (spaceid && (H5Sclose(spaceid) < 0)) + BAIL2(NC_EFILEMETA); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (attid && (H5Aclose(attid) < 0)) + BAIL2(NC_EFILEMETA); + return retval; +} + +static int +create_group(NC_GRP_INFO_T *grp) +{ + hid_t gcpl_id = 0; + int retval = NC_NOERR;; + + assert(grp); + + /* If this is not the root group, create it in the HDF5 file. */ + if (grp->parent) + { + /* Create group, with link_creation_order set in the group + * creation property list. */ + if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) + return NC_EHDFERR; +#ifdef EXTRA_TESTS + num_plists++; +#endif + if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED|H5P_CRT_ORDER_INDEXED) < 0) + BAIL(NC_EHDFERR); + if (H5Pset_attr_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED|H5P_CRT_ORDER_INDEXED) < 0) + BAIL(NC_EHDFERR); + if ((grp->hdf_grpid = H5Gcreate2(grp->parent->hdf_grpid, grp->name, + H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) + BAIL(NC_EHDFERR); + if (H5Pclose(gcpl_id) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; +#endif + } + else + { + /* Since this is the root group, we have to open it. */ + if ((grp->hdf_grpid = H5Gopen2(grp->file->nc4_info->hdfid, "/", H5P_DEFAULT)) < 0) + BAIL(NC_EFILEMETA); + } + return NC_NOERR; + + exit: + if (gcpl_id > 0 && H5Pclose(gcpl_id) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; +#endif + if (grp->hdf_grpid > 0 && H5Gclose(grp->hdf_grpid) < 0) + BAIL2(NC_EHDFERR); + return retval; +} + +/* After all the datasets of the file have been read, it's time to + * sort the wheat from the chaff. Which of the datasets are netCDF + * dimensions, and which are coordinate variables, and which are + * non-coordinate variables. */ +static int +attach_dimscales(NC_GRP_INFO_T *grp) +{ + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim1; + NC_GRP_INFO_T *g; + int d; + int retval = NC_NOERR; + + /* Attach dimension scales. */ + for (var = grp->var; var; var = var->next) + { + /* Scales themselves do not attach. But I really wish they + * would. */ + if (var->dimscale) + { + /* If this is a multidimensional coordinate variable, it will + * have a special coords attribute (read earlier) with a list + * of the dimensions for this variable. */ + } + else /* not a dimscale... */ + { + /* Find the scale for each dimension and attach it. */ + for (d = 0; d < var->ndims; d++) + { + /* Is there a dimscale for this dimension? */ + if (var->dimscale_attached) + { + if (!var->dimscale_attached[d]) + { + for (g = grp; g && !var->dimscale_attached[d]; g = g->parent) + for (dim1 = g->dim; dim1; dim1 = dim1->next) + if (var->dimids[d] == dim1->dimid) + { + LOG((2, "attach_dimscales: attaching scale for dimid %d to var %s", + var->dimids[d], var->name)); + if (H5DSattach_scale(var->hdf_datasetid, dim1->hdf_dimscaleid, d) < 0) + BAIL(NC_EHDFERR); + var->dimscale_attached[d]++; + break; + } + } + + /* If we didn't find a dimscale to attach, that's a problem! */ + if (!var->dimscale_attached[d]) + { + LOG((0, "no dimscale found!")); + return NC_EDIMSCALE; + } + } + else + { + /* Create a phoney dimension! */ + + } + } + } /* next d */ + } + exit: + return retval; +} + +/* Write all the dirty atts in an attlist. */ +static int +write_attlist(NC_ATT_INFO_T *attlist, int varid, NC_GRP_INFO_T *grp) +{ + NC_ATT_INFO_T *att; + int retval; + + for (att = attlist; att; att = att->next) + { + if (att->dirty) + { + LOG((4, "write_attlist: writing att %s to varid %d", att->name, varid)); + if ((retval = put_att_grpa(grp, varid, att))) + return retval; + att->dirty = 0; + att->created++; + } + } + return NC_NOERR; +} + +/* Using the HDF5 group iterator is more efficient than the original + * code (O(n) vs O(n**2) for n variables in the group) */ +#define USE_ITERATE_CODE +#ifdef USE_ITERATE_CODE +typedef struct { + char *name; /* The name of the object to searched*/ + int *exists; /* 1 if the object exists, 0 otherswise */ +} var_exists_iter_info; + +/*------------------------------------------------------------------------- + * Function: var_exists_cb + * + * Purpose: Callback routine for checking an object by its name + * + * Return: Exist: 1 + * Not exist: 0 + * Failure: -1 + * + * Programmer: Peter Cao + * 1/25/2012 + * + *------------------------------------------------------------------------- + */ +static int +var_exists_cb(hid_t grpid, const char *name, const H5L_info_t *info, + void *_op_data) +{ + var_exists_iter_info *iter_info = (var_exists_iter_info *)_op_data; + H5I_type_t otype; + hid_t oid; + + if ((oid = H5Oopen(grpid, name, H5P_DEFAULT)) < 0) + return H5_ITER_STOP; + + if ((otype = H5Iget_type( oid ))<0) { + H5Oclose(oid); + return H5_ITER_STOP; + } + H5Oclose(oid); + + if (otype == H5I_DATASET) { + if (!strcmp(iter_info->name, name)) { + *(iter_info->exists) = 1; + return (H5_ITER_STOP); + } + } + + return (H5_ITER_CONT); +} /* end var_exists_cb() */ + +static int +var_exists(hid_t grpid, char *name, int *exists) +{ + hsize_t num_obj; + var_exists_iter_info iter_info; + iter_info.name = name; + iter_info.exists = exists; + + if (H5Gget_num_objs(grpid, &num_obj) < 0) + return NC_EVARMETA; + + if (!name) + return NC_NOERR; + + *exists = 0; + if (H5Literate(grpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, var_exists_cb, &iter_info) < 0) + return NC_EHDFERR; + + return NC_NOERR; +} +#else +static int +var_exists(hid_t grpid, char *name, int *exists) +{ + hsize_t num_obj, i; + H5O_info_t obj_info; + int obj_class; + char obj_name[NC_MAX_NAME + 1]; + ssize_t size; + int retval = NC_NOERR; + + *exists = 0; + if (H5Gget_num_objs(grpid, &num_obj) < 0) + return NC_EVARMETA; + for (i = 0; i < num_obj; i++) + { + if (H5Oget_info_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, i, &obj_info, H5P_DEFAULT) < 0) + return NC_EHDFERR; + obj_class = obj_info.type; + if ((size = H5Lget_name_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, i, NULL, 0, H5P_DEFAULT)) < 0) + return NC_EHDFERR; + if (size > NC_MAX_NAME) + return NC_EMAXNAME; + if (H5Lget_name_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, i, obj_name, size+1, H5P_DEFAULT) < 0) + return NC_EHDFERR; + if (obj_class == H5O_TYPE_DATASET) + { + if (!strncmp(name, obj_name, NC_MAX_NAME)) + { + *exists = 1; + return NC_NOERR; + } + } + } + + return retval; +} +#endif /* USE_ITERATE_CODE */ + +/* This function writes a variable. The principle difficulty comes + * from the possibility that this is a coordinate variable, and was + * already written to the file as a dimension-only dimscale. If this + * occurs, then it must be deleted and recreated. */ +static int +write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, int write_dimid) +{ + NC_DIM_INFO_T *d1 = NULL; + int replace_existing_var = 0; + int exists; + int retval; + + if (!var->dirty) + { + if (write_dimid && var->ndims) + if ((retval = write_netcdf4_dimid(var->hdf_datasetid, + var->dimids[0]))) + BAIL(retval); + } + else + { + LOG((4, "write_var: writing var %s", var->name)); + + if (var->created) + replace_existing_var = 1; + + /* If this is a coordinate var, and a dataset has already + * been created for it, then delete that dataset and recreate + * it (because its type may be wrong anyway.) But then we + * have to reattach dimension scales for all vars! Oh well, + * this all only happens when the user defines a var, writes + * metadata, reenters define mode, and adds a coordinate + * var. Presumably this will happen rarely. */ + + /* Is this a coordinate var that has already been created in + * the HDF5 as a dimscale dataset? Check for dims with the + * same name in this group. If there is one, check to see if + * this object exists in the HDF group. */ + if (var->dimscale) + for (d1 = grp->dim; d1; d1 = d1->next) + if (!strcmp(d1->name, var->name)) + { + if ((retval = var_exists(grp->hdf_grpid, var->name, &exists))) + return retval; + if (exists) + { + replace_existing_var++; + + /* If we're replacing an existing dimscale dataset, go to + * every var in the file and detatch this dimension scale, + * because we have to delete it. */ + if ((retval = rec_detach_scales(grp->file->nc4_info->root_grp, + var->dimids[0], d1->hdf_dimscaleid))) + return retval; + break; + } + } + + /* Delete the HDF5 dataset that is to be replaced. */ + if (replace_existing_var) + { + /* If this is a dimension scale, do this stuff. */ + if (d1) + { + assert(d1 && d1->hdf_dimscaleid); + if (H5Dclose(d1->hdf_dimscaleid) < 0) + return NC_EDIMMETA; + } + else + { + int dims_detached = 0; + int finished = 0; + int d; + NC_DIM_INFO_T *dim1; + NC_GRP_INFO_T *g; + + /* If this is a regular var, detach all its dim scales. */ + for (d = 0; d < var->ndims; d++) + for (g = grp; g && !finished; g = g->parent) + for (dim1 = g->dim; dim1; dim1 = dim1->next) + if (var->dimids[d] == dim1->dimid) + { + if (H5DSdetach_scale(var->hdf_datasetid, dim1->hdf_dimscaleid, d) < 0) + BAIL(NC_EHDFERR); + var->dimscale_attached[d] = 0; + if (dims_detached++ == var->ndims) + finished++; + } + } + + /* Free the HDF5 dataset id. */ + if (var->hdf_datasetid && H5Dclose(var->hdf_datasetid)) + BAIL(NC_EHDFERR); + + /* Now delete the variable. */ + if (H5Gunlink(grp->hdf_grpid, var->name) < 0) + return NC_EDIMMETA; + } + + /* Create the dataset. */ + if ((retval = var_create_dataset(grp, var, write_dimid))) + return retval; + + /* Reattach this scale everywhere it is used. (Recall that + * netCDF dimscales are always 1-D). */ + if (d1 && replace_existing_var) + { + d1->hdf_dimscaleid = var->hdf_datasetid; + if ((retval = rec_reattach_scales(grp->file->nc4_info->root_grp, + var->dimids[0], d1->hdf_dimscaleid))) + return retval; + } + } + + /* Now check the atributes for this var. */ + /* Write attributes for this var. */ + if ((retval = write_attlist(var->att, var->varid, grp))) + BAIL(retval); + + return NC_NOERR; + exit: + return retval; +} + +static int +write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, int write_dimid) +{ + hid_t spaceid, create_propid; + hsize_t dims[1], max_dims[1], chunk_dims[1] = {1}; + int dimscale_exists = 0; + char dimscale_wo_var[NC_MAX_NAME]; + int retval; + + if (dim->dirty) + { + /* If there's no dimscale dataset for this dim, create one, + * and mark that it should be hidden from netCDF as a + * variable. (That is, it should appear as a dimension + * without an associated variable.) */ + if (!dimscale_exists) + { + LOG((4, "write_dim: creating dim %s", dim->name)); + + /* Create a property list. If this dimension scale is + * unlimited (i.e. it's an unlimited dimension), then set + * up chunking, with a chunksize of 1. */ + if ((create_propid = H5Pcreate(H5P_DATASET_CREATE)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists++; +#endif + dims[0] = dim->len; + max_dims[0] = dim->len; + if (dim->unlimited) + { + max_dims[0] = H5S_UNLIMITED; + if (H5Pset_chunk(create_propid, 1, chunk_dims) < 0) + BAIL(NC_EHDFERR); + } + + /* Set up space. */ + if ((spaceid = H5Screate_simple(1, dims, max_dims)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + + /* If we define, and then rename this dimension before + * creation of the dimscale dataset, then we can throw + * away the old_name of the dimension. */ + if (dim->old_name && strlen(dim->old_name)) + strcpy(dim->old_name, ""); + + if (H5Pset_attr_creation_order(create_propid, H5P_CRT_ORDER_TRACKED| + H5P_CRT_ORDER_INDEXED) < 0) + BAIL(NC_EHDFERR); + + /* Create the dataset that will be the dimension scale. */ + LOG((4, "write_dim: about to H5Dcreate a dimscale dataset %s", dim->name)); + if ((dim->hdf_dimscaleid = H5Dcreate1(grp->hdf_grpid, dim->name, H5T_IEEE_F32BE, + spaceid, create_propid)) < 0) + BAIL(NC_EHDFERR); + + /* Close the spaceid and create_propid. */ + if (H5Sclose(spaceid) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (H5Pclose(create_propid) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_plists--; +#endif + + /* Indicate that this is a scale. Also indicate that not + * be shown to the user as a variable. It is hidden. It is + * a DIM WITHOUT A VARIABLE! */ + sprintf(dimscale_wo_var, "%s%10d", DIM_WITHOUT_VARIABLE, (int)dim->len); + if (H5DSset_scale(dim->hdf_dimscaleid, dimscale_wo_var) < 0) + BAIL(NC_EHDFERR); + + } + dim->dirty = 0; + } + + /* Did we extend an unlimited dimension? */ + if (dim->extended) + { + NC_VAR_INFO_T *v1; + + assert(dim->unlimited); + /* If this is a dimension without a variable, then update + * the secret length information at the end of the NAME + * attribute. */ + for (v1 = grp->var; v1; v1 = v1->next) + if (!strcmp(v1->name, dim->name)) + break; + + if (v1) + { + hsize_t *new_size; + NC_GRP_INFO_T *g; + NC_DIM_INFO_T *dim1; + int d1; + + /* Extend the dimension scale dataset to reflect the new + * length of the dimension. */ + if (!(new_size = malloc(v1->ndims * sizeof(hsize_t)))) + BAIL(NC_ENOMEM); + for (d1 = 0; d1 < v1->ndims; d1++) + { + if (v1->dimids[d1] == dim->dimid) + new_size[d1] = dim->len; + else + { + int break_it = 0; + for (g = grp; g && !break_it; g = g->parent) + for (dim1 = g->dim; dim1; dim1 = dim1->next) + if (dim1->dimid == v1->dimids[d1]) + { + new_size[d1] = dim1->len; + break_it++; + break; + } + } + } + if (H5Dextend(v1->hdf_datasetid, new_size) < 0) + BAIL(NC_EHDFERR); + free(new_size); + } + } + + /* Did we rename this dimension? */ + if (dim->old_name && strlen(dim->old_name)) + { + /* Rename the dimension's dataset in the HDF5 file. */ + if (H5Gmove2(grp->hdf_grpid, dim->old_name, grp->hdf_grpid, dim->name) < 0) + return NC_EHDFERR; + + /* Reset old_name. */ + strcpy(dim->old_name, ""); + } + + /* If desired, write the secret dimid. This will be used instead of + * the dimid that the dimension would otherwise receive based on + * creation order. This can be necessary when dims and their + * coordinate variables were created in different order. */ + if (write_dimid && dim->hdf_dimscaleid) + if ((retval = write_netcdf4_dimid(dim->hdf_dimscaleid, + dim->dimid))) + BAIL(retval); + + return NC_NOERR; + exit: + return retval; +} + +/* Recursively write all the metadata in a group. Groups and types + * have all already been written. */ +int +nc4_rec_write_metadata(NC_GRP_INFO_T *grp) +{ + NC_DIM_INFO_T *dim; + NC_VAR_INFO_T *var; + NC_GRP_INFO_T *child_grp; + int found_coord, coord_varid = -1, wrote_coord; + int bad_coord_order = 0; + int last_dimid = -1; + int retval; + + assert(grp && grp->name && grp->hdf_grpid); + LOG((3, "nc4_rec_write_metadata: grp->name %s", grp->name)); + + /* Write global attributes for this group. */ + if ((retval = write_attlist(grp->att, NC_GLOBAL, grp))) + return retval; + + /* If the user writes coord vars in a different order then he + * defined their dimensions, then, when the file is reopened, the + * order of the dimids will change to match the order of the coord + * vars. Detect if this is about to happen. */ + for (var = grp->var; var; var = var->next) + { + LOG((5, "checking %s for out of order coord var", var->name)); + if (var->ndims && var->dimscale) + { + if (var->dimids[0] < last_dimid) + { + bad_coord_order++; + break; + } + last_dimid = var->dimids[0]; + } + } + + /* Did the user define a dimension, end define mode, reenter define + * mode, and then define a coordinate variable for that dimension? + * If so, dimensions will be out of order. */ + for (var = grp->var; var; var = var->next) + if (var->dirty && !var->created && var->ndims) + for (dim = grp->dim; dim && dim->next; dim = dim->next) + if (strcmp(dim->name, var->name) && !dim->dirty) + { + LOG((5, "coord var defined after enddef/redef")); + bad_coord_order++; + } + + + /* For some stupid reason, the dim list is stored backwards! Get to + * the back of the list. */ + for (dim = grp->dim; dim && dim->next; dim = dim->next) + ; + + /* Set the pointer to the beginning of the list of vars in this + * group. */ + var = grp->var; + + /* Because of HDF5 ordering the dims and vars have to be stored in + * this way to ensure that the dims and coordinate vars come out in + * the correct order. */ + while (dim || var) + { + /* Write non-coord dims in order, stopping at the first one that + * has an associated coord var. */ + for (found_coord = 0; dim && !found_coord; dim = dim->prev) + { + if (!dim->coord_var_in_grp) + { + if ((retval = write_dim(dim, grp, bad_coord_order))) + return retval; + } + else + { + found_coord++; + coord_varid = dim->coord_var->varid; + } + } + + /* Write each var. When we get to the coord var we are waiting + * for (if any), then we break after writing it. */ + for (wrote_coord = 0; var && !wrote_coord; var = var->next) + { + if ((retval = write_var(var, grp, bad_coord_order))) + return retval; + if (found_coord && var->varid == coord_varid) + wrote_coord++; + } + } /* end while */ + + if ((retval = attach_dimscales(grp))) + return retval; + + /* If there are any child groups, write their metadata. */ + for (child_grp = grp->children; child_grp; child_grp = child_grp->next) + if ((retval = nc4_rec_write_metadata(child_grp))) + return retval; + + return NC_NOERR; +} + +/* Recursively write all groups and types. */ +int +nc4_rec_write_types(NC_GRP_INFO_T *grp) +{ + NC_GRP_INFO_T *child_grp; + NC_TYPE_INFO_T *type; + int retval; + + assert(grp && grp->name); + LOG((3, "nc4_rec_write_types: grp->name %s", grp->name)); + + /* Create the group in the HDF5 file if it doesn't exist. */ + if (!grp->hdf_grpid) + if ((retval = create_group(grp))) + return retval; + + /* If this is the root group of a file with strict NC3 rules, write + * an attribute. But don't leave the attribute open. */ + if (!grp->parent && (grp->file->nc4_info->cmode & NC_CLASSIC_MODEL)) + if ((retval = write_nc3_strict_att(grp->hdf_grpid))) + return retval; + + /* If there are any user-defined types, write them now. */ + for (type = grp->type; type; type = type->next) + if ((retval = commit_type(grp, type))) + return retval; + + /* If there are any child groups, write their groups and types. */ + for (child_grp = grp->children; child_grp; child_grp = child_grp->next) + if ((retval = nc4_rec_write_types(child_grp))) + return retval; + + return NC_NOERR; +} + +/* This reads/writes a whole var at a time. If the file has an + unlimited dimension, then we will look at the number of records + currently existing for this var, and read/write that many. This + this is not what the user intended, particularly with writing, then + that is there look-out! So we will not be extending datasets + here. */ +int +pg_var(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, nc_type xtype, + int is_long, void *ip) +{ + NC_GRP_INFO_T *grp; + NC_VAR_INFO_T *var; + size_t start[NC_MAX_VAR_DIMS], count[NC_MAX_VAR_DIMS]; + int i; + int retval; + + assert(nc); + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; + assert(grp && var && var->name); + + /* For each dimension, the start will be 0, and the count will be + * the length of the dimension. */ + for (i = 0; i < var->ndims; i++) + { + start[i] = 0; + if ((retval = nc_inq_dimlen(ncid, var->dimids[i], &(count[i])))) + return retval; + } + + /* Read or write the data. */ + if (pg == GET) + return nc4_get_vara(nc, ncid, varid, start, count, xtype, + is_long, ip); + else + return nc4_put_vara(nc, ncid, varid, start, count, xtype, + is_long, ip); +} + +/* Write or read some mapped data. Yea, like I even understand what it + is! + + I stole this code, lock, stock, and semicolons, from the netcdf + 3.5.1 beta release. It walks through the stride and map arrays, and + converts them to a series of calles to the varm function. + + I had to modify the code a little to fit it in, and generalize it + for all data types, and for both puts and gets. + + Ed Hartnett, 9/43/03 +*/ +int +nc4_pg_varm(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *start, + const size_t *edges, const ptrdiff_t *stride, + const ptrdiff_t *map, nc_type xtype, int is_long, void *data) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + int maxidim; /* maximum dimensional index */ + size_t mem_type_size; + int convert_map = 0; + ptrdiff_t new_map[NC_MAX_VAR_DIMS]; + int i; + int retval = NC_NOERR; + + LOG((3, "nc4_pg_varm: ncid 0x%x varid %d xtype %d", ncid, varid, + xtype)); + + /* Find metadata for this file and var. */ + assert(nc && nc->nc4_info); + h5 = nc->nc4_info; + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; + assert(grp && var && var->name); + + /* If mem_nc_type is NC_NAT, it means we were called by + * nc_get|put_varm, the old V2 API call! In this case we want to + * use the file type as the mem type as well. Also, for these two + * functions only, we interpret the map array as referring to + * numbers of bytes rather than number of elements. (This is + * something that changed between V2 and V3.) Also we do not allow + * mapped access to user-defined vars in nc4. */ + if (xtype == NC_NAT) + { + if (var->xtype > NC_STRING) + return NC_EMAPTYPE; + xtype = var->xtype; + convert_map++; + } + assert(xtype); + + /* What is the size of this type? */ + if ((retval = nc4_get_typelen_mem(h5, xtype, is_long, &mem_type_size))) + return retval; + + if(map != NULL && var->ndims && convert_map) + { + /* convert map units from bytes to units of sizeof(type) */ + for(i = 0; i < var->ndims; i++) + { + if(map[i] % mem_type_size != 0) + return NC_EINVAL; + new_map[i] = map[i] / mem_type_size; + } + map = new_map; + } + + /* No text to number hanky-panky is allowed for those observing + * strict netcdf-3 rules! It's sick. */ + if ((h5->cmode & NC_CLASSIC_MODEL) && (xtype == NC_CHAR || var->xtype == NC_CHAR) && + (xtype != var->xtype)) + return NC_ECHAR; + + /* If the file is read-only, return an error. */ + if (pg == PUT && h5->no_write) + return NC_EPERM; + + /* If we're in define mode, we can't read or write data. If strict + * nc3 rules are in effect, return an error, otherwise leave define + * mode. */ + if (h5->flags & NC_INDEF) + { + if (h5->cmode & NC_CLASSIC_MODEL) + return NC_EINDEFINE; + if ((retval = nc_enddef(ncid))) + BAIL(retval); + } + +#ifdef LOGGING + { + int i; + if (start) + for (i=0; indims; i++) + LOG((4, "start[%d] %d", i, start[i])); + if (edges) + for (i=0; indims; i++) + LOG((4, "edges[%d] %d", i, edges[i])); + if (stride) + for (i=0; indims; i++) + LOG((4, "stride[%d] %d", i, stride[i])); + if (map) + for (i=0; indims; i++) + LOG((4, "map[%d] %d", i, map[i])); + } +#endif /* LOGGING */ + + /* The code below was stolen from netcdf-3. Some comments by Ed. */ + maxidim = (int) var->ndims - 1; + if (maxidim < 0) + { + /* The variable is a scalar; consequently, there is only one + thing to get and only one place to put it. (Why was I + called?) */ + return pg_var(pg, nc, ncid, varid, xtype, is_long, data); + } + + /* The variable is an array. */ + { + int idim; + size_t *mystart = NULL; + size_t *myedges; + size_t *iocount; /* count vector */ + size_t *stop; /* stop indexes */ + size_t *length; /* edge lengths in bytes */ + ptrdiff_t *mystride; + ptrdiff_t *mymap; + + /* Verify stride argument. */ + for (idim = 0; idim <= maxidim; ++idim) + { + if (stride != NULL + && (stride[idim] == 0 + /* cast needed for braindead systems with signed size_t */ + || (unsigned long) stride[idim] >= X_INT_MAX)) + { + return NC_ESTRIDE; + } + } + + /* The mystart array of pointer info is needed to walk our way + through the dimensions as specified by the start, edges, + stride and (gulp!) map parameters. */ + if (!(mystart = (size_t *)calloc((size_t)var->ndims * 7, sizeof(ptrdiff_t)))) + return NC_ENOMEM; + myedges = mystart + var->ndims; + iocount = myedges + var->ndims; + stop = iocount + var->ndims; + length = stop + var->ndims; + mystride = (ptrdiff_t *)(length + var->ndims); + mymap = mystride + var->ndims; + + /* Initialize I/O parameters. */ + for (idim = maxidim; idim >= 0; --idim) + { + /* Get start value, use 0 if non provided. */ + mystart[idim] = start != NULL ? start[idim] : 0; + + /* If any edges are 0, return NC_NOERR and forget it. */ + if (edges[idim] == 0) + { + retval = NC_NOERR; + goto done; + } + + /* If edges not provided, use the current dimlen. */ + if (edges) + myedges[idim] = edges[idim]; + else + { + size_t len; + if ((retval = nc_inq_dimlen(ncid, var->dimids[idim], &len))) + goto done; + myedges[idim] = len - mystart[idim]; + } + + /* If stride not provided, use 1. */ + mystride[idim] = stride != NULL ? stride[idim] : 1; + + /* If map is not provided, do something dark and + mysterious. */ + if (map) + mymap[idim] = map[idim]; + else + mymap[idim] = idim == maxidim ? 1 : + mymap[idim + 1] * (ptrdiff_t) myedges[idim + 1]; + + iocount[idim] = 1; + length[idim] = mymap[idim] * myedges[idim]; + stop[idim] = mystart[idim] + myedges[idim] * mystride[idim]; + } + + /* Check start, edges */ + for (idim = maxidim; idim >= 0; --idim) + { + size_t dimlen; + if ((retval = nc_inq_dimlen(ncid, var->dimids[idim], &dimlen))) + goto done; + /* Don't check unlimited dimension on PUTs. */ + if (pg == PUT) + { + int stop = 0, d, num_unlim_dim, unlim_dimids[NC_MAX_DIMS]; + if ((retval = nc_inq_unlimdims(ncid, &num_unlim_dim, unlim_dimids))) + goto done; + for (d = 0; d < num_unlim_dim; d++) + if (var->dimids[idim] == unlim_dimids[d]) + stop++; + if (stop) + break; + } + LOG((4, "idim=%d mystart[idim]=%d myedge[idim]=%d dimlen=%d", + idim, mystart[idim], myedges[idim], dimlen)); + if (mystart[idim] >= dimlen) + { + retval = NC_EINVALCOORDS; + goto done; + } + + if (mystart[idim] + myedges[idim] > dimlen) + { + retval = NC_EEDGE; + goto done; + } + } + + /* OK, now we're just getting too fancy... As an optimization, + adjust I/O parameters when the fastest dimension has unity + stride both externally and internally. In this case, the user + could have called a simpler routine + (i.e. ncvarnc_get_vara_text).*/ + if (mystride[maxidim] == 1 + && mymap[maxidim] == 1) + { + iocount[maxidim] = myedges[maxidim]; + mystride[maxidim] = (ptrdiff_t) myedges[maxidim]; + mymap[maxidim] = (ptrdiff_t) length[maxidim]; + } + + /* Perform I/O. Exit when done. */ + for (;;) + { + int lretval; + if (pg == GET) + lretval = nc4_get_vara(nc, ncid, varid, mystart, iocount, xtype, + is_long, data); + else + lretval = nc4_put_vara(nc, ncid, varid, mystart, iocount, xtype, + is_long, data); + if (lretval != NC_NOERR + && (retval == NC_NOERR || lretval != NC_ERANGE)) + retval = lretval; + + /* + * The following code permutes through the variable s + * external start-index space and it s internal address + * space. At the UPC, this algorithm is commonly + * called "odometer code". + */ + idim = maxidim; + carry: + data = (char *)data + (mymap[idim] * mem_type_size); + LOG((4, "data=0x%x mymap[%d]=%d", data, idim, (int)mymap[idim])); + mystart[idim] += mystride[idim]; + LOG((4, "mystart[%d]=%d length[%d]=%d", idim, (int)mystart[idim], + idim, (int)length[idim])); + if (mystart[idim] == stop[idim]) + { + mystart[idim] = start[idim]; + data = (char *)data - (length[idim] * mem_type_size); + if (--idim < 0) + break; /* normal return */ + goto carry; + } + } /* I/O loop */ + done: + free(mystart); + } /* variable is array */ + + exit: + return retval; +} + +/* This function will copy data from one buffer to another, in + accordance with the types. Range errors will be noted, and the fill + value used (or the default fill value if none is supplied) for + values that overflow the type. + + I should be able to take this out when HDF5 does the right thing + with data type conversion. + + Ed Hartnett, 11/15/3 +*/ + +int +nc4_convert_type(const void *src, void *dest, + const nc_type src_type, const nc_type dest_type, + const size_t len, int *range_error, + const void *fill_value, int strict_nc3, int src_long, + int dest_long) +{ + char *cp, *cp1; + float *fp, *fp1; + double *dp, *dp1; + int *ip, *ip1; + signed long *lp, *lp1; + short *sp, *sp1; + signed char *bp, *bp1; + unsigned char *ubp, *ubp1; + unsigned short *usp, *usp1; + unsigned int *uip, *uip1; + long long *lip, *lip1; + unsigned long long *ulip, *ulip1; + size_t count = 0; + + *range_error = 0; + LOG((3, "nc4_convert_type: len %d src_type %d dest_type %d src_long %d" + " dest_long %d", len, src_type, dest_type, src_long, dest_long)); + + /* OK, this is ugly. If you can think of anything better, I'm open + to suggestions! + + Note that we don't use a default fill value for type + NC_BYTE. This is because Lord Voldemort cast a nofilleramous spell + at Harry Potter, but it bounced off his scar and hit the netcdf-4 + code. + */ + switch (src_type) + { + case NC_CHAR: + switch (dest_type) + { + case NC_CHAR: + for (cp = (char *)src, cp1 = dest; count < len; count++) + *cp1++ = *cp++; + break; + default: + LOG((0, "nc4_convert_type: Uknown destination type.")); + } + break; + case NC_BYTE: + switch (dest_type) + { + case NC_BYTE: + for (bp = (signed char *)src, bp1 = dest; count < len; count++) + *bp1++ = *bp++; + break; + case NC_UBYTE: + for (bp = (signed char *)src, ubp = dest; count < len; count++) + { + if (*bp < 0) + (*range_error)++; + *ubp++ = *bp++; + } + break; + case NC_SHORT: + for (bp = (signed char *)src, sp = dest; count < len; count++) + *sp++ = *bp++; + break; + case NC_USHORT: + for (bp = (signed char *)src, usp = dest; count < len; count++) + { + if (*bp < 0) + (*range_error)++; + *usp++ = *bp++; + } + break; + case NC_INT: + if (dest_long) + { + for (bp = (signed char *)src, lp = dest; count < len; count++) + *lp++ = *bp++; + break; + } + else + { + for (bp = (signed char *)src, ip = dest; count < len; count++) + *ip++ = *bp++; + break; + } + case NC_UINT: + for (bp = (signed char *)src, uip = dest; count < len; count++) + { + if (*bp < 0) + (*range_error)++; + *uip++ = *bp++; + } + break; + case NC_INT64: + for (bp = (signed char *)src, lip = dest; count < len; count++) + *lip++ = *bp++; + break; + case NC_UINT64: + for (bp = (signed char *)src, ulip = dest; count < len; count++) + { + if (*bp < 0) + (*range_error)++; + *ulip++ = *bp++; + } + break; + case NC_FLOAT: + for (bp = (signed char *)src, fp = dest; count < len; count++) + *fp++ = *bp++; + break; + case NC_DOUBLE: + for (bp = (signed char *)src, dp = dest; count < len; count++) + *dp++ = *bp++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + case NC_UBYTE: + switch (dest_type) + { + case NC_BYTE: + for (ubp = (unsigned char *)src, bp = dest; count < len; count++) + { + if (!strict_nc3 && *ubp > X_SCHAR_MAX) + (*range_error)++; + *bp++ = *ubp++; + } + break; + case NC_SHORT: + for (ubp = (unsigned char *)src, sp = dest; count < len; count++) + *sp++ = *ubp++; + break; + case NC_UBYTE: + for (ubp = (unsigned char *)src, ubp1 = dest; count < len; count++) + *ubp1++ = *ubp++; + break; + case NC_USHORT: + for (ubp = (unsigned char *)src, usp = dest; count < len; count++) + *usp++ = *ubp++; + break; + case NC_INT: + if (dest_long) + { + for (ubp = (unsigned char *)src, lp = dest; count < len; count++) + *lp++ = *ubp++; + break; + } + else + { + for (ubp = (unsigned char *)src, ip = dest; count < len; count++) + *ip++ = *ubp++; + break; + } + case NC_UINT: + for (ubp = (unsigned char *)src, uip = dest; count < len; count++) + *uip++ = *ubp++; + break; + case NC_INT64: + for (ubp = (unsigned char *)src, lip = dest; count < len; count++) + *lip++ = *ubp++; + break; + case NC_UINT64: + for (ubp = (unsigned char *)src, ulip = dest; count < len; count++) + *ulip++ = *ubp++; + break; + case NC_FLOAT: + for (ubp = (unsigned char *)src, fp = dest; count < len; count++) + *fp++ = *ubp++; + break; + case NC_DOUBLE: + for (ubp = (unsigned char *)src, dp = dest; count < len; count++) + *dp++ = *ubp++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + case NC_SHORT: + switch (dest_type) + { + case NC_UBYTE: + for (sp = (short *)src, ubp = dest; count < len; count++) + { + if (*sp > X_UCHAR_MAX || *sp < 0) + (*range_error)++; + *ubp++ = *sp++; + } + break; + case NC_BYTE: + for (sp = (short *)src, bp = dest; count < len; count++) + { + if (*sp > X_SCHAR_MAX || *sp < X_SCHAR_MIN) + (*range_error)++; + *bp++ = *sp++; + } + break; + case NC_SHORT: + for (sp = (short *)src, sp1 = dest; count < len; count++) + *sp1++ = *sp++; + break; + case NC_USHORT: + for (sp = (short *)src, usp = dest; count < len; count++) + { + if (*sp < 0) + (*range_error)++; + *usp++ = *sp++; + } + break; + case NC_INT: + if (dest_long) + for (sp = (short *)src, lp = dest; count < len; count++) + *lp++ = *sp++; + else + for (sp = (short *)src, ip = dest; count < len; count++) + *ip++ = *sp++; + break; + case NC_UINT: + for (sp = (short *)src, uip = dest; count < len; count++) + { + if (*sp < 0) + (*range_error)++; + *uip++ = *sp++; + } + break; + case NC_INT64: + for (sp = (short *)src, lip = dest; count < len; count++) + *lip++ = *sp++; + break; + case NC_UINT64: + for (sp = (short *)src, ulip = dest; count < len; count++) + { + if (*sp < 0) + (*range_error)++; + *ulip++ = *sp++; + } + break; + case NC_FLOAT: + for (sp = (short *)src, fp = dest; count < len; count++) + *fp++ = *sp++; + break; + case NC_DOUBLE: + for (sp = (short *)src, dp = dest; count < len; count++) + *dp++ = *sp++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + case NC_USHORT: + switch (dest_type) + { + case NC_UBYTE: + for (usp = (unsigned short *)src, ubp = dest; count < len; count++) + { + if (*usp > X_UCHAR_MAX) + (*range_error)++; + *ubp++ = *usp++; + } + break; + case NC_BYTE: + for (usp = (unsigned short *)src, bp = dest; count < len; count++) + { + if (*usp > X_SCHAR_MAX) + (*range_error)++; + *bp++ = *usp++; + } + break; + case NC_SHORT: + for (usp = (unsigned short *)src, sp = dest; count < len; count++) + { + if (*usp > X_SHORT_MAX) + (*range_error)++; + *sp++ = *usp++; + } + break; + case NC_USHORT: + for (usp = (unsigned short *)src, usp1 = dest; count < len; count++) + *usp1++ = *usp++; + break; + case NC_INT: + if (dest_long) + for (usp = (unsigned short *)src, lp = dest; count < len; count++) + *lp++ = *usp++; + else + for (usp = (unsigned short *)src, ip = dest; count < len; count++) + *ip++ = *usp++; + break; + case NC_UINT: + for (usp = (unsigned short *)src, uip = dest; count < len; count++) + *uip++ = *usp++; + break; + case NC_INT64: + for (usp = (unsigned short *)src, lip = dest; count < len; count++) + *lip++ = *usp++; + break; + case NC_UINT64: + for (usp = (unsigned short *)src, ulip = dest; count < len; count++) + *ulip++ = *usp++; + break; + case NC_FLOAT: + for (usp = (unsigned short *)src, fp = dest; count < len; count++) + *fp++ = *usp++; + break; + case NC_DOUBLE: + for (usp = (unsigned short *)src, dp = dest; count < len; count++) + *dp++ = *usp++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + case NC_INT: + if (src_long) + { + switch (dest_type) + { + case NC_UBYTE: + for (lp = (long *)src, ubp = dest; count < len; count++) + { + if (*lp > X_UCHAR_MAX || *lp < 0) + (*range_error)++; + *ubp++ = *lp++; + } + break; + case NC_BYTE: + for (lp = (long *)src, bp = dest; count < len; count++) + { + if (*lp > X_SCHAR_MAX || *lp < X_SCHAR_MIN) + (*range_error)++; + *bp++ = *lp++; + } + break; + case NC_SHORT: + for (lp = (long *)src, sp = dest; count < len; count++) + { + if (*lp > X_SHORT_MAX || *lp < X_SHORT_MIN) + (*range_error)++; + *sp++ = *lp++; + } + break; + case NC_USHORT: + for (lp = (long *)src, usp = dest; count < len; count++) + { + if (*lp > X_USHORT_MAX || *lp < 0) + (*range_error)++; + *usp++ = *lp++; + } + break; + case NC_INT: /* src is long */ + if (dest_long) + { + for (lp = (long *)src, lp1 = dest; count < len; count++) + { + if (*lp > X_LONG_MAX || *lp < X_LONG_MIN) + (*range_error)++; + *lp1++ = *lp++; + } + } + else /* dest is int */ + { + for (lp = (long *)src, ip = dest; count < len; count++) + { + if (*lp > X_INT_MAX || *lp < X_INT_MIN) + (*range_error)++; + *ip++ = *lp++; + } + } + break; + case NC_UINT: + for (lp = (long *)src, uip = dest; count < len; count++) + { + if (*lp > X_UINT_MAX || *lp < 0) + (*range_error)++; + *uip++ = *lp++; + } + break; + case NC_INT64: + for (lp = (long *)src, lip = dest; count < len; count++) + *lip++ = *lp++; + break; + case NC_UINT64: + for (lp = (long *)src, ulip = dest; count < len; count++) + { + if (*lp < 0) + (*range_error)++; + *ulip++ = *lp++; + } + break; + case NC_FLOAT: + for (lp = (long *)src, fp = dest; count < len; count++) + *fp++ = *lp++; + break; + case NC_DOUBLE: + for (lp = (long *)src, dp = dest; count < len; count++) + *dp++ = *lp++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + } + else + { + switch (dest_type) + { + case NC_UBYTE: + for (ip = (int *)src, ubp = dest; count < len; count++) + { + if (*ip > X_UCHAR_MAX || *ip < 0) + (*range_error)++; + *ubp++ = *ip++; + } + break; + case NC_BYTE: + for (ip = (int *)src, bp = dest; count < len; count++) + { + if (*ip > X_SCHAR_MAX || *ip < X_SCHAR_MIN) + (*range_error)++; + *bp++ = *ip++; + } + break; + case NC_SHORT: + for (ip = (int *)src, sp = dest; count < len; count++) + { + if (*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) + (*range_error)++; + *sp++ = *ip++; + } + break; + case NC_USHORT: + for (ip = (int *)src, usp = dest; count < len; count++) + { + if (*ip > X_USHORT_MAX || *ip < 0) + (*range_error)++; + *usp++ = *ip++; + } + break; + case NC_INT: /* src is int */ + if (dest_long) + { + for (ip = (int *)src, lp1 = dest; count < len; count++) + { + if (*ip > X_LONG_MAX || *ip < X_LONG_MIN) + (*range_error)++; + *lp1++ = *ip++; + } + } + else /* dest is int */ + { + for (ip = (int *)src, ip1 = dest; count < len; count++) + { + if (*ip > X_INT_MAX || *ip < X_INT_MIN) + (*range_error)++; + *ip1++ = *ip++; + } + } + break; + case NC_UINT: + for (ip = (int *)src, uip = dest; count < len; count++) + { + if (*ip > X_UINT_MAX || *ip < 0) + (*range_error)++; + *uip++ = *ip++; + } + break; + case NC_INT64: + for (ip = (int *)src, lip = dest; count < len; count++) + *lip++ = *ip++; + break; + case NC_UINT64: + for (ip = (int *)src, ulip = dest; count < len; count++) + { + if (*ip < 0) + (*range_error)++; + *ulip++ = *ip++; + } + break; + case NC_FLOAT: + for (ip = (int *)src, fp = dest; count < len; count++) + *fp++ = *ip++; + break; + case NC_DOUBLE: + for (ip = (int *)src, dp = dest; count < len; count++) + *dp++ = *ip++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + } + break; + case NC_UINT: + switch (dest_type) + { + case NC_UBYTE: + for (uip = (unsigned int *)src, ubp = dest; count < len; count++) + { + if (*uip > X_UCHAR_MAX) + (*range_error)++; + *ubp++ = *uip++; + } + break; + case NC_BYTE: + for (uip = (unsigned int *)src, bp = dest; count < len; count++) + { + if (*uip > X_SCHAR_MAX) + (*range_error)++; + *bp++ = *uip++; + } + break; + case NC_SHORT: + for (uip = (unsigned int *)src, sp = dest; count < len; count++) + { + if (*uip > X_SHORT_MAX) + (*range_error)++; + *sp++ = *uip++; + } + break; + case NC_USHORT: + for (uip = (unsigned int *)src, usp = dest; count < len; count++) + { + if (*uip > X_USHORT_MAX) + (*range_error)++; + *usp++ = *uip++; + } + break; + case NC_INT: + if (dest_long) + for (uip = (unsigned int *)src, lp = dest; count < len; count++) + { + if (*uip > X_LONG_MAX) + (*range_error)++; + *lp++ = *uip++; + } + else + for (uip = (unsigned int *)src, ip = dest; count < len; count++) + { + if (*uip > X_INT_MAX) + (*range_error)++; + *ip++ = *uip++; + } + break; + case NC_UINT: + for (uip = (unsigned int *)src, uip1 = dest; count < len; count++) + { + if (*uip > X_UINT_MAX) + (*range_error)++; + *uip1++ = *uip++; + } + break; + case NC_INT64: + for (uip = (unsigned int *)src, lip = dest; count < len; count++) + *lip++ = *uip++; + break; + case NC_UINT64: + for (uip = (unsigned int *)src, ulip = dest; count < len; count++) + *ulip++ = *uip++; + break; + case NC_FLOAT: + for (uip = (unsigned int *)src, fp = dest; count < len; count++) + *fp++ = *uip++; + break; + case NC_DOUBLE: + for (uip = (unsigned int *)src, dp = dest; count < len; count++) + *dp++ = *uip++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + case NC_INT64: + switch (dest_type) + { + case NC_UBYTE: + for (lip = (long long *)src, ubp = dest; count < len; count++) + { + if (*lip > X_UCHAR_MAX || *lip < 0) + (*range_error)++; + *ubp++ = *lip++; + } + break; + case NC_BYTE: + for (lip = (long long *)src, bp = dest; count < len; count++) + { + if (*lip > X_SCHAR_MAX || *lip < X_SCHAR_MIN) + (*range_error)++; + *bp++ = *lip++; + } + break; + case NC_SHORT: + for (lip = (long long *)src, sp = dest; count < len; count++) + { + if (*lip > X_SHORT_MAX || *lip < X_SHORT_MIN) + (*range_error)++; + *sp++ = *lip++; + } + break; + case NC_USHORT: + for (lip = (long long *)src, usp = dest; count < len; count++) + { + if (*lip > X_USHORT_MAX || *lip < 0) + (*range_error)++; + *usp++ = *lip++; + } + break; + case NC_UINT: + for (lip = (long long *)src, uip = dest; count < len; count++) + { + if (*lip > X_UINT_MAX || *lip < 0) + (*range_error)++; + *uip++ = *lip++; + } + break; + case NC_INT: + if (dest_long) + for (lip = (long long *)src, lp = dest; count < len; count++) + { + if (*lip > X_LONG_MAX || *lip < X_LONG_MIN) + (*range_error)++; + *lp++ = *lip++; + } + else + for (lip = (long long *)src, ip = dest; count < len; count++) + { + if (*lip > X_INT_MAX || *lip < X_INT_MIN) + (*range_error)++; + *ip++ = *lip++; + } + break; + case NC_INT64: + for (lip = (long long *)src, lip1 = dest; count < len; count++) + *lip1++ = *lip++; + break; + case NC_UINT64: + for (lip = (long long *)src, ulip = dest; count < len; count++) + { + if (*lip < 0) + (*range_error)++; + *ulip++ = *lip++; + } + break; + case NC_FLOAT: + for (lip = (long long *)src, fp = dest; count < len; count++) + *fp++ = *lip++; + break; + case NC_DOUBLE: + for (lip = (long long *)src, dp = dest; count < len; count++) + *dp++ = *lip++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + case NC_UINT64: + switch (dest_type) + { + case NC_UBYTE: + for (ulip = (unsigned long long *)src, ubp = dest; count < len; count++) + { + if (*ulip > X_UCHAR_MAX) + (*range_error)++; + *ubp++ = *ulip++; + } + break; + case NC_BYTE: + for (ulip = (unsigned long long *)src, bp = dest; count < len; count++) + { + if (*ulip > X_SCHAR_MAX) + (*range_error)++; + *bp++ = *ulip++; + } + break; + case NC_SHORT: + for (ulip = (unsigned long long *)src, sp = dest; count < len; count++) + { + if (*ulip > X_SHORT_MAX) + (*range_error)++; + *sp++ = *ulip++; + } + break; + case NC_USHORT: + for (ulip = (unsigned long long *)src, usp = dest; count < len; count++) + { + if (*ulip > X_USHORT_MAX) + (*range_error)++; + *usp++ = *ulip++; + } + break; + case NC_UINT: + for (ulip = (unsigned long long *)src, uip = dest; count < len; count++) + { + if (*ulip > X_UINT_MAX) + (*range_error)++; + *uip++ = *ulip++; + } + break; + case NC_INT: + if (dest_long) + for (ulip = (unsigned long long *)src, lp = dest; count < len; count++) + { + if (*ulip > X_LONG_MAX) + (*range_error)++; + *lp++ = *ulip++; + } + else + for (ulip = (unsigned long long *)src, ip = dest; count < len; count++) + { + if (*ulip > X_INT_MAX) + (*range_error)++; + *ip++ = *ulip++; + } + break; + case NC_INT64: + for (ulip = (unsigned long long *)src, lip = dest; count < len; count++) + { + if (*ulip > X_INT64_MAX) + (*range_error)++; + *lip++ = *ulip++; + } + break; + case NC_UINT64: + for (ulip = (unsigned long long *)src, ulip1 = dest; count < len; count++) + *ulip1++ = *ulip++; + break; + case NC_FLOAT: + for (ulip = (unsigned long long *)src, fp = dest; count < len; count++) + *fp++ = *ulip++; + break; + case NC_DOUBLE: + for (ulip = (unsigned long long *)src, dp = dest; count < len; count++) + *dp++ = *ulip++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + case NC_FLOAT: + switch (dest_type) + { + case NC_UBYTE: + for (fp = (float *)src, ubp = dest; count < len; count++) + { + if (*fp > X_UCHAR_MAX || *fp < 0) + (*range_error)++; + *ubp++ = *fp++; + } + break; + case NC_BYTE: + for (fp = (float *)src, bp = dest; count < len; count++) + { + if (*fp > (double)X_SCHAR_MAX || *fp < (double)X_SCHAR_MIN) + (*range_error)++; + *bp++ = *fp++; + } + break; + case NC_SHORT: + for (fp = (float *)src, sp = dest; count < len; count++) + { + if (*fp > (double)X_SHORT_MAX || *fp < (double)X_SHORT_MIN) + (*range_error)++; + *sp++ = *fp++; + } + break; + case NC_USHORT: + for (fp = (float *)src, usp = dest; count < len; count++) + { + if (*fp > X_USHORT_MAX || *fp < 0) + (*range_error)++; + *usp++ = *fp++; + } + break; + case NC_UINT: + for (fp = (float *)src, uip = dest; count < len; count++) + { + if (*fp > X_UINT_MAX || *fp < 0) + (*range_error)++; + *uip++ = *fp++; + } + break; + case NC_INT: + if (dest_long) + for (fp = (float *)src, lp = dest; count < len; count++) + { + if (*fp > (double)X_LONG_MAX || *fp < (double)X_LONG_MIN) + (*range_error)++; + *lp++ = *fp++; + } + else + for (fp = (float *)src, ip = dest; count < len; count++) + { + if (*fp > (double)X_INT_MAX || *fp < (double)X_INT_MIN) + (*range_error)++; + *ip++ = *fp++; + } + break; + case NC_INT64: + for (fp = (float *)src, lip = dest; count < len; count++) + { + if (*fp > X_INT64_MAX || *fp X_UINT64_MAX || *fp < 0) + (*range_error)++; + *lip++ = *fp++; + } + break; + case NC_FLOAT: + for (fp = (float *)src, fp1 = dest; count < len; count++) + { +/* if (*fp > X_FLOAT_MAX || *fp < X_FLOAT_MIN) + (*range_error)++;*/ + *fp1++ = *fp++; + } + break; + case NC_DOUBLE: + for (fp = (float *)src, dp = dest; count < len; count++) + *dp++ = *fp++; + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + case NC_DOUBLE: + switch (dest_type) + { + case NC_UBYTE: + for (dp = (double *)src, ubp = dest; count < len; count++) + { + if (*dp > X_UCHAR_MAX || *dp < 0) + (*range_error)++; + *ubp++ = *dp++; + } + break; + case NC_BYTE: + for (dp = (double *)src, bp = dest; count < len; count++) + { + if (*dp > X_SCHAR_MAX || *dp < X_SCHAR_MIN) + (*range_error)++; + *bp++ = *dp++; + } + break; + case NC_SHORT: + for (dp = (double *)src, sp = dest; count < len; count++) + { + if (*dp > X_SHORT_MAX || *dp < X_SHORT_MIN) + (*range_error)++; + *sp++ = *dp++; + } + break; + case NC_USHORT: + for (dp = (double *)src, usp = dest; count < len; count++) + { + if (*dp > X_USHORT_MAX || *dp < 0) + (*range_error)++; + *usp++ = *dp++; + } + break; + case NC_UINT: + for (dp = (double *)src, uip = dest; count < len; count++) + { + if (*dp > X_UINT_MAX || *dp < 0) + (*range_error)++; + *uip++ = *dp++; + } + break; + case NC_INT: + if (dest_long) + for (dp = (double *)src, lp = dest; count < len; count++) + { + if (*dp > X_LONG_MAX || *dp < X_LONG_MIN) + (*range_error)++; + *lp++ = *dp++; + } + else + for (dp = (double *)src, ip = dest; count < len; count++) + { + if (*dp > X_INT_MAX || *dp < X_INT_MIN) + (*range_error)++; + *ip++ = *dp++; + } + break; + case NC_INT64: + for (dp = (double *)src, lip = dest; count < len; count++) + { + if (*dp > X_INT64_MAX || *dp < X_INT64_MIN) + (*range_error)++; + *lip++ = *dp++; + } + break; + case NC_UINT64: + for (dp = (double *)src, lip = dest; count < len; count++) + { + if (*dp > X_UINT64_MAX || *dp < 0) + (*range_error)++; + *lip++ = *dp++; + } + break; + case NC_FLOAT: + for (dp = (double *)src, fp = dest; count < len; count++) + { + if (*dp > X_FLOAT_MAX || *dp < X_FLOAT_MIN) + (*range_error)++; + *fp++ = *dp++; + } + break; + case NC_DOUBLE: + for (dp = (double *)src, dp1 = dest; count < len; count++) + { + /* if (*dp > X_DOUBLE_MAX || *dp < X_DOUBLE_MIN) */ + /* (*range_error)++; */ + *dp1++ = *dp++; + } + break; + default: + LOG((0, "nc4_convert_type: unexpected dest type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + break; + default: + LOG((0, "nc4_convert_type: unexpected src type. " + "src_type %d, dest_type %d", src_type, dest_type)); + return NC_EBADTYPE; + } + return NC_NOERR; +} + +/* In our first pass through the data, we may have encountered + * variables before encountering their dimscales, so go through the + * vars in this file and make sure we've got a dimid for each. */ +int +nc4_rec_match_dimscales(NC_GRP_INFO_T *grp) +{ + NC_GRP_INFO_T *g; + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim; + H5G_stat_t statbuf; + int d, finished; + int retval = NC_NOERR; + + assert(grp && grp->name); + LOG((4, "nc4_rec_match_dimscales: grp->name %s", grp->name)); + + /* Perform var dimscale match for child groups. */ + for (g = grp->children; g; g = g->next) + if ((retval = nc4_rec_match_dimscales(g))) + return retval; + + /* Check all the vars in this group. If they have dimscale info, + * try and find a dimension for them. */ + for (var = grp->var; var; var = var->next) + { + /* Are there dimscales for this variable? */ + if (var->dimscale_hdf5_objids) + { + for (d = 0; d < var->ndims; d++) + { + LOG((5, "nc4_rec_match_dimscales: var %s has dimscale info...", var->name)); + /* Look at all the dims in this group to see if they + * match. */ + finished = 0; + for (g = grp; g && !finished; g = g->parent) + { + for (dim = g->dim; dim; dim = dim->next) + { + if (!dim->hdf_dimscaleid) + return NC_EDIMMETA; + if (H5Gget_objinfo(dim->hdf_dimscaleid, ".", 1, &statbuf) < 0) + return NC_EHDFERR; + if (var->dimscale_hdf5_objids[d].fileno[0] == statbuf.fileno[0] && + var->dimscale_hdf5_objids[d].objno[0] == statbuf.objno[0] && + var->dimscale_hdf5_objids[d].fileno[1] == statbuf.fileno[1] && + var->dimscale_hdf5_objids[d].objno[1] == statbuf.objno[1]) + { + LOG((4, "nc4_rec_match_dimscales: for dimension %d, found dim %s", + d, dim->name)); + var->dimids[d] = dim->dimid; + finished++; + break; + } + } /* next dim */ + } /* next grp */ + LOG((5, "nc4_rec_match_dimscales: dimid for this dimscale is %d", var->xtype)); + } /* next var->dim */ + } + else + { + if (!var->dimscale) + { + hid_t spaceid = 0; + hsize_t *h5dimlen = NULL, *h5dimlenmax = NULL; + int dataset_ndims; + + /* No dimscales for this var! Invent phony dimensions. */ + + /* Find the space information for this dimension. */ + if ((spaceid = H5Dget_space(var->hdf_datasetid)) < 0) + return NC_EHDFERR; +#ifdef EXTRA_TESTS + num_spaces++; +#endif + + /* Get the len of each dim in the space. */ + if (var->ndims) + { + if (!(h5dimlen = malloc(var->ndims * sizeof(hsize_t)))) + return NC_ENOMEM; + if (!(h5dimlenmax = malloc(var->ndims * sizeof(hsize_t)))) + return NC_ENOMEM; + if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid, h5dimlen, + h5dimlenmax)) < 0) + return NC_EHDFERR; + if (dataset_ndims != var->ndims) + return NC_EHDFERR; + } + else + { + /* Make sure it's scalar. */ + if (H5Sget_simple_extent_type(spaceid) != H5S_SCALAR) + return NC_EHDFERR; + } + + /* Release the space object. */ + if (H5Sclose(spaceid) < 0) + return NC_EHDFERR; +#ifdef EXTRA_TESTS + num_spaces--; +#endif + + /* Create a phony dimension for each dimension in the + * dataset, unless there already is one the correct + * size. */ + for (d = 0; d < var->ndims; d++) + { + NC_DIM_INFO_T *dim = NULL; + char phony_dim_name[NC_MAX_NAME + 1]; + + /* Is there already a phony dimension of the correct size? */ + for (dim = grp->dim; dim; dim = dim->next) + if ((dim->len == h5dimlen[d]) && + ((h5dimlenmax[d] == H5S_UNLIMITED && dim->unlimited) || + (h5dimlenmax[d] != H5S_UNLIMITED && !dim->unlimited))) + break; + + /* Didn't find a phony dim? Then create one. */ + if (!dim) + { + LOG((3, "nc4_rec_match_dimscales: creating phony dim for var %s", var->name)); + if ((retval = nc4_dim_list_add(&grp->dim))) + return retval; + grp->ndims++; + dim = grp->dim; + dim->dimid = grp->file->nc4_info->next_dimid++; + sprintf(phony_dim_name, "phony_dim_%d", dim->dimid); + if (!(dim->name = malloc((strlen(phony_dim_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(dim->name, phony_dim_name); + dim->len = h5dimlen[d]; + if (h5dimlenmax[d] == H5S_UNLIMITED) + dim->unlimited = 1; + } + + /* The variable must remember the dimid. */ + var->dimids[d] = dim->dimid; + } /* next dim */ + + /* Free the memory we malloced. */ + free(h5dimlen); + free(h5dimlenmax); + } + } + } + + return retval; +} + +/* Get the length, in bytes, of one element of a type in memory. */ +int +nc4_get_typelen_mem(NC_HDF5_FILE_INFO_T *h5, nc_type xtype, int is_long, + size_t *len) +{ + NC_TYPE_INFO_T *type; + int retval; + + LOG((4, "nc4_get_typelen_mem xtype: %d", xtype)); + assert(len); + + /* If this is an atomic type, the answer is easy. */ + switch (xtype) + { + case NC_BYTE: + case NC_CHAR: + case NC_UBYTE: + *len = sizeof(char); + return NC_NOERR; + case NC_SHORT: + case NC_USHORT: + *len = sizeof(short); + return NC_NOERR; + case NC_INT: + case NC_UINT: + if (is_long) + *len = sizeof(long); + else + *len = sizeof(int); + return NC_NOERR; + case NC_FLOAT: + *len = sizeof(float); + return NC_NOERR; + case NC_DOUBLE: + *len = sizeof(double); + return NC_NOERR; + case NC_INT64: + case NC_UINT64: + *len = sizeof(long long); + return NC_NOERR; + case NC_STRING: + *len = 0; /* can't even guess! */ + return NC_NOERR; + } + + /* See if var is compound type. */ + if ((retval = nc4_find_type(h5, xtype, &type))) + return retval; + + if (!type) + return NC_EBADTYPE; + + *len = type->size; + + LOG((5, "type->size ", type->size)); + + return NC_NOERR; +} diff --git a/extern/src_netcdf4/nc4internal.c b/extern/src_netcdf4/nc4internal.c new file mode 100644 index 0000000000000000000000000000000000000000..db13e4200b265479f39f33c07f4d1cdf15a7ec1f --- /dev/null +++ b/extern/src_netcdf4/nc4internal.c @@ -0,0 +1,1476 @@ +/** \file \internal +Internal netcdf-4 functions. + +This file contains functions internal to the netcdf4 library. None of +the functions in this file are exposed in the exetnal API. These +functions all relate to the manipulation of netcdf-4's in-memory +buffer of metadata information, i.e. the linked list of NC_FILE_INFO_T +structs. + +Copyright 2003-2011, University Corporation for Atmospheric +Research. See the COPYRIGHT file for copying and redistribution +conditions. + +*/ +#include "config.h" +#include "nc4internal.h" +#include "nc.h" /* from libsrc */ +#include "ncdispatch.h" /* from libdispatch */ +#include + +#define MEGABYTE 1048576 + +/* These are the default chunk cache sizes for HDF5 files created or + * opened with netCDF-4. */ +extern size_t nc4_chunk_cache_size; +extern size_t nc4_chunk_cache_nelems; +extern float nc4_chunk_cache_preemption; + +/* This is to track opened HDF5 objects to make sure they are + * closed. */ +#ifdef EXTRA_TESTS +extern int num_spaces; +#endif /* EXTRA_TESTS */ + +#ifdef LOGGING +/* This is the severity level of messages which will be logged. Use + severity 0 for errors, 1 for important log messages, 2 for less + important, etc. */ +int nc_log_level = -1; + +#endif /* LOGGING */ + +/* Check and normalize and name. */ +int +nc4_check_name(const char *name, char *norm_name) +{ + char *temp; + int retval; + + /* Check the length. */ + if (strlen(name) > NC_MAX_NAME) + return NC_EMAXNAME; + + /* Make sure this is a valid netcdf name. This should be done + * before the name is normalized, because it gives better error + * codes for bad utf8 strings. */ + if ((retval = NC_check_name(name))) + return retval; + + /* Normalize the name. */ + if (!(temp = (char *)utf8proc_NFC((const unsigned char *)name))) + return NC_EINVAL; + strcpy(norm_name, temp); + free(temp); + + return NC_NOERR; +} + +/* Given a varid, find its shape. For unlimited dimensions, return + the current number of records. */ +static int +find_var_shape_grp(NC_GRP_INFO_T *grp, int varid, int *ndims, + int *dimid, size_t *dimlen) +{ + hid_t datasetid = 0, spaceid = 0; + NC_VAR_INFO_T *var; + hsize_t *h5dimlen = NULL, *h5dimlenmax = NULL; + int d, dataset_ndims = 0; + int retval = NC_NOERR; + + /* Find this var. */ + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + break; + if (!var) + return NC_ENOTVAR; + + /* Get the dimids and the ndims for this var. */ + if (ndims) + *ndims = var->ndims; + + if (dimid) + for (d = 0; d < var->ndims; d++) + dimid[d] = var->dimids[d]; + + if (dimlen) + { + /* If the var hasn't been created yet, its size is 0. */ + if (!var->created) + { + for (d = 0; d < var->ndims; d++) + dimlen[d] = 0; + } + else + { + /* Get the number of records in the dataset. */ + if ((retval = nc4_open_var_grp2(grp, var->varid, &datasetid))) + BAIL(retval); + if ((spaceid = H5Dget_space(datasetid)) < 0) + BAIL(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces++; +#endif + /* If it's a scalar dataset, it has length one. */ + if (H5Sget_simple_extent_type(spaceid) == H5S_SCALAR) + { + dimlen[0] = 1; + } + else + { + /* Check to make sure ndims is right, then get the len of each + dim in the space. */ + if ((dataset_ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) + BAIL(NC_EHDFERR); + if (ndims && dataset_ndims != *ndims) + BAIL(NC_EHDFERR); + if (!(h5dimlen = malloc(dataset_ndims * sizeof(hsize_t)))) + BAIL(NC_ENOMEM); + if (!(h5dimlenmax = malloc(dataset_ndims * sizeof(hsize_t)))) + BAIL(NC_ENOMEM); + if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid, + h5dimlen, h5dimlenmax)) < 0) + BAIL(NC_EHDFERR); + LOG((5, "find_var_shape_nc: varid %d len %d max: %d", + varid, (int)h5dimlen[0], (int)h5dimlenmax[0])); + for (d=0; d 0 && H5Sclose(spaceid) < 0) + BAIL2(NC_EHDFERR); +#ifdef EXTRA_TESTS + num_spaces--; +#endif + if (h5dimlen) free(h5dimlen); + if (h5dimlenmax) free(h5dimlenmax); + return retval; +} + +/* Given an NC_FILE_INFO_T pointer, add the necessary stuff for a + * netcdf-4 file. */ +int +nc4_nc4f_list_add(NC_FILE_INFO_T *nc, const char *path, int mode) +{ + NC_HDF5_FILE_INFO_T *h5; + NC_GRP_INFO_T *grp; + + assert(nc && !nc->nc4_info && path); + + /* The NC_FILE_INFO_T was allocated and inited by + ncfunc.c before this function is called. We need to malloc and + initialize the substructure NC_HDF_FILE_INFO_T. */ + if (!(nc->nc4_info = calloc(1, sizeof(NC_HDF5_FILE_INFO_T)))) + return NC_ENOMEM; + h5 = nc->nc4_info; + + /* Hang on to the filename for nc_abort. */ + if (!(h5->path = malloc((strlen(path) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(h5->path, path); + + /* Hang on to cmode, and note that we're in define mode. */ + h5->cmode = mode | NC_INDEF; + + /* The next_typeid needs to be set beyond the end of our atomic + * types. */ + h5->next_typeid = NC_FIRSTUSERTYPEID; + + /* There's always at least one open group - the root + * group. Allocate space for one group's worth of information. Set + * its hdf id, name, and a pointer to it's file structure. */ + return nc4_grp_list_add(&(h5->root_grp), h5->next_nc_grpid++, + NULL, nc, NC_GROUP_NAME, &grp); +} +/* /\* Given an ncid, find the relevant group and return a pointer to */ +/* * it. *\/ */ +/* NC_GRP_INFO_T * */ +/* find_nc_grp(int ncid) */ +/* { */ +/* NC_FILE_INFO_T *f; */ + +/* for (f = nc_file; f; f = f->next) */ +/* { */ +/* if (f->ext_ncid == (ncid & FILE_ID_MASK)) */ +/* { */ +/* assert(f->nc4_info && f->nc4_info->root_grp); */ +/* return nc4_rec_find_grp(f->nc4_info->root_grp, (ncid & GRP_ID_MASK)); */ +/* } */ +/* } */ + +/* return NULL; */ +/* } */ + +/* Given an ncid, find the relevant group and return a pointer to it, + * return an error of this is not a netcdf-4 file (or if strict nc3 is + * turned on for this file.) */ + + +int +nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp) +{ + NC_FILE_INFO_T *f = nc4_find_nc_file(ncid); + if(f == NULL) return NC_EBADID; + + /* No netcdf-3 files allowed! */ + if (!f->nc4_info) return NC_ENOTNC4; + assert(f->nc4_info->root_grp); + + /* This function demands netcdf-4 files without strict nc3 + * rules.*/ + if (f->nc4_info->cmode & NC_CLASSIC_MODEL) return NC_ESTRICTNC3; + + /* If we can't find it, the grp id part of ncid is bad. */ + if (!(*grp = nc4_rec_find_grp(f->nc4_info->root_grp, (ncid & GRP_ID_MASK)))) + return NC_EBADID; + return NC_NOERR; +} + +/* Given an ncid, find the relevant group and return a pointer to it, + * also set a pointer to the nc4_info struct of the related file. For + * netcdf-3 files, *h5 will be set to NULL. */ +int +nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_HDF5_FILE_INFO_T **h5) +{ + NC_FILE_INFO_T *f = nc4_find_nc_file(ncid); + if(f == NULL) return NC_EBADID; + if (f->nc4_info) { + assert(f->nc4_info->root_grp); + /* If we can't find it, the grp id part of ncid is bad. */ + if (!(*grp = nc4_rec_find_grp(f->nc4_info->root_grp, (ncid & GRP_ID_MASK)))) + return NC_EBADID; + *h5 = (*grp)->file->nc4_info; + assert(*h5); + } else { + *h5 = NULL; + *grp = NULL; + } + return NC_NOERR; +} + +int +nc4_find_nc_grp_h5(int ncid, NC_FILE_INFO_T **nc, NC_GRP_INFO_T **grp, + NC_HDF5_FILE_INFO_T **h5) +{ + NC_FILE_INFO_T *f = nc4_find_nc_file(ncid); + if(f == NULL) return NC_EBADID; + *nc = f; + if (f->nc4_info) { + assert(f->nc4_info->root_grp); + /* If we can't find it, the grp id part of ncid is bad. */ + if (!(*grp = nc4_rec_find_grp(f->nc4_info->root_grp, (ncid & GRP_ID_MASK)))) + return NC_EBADID; + + *h5 = (*grp)->file->nc4_info; + assert(*h5); + } else { + *h5 = NULL; + *grp = NULL; + } + return NC_NOERR; +} + +/* Recursively hunt for a group id. */ +NC_GRP_INFO_T * +nc4_rec_find_grp(NC_GRP_INFO_T *start_grp, int target_nc_grpid) +{ + NC_GRP_INFO_T *g, *res; + + assert(start_grp); + + /* Is this the group we are searching for? */ + if (start_grp->nc_grpid == target_nc_grpid) + return start_grp; + + /* Shake down the kids. */ + if (start_grp->children) + for (g = start_grp->children; g; g = g->next) + if ((res = nc4_rec_find_grp(g, target_nc_grpid))) + return res; + + /* Can't find if. Fate, why do you mock me? */ + return NULL; +} + +/* Given an ncid and varid, get pointers to the group and var + * metadata. */ +int +nc4_find_g_var_nc(NC_FILE_INFO_T *nc, int ncid, int varid, + NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var) +{ + /* Find the group info. */ + assert(grp && var && nc && nc->nc4_info && nc->nc4_info->root_grp); + *grp = nc4_rec_find_grp(nc->nc4_info->root_grp, (ncid & GRP_ID_MASK)); + + /* Find the var info. */ + for ((*var) = (*grp)->var; (*var); (*var) = (*var)->next) + if ((*var)->varid == varid) + break; + if (!(*var)) + return NC_ENOTVAR; + + return NC_NOERR; +} + +/* Find a dim in a grp (or parents). */ +int +nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim, + NC_GRP_INFO_T **dim_grp) +{ + NC_GRP_INFO_T *g, *dg = NULL; + int finished = 0; + + assert(grp && dim); + + /* Find the dim info. */ + for (g = grp; g && !finished; g = g->parent) + for ((*dim) = g->dim; (*dim); (*dim) = (*dim)->next) + if ((*dim)->dimid == dimid) + { + dg = g; + finished++; + break; + } + + /* If we didn't find it, return an error. */ + if (!(*dim)) + return NC_EBADDIM; + + /* Give the caller the group the dimension is in. */ + if (dim_grp) + *dim_grp = dg; + + return NC_NOERR; +} + +/* Recursively hunt for a HDF type id. */ +NC_TYPE_INFO_T * +nc4_rec_find_hdf_type(NC_GRP_INFO_T *start_grp, hid_t target_hdf_typeid) +{ + NC_GRP_INFO_T *g; + NC_TYPE_INFO_T *type, *res; + htri_t equal; + + assert(start_grp); + + /* Does this group have the type we are searching for? */ + for (type = start_grp->type; type; type = type->next) + { + if ((equal = H5Tequal(type->native_typeid ? type->native_typeid : type->hdf_typeid, target_hdf_typeid)) < 0) + return NULL; + if (equal) + return type; + } + + /* Shake down the kids. */ + if (start_grp->children) + for (g = start_grp->children; g; g = g->next) + if ((res = nc4_rec_find_hdf_type(g, target_hdf_typeid))) + return res; + + /* Can't find if. Fate, why do you mock me? */ + return NULL; +} + +/* Recursively hunt for a netCDF type id. */ +NC_TYPE_INFO_T * +nc4_rec_find_nc_type(NC_GRP_INFO_T *start_grp, nc_type target_nc_typeid) +{ + NC_GRP_INFO_T *g; + NC_TYPE_INFO_T *type, *res; + + assert(start_grp); + + /* Does this group have the type we are searching for? */ + for (type = start_grp->type; type; type = type->next) + if (type->nc_typeid == target_nc_typeid) + return type; + + /* Shake down the kids. */ + if (start_grp->children) + for (g = start_grp->children; g; g = g->next) + if ((res = nc4_rec_find_nc_type(g, target_nc_typeid))) + return res; + + /* Can't find if. Fate, why do you mock me? */ + return NULL; +} + +/* Recursively hunt for a netCDF type by name. */ +NC_TYPE_INFO_T * +nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name) +{ + NC_GRP_INFO_T *g; + NC_TYPE_INFO_T *type, *res; + + assert(start_grp); + + /* Does this group have the type we are searching for? */ + for (type = start_grp->type; type; type = type->next) + if (!strcmp(type->name, name)) + return type; + + /* Search subgroups. */ + if (start_grp->children) + for (g = start_grp->children; g; g = g->next) + if ((res = nc4_rec_find_named_type(g, name))) + return res; + + /* Can't find if. Oh, woe is me! */ + return NULL; +} + +/* Use a netCDF typeid to find a type in a type_list. */ +int +nc4_find_type(NC_HDF5_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **type) +{ + if (typeid < 0 || !type) + return NC_EINVAL; + *type = NULL; + + /* Atomic types don't have associated NC_TYPE_INFO_T struct, just + * return NOERR. */ + if (typeid <= NC_STRING) + return NC_NOERR; + + /* Find the type. */ + if(!(*type = nc4_rec_find_nc_type(h5->root_grp, typeid))) + return NC_EBADTYPID; + + return NC_NOERR; +} + +/* Find the actual length of a dim by checking the length of that dim + * in all variables that use it, in grp or children. *len must be + * initialized to zero before this function is called. */ +int +nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len) +{ + NC_GRP_INFO_T *g; + NC_VAR_INFO_T *var; + int d, ndims, dimids[NC_MAX_DIMS]; + size_t dimlen[NC_MAX_DIMS]; + int retval; + + assert(grp && len); + LOG((3, "nc4_find_dim_len: grp->name %s dimid %d", grp->name, dimid)); + + /* If there are any groups, call this function recursively on + * them. */ + for (g = grp->children; g; g = g->next) + if ((retval = nc4_find_dim_len(g, dimid, len))) + return retval; + + /* For all variables in this group, find the ones that use this + * dimension, and remember the max length. */ + for (var = grp->var; var; var = var->next) + { + /* Find dimensions of this var. */ + if ((retval = find_var_shape_grp(grp, var->varid, &ndims, + dimids, dimlen))) + return retval; + + /* Check for any dimension that matches dimid. If found, check + * if its length is longer than *lenp. */ + for (d = 0; d < ndims; d++) + { + if (dimids[d] == dimid) + { + /* Remember the max length in *lenp. */ + **len = dimlen[d] > **len ? dimlen[d] : **len; + break; + } + } + } + + return NC_NOERR; +} + +/* Given a group, find an att. */ +int +nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum, + NC_ATT_INFO_T **att) +{ + NC_VAR_INFO_T *var; + NC_ATT_INFO_T *attlist = NULL; + + assert(grp && grp->name); + LOG((4, "nc4_find_grp_att: grp->name %s varid %d name %s attnum %d", + grp->name, varid, name, attnum)); + + /* Get either the global or a variable attribute list. */ + if (varid == NC_GLOBAL) + attlist = grp->att; + else + { + for(var = grp->var; var; var = var->next) + { + if (var->varid == varid) + { + attlist = var->att; + break; + } + } + if (!var) + return NC_ENOTVAR; + } + + /* Now find the attribute by name or number. If a name is provided, + * ignore the attnum. */ + for (*att = attlist; *att; *att = (*att)->next) + if ((name && !strcmp((*att)->name, name)) || + (!name && (*att)->attnum == attnum)) + return NC_NOERR; + + /* If we get here, we couldn't find the attribute. */ + return NC_ENOTATT; +} + +/* Given an ncid, varid, and name or attnum, find and return pointer + to NC_ATT_INFO_T metadata. */ +int +nc4_find_nc_att(int ncid, int varid, const char *name, int attnum, + NC_ATT_INFO_T **att) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + NC_ATT_INFO_T *attlist = NULL; + int retval; + + LOG((4, "nc4_find_nc_att: ncid 0x%x varid %d name %s attnum %d", + ncid, varid, name, attnum)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + assert(grp && h5); + + /* Get either the global or a variable attribute list. */ + if (varid == NC_GLOBAL) + attlist = grp->att; + else + { + for(var = grp->var; var; var = var->next) + { + if (var->varid == varid) + { + attlist = var->att; + break; + } + } + if (!var) + return NC_ENOTVAR; + } + + /* Now find the attribute by name or number. If a name is provided, ignore the attnum. */ + for (*att = attlist; *att; *att = (*att)->next) + if ((name && !strcmp((*att)->name, name)) || + (!name && (*att)->attnum == attnum)) + return NC_NOERR; + + /* If we get here, we couldn't find the attribute. */ + return NC_ENOTATT; +} + +void +nc4_file_list_free(void) +{ + free_NCList(); +} + + +int +NC4_new_nc(NC** ncpp) +{ + NC_FILE_INFO_T** ncp; + /* Allocate memory for this info. */ + if (!(ncp = calloc(1, sizeof(NC_FILE_INFO_T)))) + return NC_ENOMEM; + if(ncpp) *ncpp = (NC*)ncp; + return NC_NOERR; +} + +int +nc4_file_list_add(NC_FILE_INFO_T** ncp, NC_Dispatch* dispatch) +{ + NC_FILE_INFO_T *nc; + int status = NC_NOERR; + + /* Allocate memory for this info; use the dispatcher to do this */ + status = dispatch->new_nc((NC**)&nc); + if(status) return status; + + /* Add this file to the list. */ + if ((status = add_to_NCList((NC *)nc))) + { + if(nc && nc->ext_ncid > 0) + { + del_from_NCList((NC *)nc); + free(nc); + } + return status; + } + + /* Return a pointer to the new struct. */ + if(ncp) + *ncp = nc; + + return NC_NOERR; +} + +/* Remove a NC_FILE_INFO_T from the linked list. This will nc_free the + memory too. */ +void +nc4_file_list_del(NC_FILE_INFO_T *nc) +{ + /* Remove file from master list. */ + del_from_NCList((NC *)nc); + free(nc); +} + + +/* Given an id, walk the list and find the appropriate + NC_FILE_INFO_T. */ +NC_FILE_INFO_T* +nc4_find_nc_file(int ext_ncid) +{ + return (NC_FILE_INFO_T*)find_in_NCList(ext_ncid); +} + + +/* Add to the end of a var list. Return a pointer to the newly + * added var. */ +int +nc4_var_list_add(NC_VAR_INFO_T **list, NC_VAR_INFO_T **var) +{ + NC_VAR_INFO_T *v; + + /* Allocate storage for new variable. */ + if (!(*var = calloc(1, sizeof(NC_VAR_INFO_T)))) + return NC_ENOMEM; + + /* Go to the end of the list and set the last one to point at our + * new var, or, if the list is empty, our new var becomes the + * list. */ + if(*list) + { + for (v = *list; v; v = v->next) + if (!v->next) + break; + v->next = *var; + (*var)->prev = v; + } + else + *list = *var; + + /* These are the HDF5-1.8.4 defaults. */ + (*var)->chunk_cache_size = nc4_chunk_cache_size; + (*var)->chunk_cache_nelems = nc4_chunk_cache_nelems; + (*var)->chunk_cache_preemption = nc4_chunk_cache_preemption; + + return NC_NOERR; +} + +/* Add to the beginning of a dim list. */ +int +nc4_dim_list_add(NC_DIM_INFO_T **list) +{ + NC_DIM_INFO_T *dim; + if (!(dim = calloc(1, sizeof(NC_DIM_INFO_T)))) + return NC_ENOMEM; + if(*list) + (*list)->prev = dim; + dim->next = *list; + *list = dim; + return NC_NOERR; +} + +/* Add to the beginning of a dim list. */ +int +nc4_dim_list_add2(NC_DIM_INFO_T **list, NC_DIM_INFO_T **new_dim) +{ + NC_DIM_INFO_T *dim; + if (!(dim = calloc(1, sizeof(NC_DIM_INFO_T)))) + return NC_ENOMEM; + if(*list) + (*list)->prev = dim; + dim->next = *list; + *list = dim; + + /* Return pointer to new dimension. */ + if (new_dim) + *new_dim = dim; + return NC_NOERR; +} + +/* Add to the end of an att list. */ +int +nc4_att_list_add(NC_ATT_INFO_T **list) +{ + NC_ATT_INFO_T *att, *a1; + if (!(att = calloc(1, sizeof(NC_ATT_INFO_T)))) + return NC_ENOMEM; + if (*list) + { + for (a1 = *list; a1; a1 = a1->next) + if (!a1->next) + break; + a1->next = att; + att->prev = a1; + } + else + { + *list = att; + } + + return NC_NOERR; +} + +/* Add to the end of a group list. Can't use 0 as a new_nc_grpid - + * it's reserverd for the root group. */ +int +nc4_grp_list_add(NC_GRP_INFO_T **list, int new_nc_grpid, + NC_GRP_INFO_T *parent_grp, NC_FILE_INFO_T *nc, + char *name, NC_GRP_INFO_T **grp) +{ + NC_GRP_INFO_T *g; + + LOG((3, "grp_list_add: new_nc_grpid %d name %s ", + new_nc_grpid, name)); + + /* Get the memory to store this groups info. */ + if (!(*grp = calloc(1, sizeof(NC_GRP_INFO_T)))) + return NC_ENOMEM; + + /* If the list is not NULL, add this group to it. Otherwise, this + * group structure becomes the list. */ + if (*list) + { + /* Move to end of the list. */ + for (g = *list; g; g = g->next) + if (!g->next) + break; + g->next = *grp; /* Add grp to end of list. */ + (*grp)->prev = g; + } + else + { + *list = *grp; + } + + /* Fill in this group's information. */ + (*grp)->nc_grpid = new_nc_grpid; + (*grp)->parent = parent_grp; + if (!((*grp)->name = malloc((strlen(name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy((*grp)->name, name); + (*grp)->file = nc; + + return NC_NOERR; +} + +/* Names for groups, variables, and types must not be the same. This + * function checks that a proposed name is not already in + * use. Normalzation of UTF8 strings should happen before this + * function is called. */ +int +nc4_check_dup_name(NC_GRP_INFO_T *grp, char *name) +{ + NC_TYPE_INFO_T *type; + NC_GRP_INFO_T *g; + NC_VAR_INFO_T *var; + + /* Any types of this name? */ + for (type = grp->type; type; type = type->next) + if (!strcmp(type->name, name)) + return NC_ENAMEINUSE; + + /* Any child groups of this name? */ + for (g = grp->children; g; g = g->next) + if (!strcmp(g->name, name)) + return NC_ENAMEINUSE; + + /* Any variables of this name? */ + for (var = grp->var; var; var = var->next) + if (!strcmp(var->name, name)) + return NC_ENAMEINUSE; + + return NC_NOERR; +} + +/* Add to the end of a type list. */ +int +nc4_type_list_add(NC_TYPE_INFO_T **list, NC_TYPE_INFO_T **new_type) +{ + NC_TYPE_INFO_T *type, *t; + + if (!(type = calloc(1, sizeof(NC_TYPE_INFO_T)))) + return NC_ENOMEM; + + if (*list) + { + for (t = *list; t; t = t->next) + if (!t->next) + break; + t->next = type; + type->prev = t; + } + else + { + *list = type; + } + + if (new_type) + *new_type = type; + + return NC_NOERR; +} + +/* Add to the end of a compound field list. */ +int +nc4_field_list_add(NC_FIELD_INFO_T **list, int fieldid, const char *name, + size_t offset, hid_t field_hdf_typeid, hid_t native_typeid, + nc_type xtype, int ndims, const int *dim_sizesp) +{ + NC_FIELD_INFO_T *field, *f; + int i; + + /* Name has already been checked and UTF8 normalized. */ + if (!name) + return NC_EINVAL; + + /* Allocate storage for this field information. */ + if (!(field = calloc(1, sizeof(NC_FIELD_INFO_T)))) + return NC_ENOMEM; + + /* Add this field to list. */ + if (*list) + { + for (f = *list; f; f = f->next) + if (!f->next) + break; + f->next = field; + field->prev = f; + } + else + { + *list = field; + } + + /* Store the information about this field. */ + field->fieldid = fieldid; + if (!(field->name = malloc((strlen(name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(field->name, name); + field->hdf_typeid = field_hdf_typeid; + field->native_typeid = native_typeid; + field->nctype = xtype; + field->offset = offset; + field->ndims = ndims; + if (ndims) + { + if (!(field->dim_size = malloc(ndims * sizeof(int)))) + return NC_ENOMEM; + for (i = 0; i < ndims; i++) + field->dim_size[i] = dim_sizesp[i]; + } + + return NC_NOERR; +} + +/* Add a member to an enum type. */ +int +nc4_enum_member_add(NC_ENUM_MEMBER_INFO_T **list, size_t size, + const char *name, const void *value) +{ + NC_ENUM_MEMBER_INFO_T *member, *m; + + /* Name has already been checked. */ + assert(name && size > 0 && value); + LOG((4, "nc4_enum_member_add: size %d name %s", size, name)); + + /* Allocate storage for this field information. */ + if (!(member = calloc(1, sizeof(NC_ENUM_MEMBER_INFO_T))) || + !(member->value = calloc(1, size))) + return NC_ENOMEM; + + /* Add this field to list. */ + if (*list) + { + for (m = *list; m; m = m->next) + if (!m->next) + break; + m->next = member; + member->prev = m; + } + else + { + *list = member; + } + + /* Store the information about this member. */ + if (!(member->name = malloc((strlen(name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(member->name, name); + memcpy(member->value, value, size); + + return NC_NOERR; +} + +/* Delete a var from a var list, and free the memory. */ +static int +var_list_del(NC_VAR_INFO_T **list, NC_VAR_INFO_T *var) +{ + NC_ATT_INFO_T *a, *att; + int ret; + + /* First delete all the attributes attached to this var. */ + att = (*list)->att; + while (att) + { + a = att->next; + if ((ret = nc4_att_list_del(&var->att, att))) + return ret; + att = a; + } + + /* Free some things that may be allocated. */ + if (var->chunksizes) + free(var->chunksizes); + if (var->hdf5_name) + free(var->hdf5_name); + if (var->name) + free(var->name); + if (var->dimids) + free(var->dimids); + if (var->dim) + free(var->dim); + + /* Remove the var from the linked list. */ + if(*list == var) + *list = var->next; + else + var->prev->next = var->next; + + if(var->next) + var->next->prev = var->prev; + + /* Delete any fill value allocation. This must be done before the + * type_info is freed. */ + if (var->fill_value) + { + if (var->hdf_datasetid) + { + if (var->type_info->class == NC_VLEN) + nc_free_vlen((nc_vlen_t *)var->fill_value); + else if (var->type_info->nc_typeid == NC_STRING) + free(*(char **)var->fill_value); + } + free(var->fill_value); + } + + /* For atomic types we have allocated space for type information. */ +/* if (var->hdf_datasetid && var->xtype <= NC_STRING)*/ + if (var->xtype <= NC_STRING) + { + if (var->type_info->native_typeid) + if ((H5Tclose(var->type_info->native_typeid)) < 0) + return NC_EHDFERR; + + /* Only need to close the hdf_typeid when it was obtained with + * H5Dget_type (which happens when reading a file, but not when + * creating a variable). */ + if (var->type_info->close_hdf_typeid || var->xtype == NC_STRING) + if ((H5Tclose(var->type_info->hdf_typeid)) < 0) + return NC_EHDFERR; + + /* Free the name. */ + if (var->type_info->name) + free(var->type_info->name); + + free(var->type_info); + } + + /* Delete any HDF5 dimscale objid information. */ + if (var->dimscale_hdf5_objids) + free(var->dimscale_hdf5_objids); + + /* Delete information about the attachment status of dimscales. */ + if (var->dimscale_attached) + free(var->dimscale_attached); + + /* Delete the var. */ + free(var); + + return NC_NOERR; +} + +/* Delete a field from a field list, and nc_free the memory. */ +static void +field_list_del(NC_FIELD_INFO_T **list, NC_FIELD_INFO_T *field) +{ + + /* Take this field out of the list. */ + if(*list == field) + *list = field->next; + else + field->prev->next = field->next; + + if(field->next) + field->next->prev = field->prev; + + /* Free some stuff. */ + if (field->name) + free(field->name); + if (field->dim_size) + free(field->dim_size); + + /* Nc_Free the memory. */ + free(field); +} + +/* Delete a type from a type list, and nc_free the memory. */ +int +type_list_del(NC_TYPE_INFO_T **list, NC_TYPE_INFO_T *type) +{ + NC_FIELD_INFO_T *field, *f; + NC_ENUM_MEMBER_INFO_T *enum_member, *em; + + /* Close any open user-defined HDF5 typieds. */ + if (type->hdf_typeid) + { + if (H5Tclose(type->hdf_typeid) < 0) + return NC_EHDFERR; + } + if (type->native_typeid) + { + if (H5Tclose(type->native_typeid) < 0) + return NC_EHDFERR; + } + + /* Free the name. */ + if (type->name) + free(type->name); + + /* Delete all the fields in this type (there will be some if its a + * compound). */ + field = type->field; + while (field) + { + f = field->next; + field_list_del(&type->field, field); + field = f; + } + + /* Delete all the enum_members, if any. */ + enum_member = type->enum_member; + while (enum_member) + { + em = enum_member->next; + free(enum_member->value); + free(enum_member->name); + free(enum_member); + enum_member = em; + } + + /* Take this type out of the list. */ + if(*list == type) + *list = type->next; + else + type->prev->next = type->next; + + if(type->next) + type->next->prev = type->prev; + + /* Nc_Free the memory. */ + free(type); + + return NC_NOERR; +} + +/* Delete a del from a var list, and nc_free the memory. */ +int +nc4_dim_list_del(NC_DIM_INFO_T **list, NC_DIM_INFO_T *dim) +{ + /* Take this dimension out of the list. */ + if(*list == dim) + *list = dim->next; + else + dim->prev->next = dim->next; + + if(dim->next) + dim->next->prev = dim->prev; + + /* Free memory allocated for names. */ + if (dim->name) + free(dim->name); + if (dim->old_name) + free(dim->old_name); + + free(dim); + return NC_NOERR; +} + +/* Remove a NC_GRP_INFO_T from the linked list. This will nc_free the + memory too. */ +static void +grp_list_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp) +{ + if(*list == grp) + *list = grp->next; + else + grp->prev->next = grp->next; + + if(grp->next) + grp->next->prev = grp->prev; + + free(grp); +} + +/* Recursively delete the data for a group (and everything it + * contains) in our internal metadata store. */ +int +nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp) +{ + NC_GRP_INFO_T *g, *c; + NC_VAR_INFO_T *v, *var; + NC_ATT_INFO_T *a, *att; + NC_DIM_INFO_T *d, *dim; + NC_TYPE_INFO_T *type, *t; + int retval; + + assert(grp); + LOG((3, "nc4_rec_grp_del: grp->name %s", grp->name)); + + /* Recursively call this function for each child, if any, stopping + * if there is an error. */ + g = grp->children; + while(g) + { + c = g->next; + if ((retval = nc4_rec_grp_del(&(grp->children), g))) + return retval; + g = c; + } + + /* Delete all the list contents for vars, dims, and atts, in each + * group. */ + att = grp->att; + while (att) + { + LOG((4, "nc4_rec_grp_del: deleting att %s", att->name)); + a = att->next; + if ((retval = nc4_att_list_del(&grp->att, att))) + return retval; + att = a; + } + + /* Delete all vars. */ + var = grp->var; + while (var) + { + LOG((4, "nc4_rec_grp_del: deleting var %s", var->name)); + /* Close HDF5 dataset associated with this var, unless it's a + * scale. */ + if (var->hdf_datasetid && !var->dimscale && + H5Dclose(var->hdf_datasetid) < 0) + return NC_EHDFERR; + v = var->next; + if ((retval = var_list_del(&grp->var, var))) + return retval; + var = v; + } + + /* Delete all dims. */ + dim = grp->dim; + while (dim) + { + LOG((4, "nc4_rec_grp_del: deleting dim %s", dim->name)); + /* Close HDF5 dataset associated with this dim. */ + if (dim->hdf_dimscaleid && H5Dclose(dim->hdf_dimscaleid) < 0) + return NC_EHDFERR; + d = dim->next; + if ((retval = nc4_dim_list_del(&grp->dim, dim))) + return retval; + dim = d; + } + + /* Delete all types. */ + type = grp->type; + while (type) + { + LOG((4, "nc4_rec_grp_del: deleting type %s", type->name)); + t = type->next; + if ((retval = type_list_del(&grp->type, type))) + return retval; + type = t; + } + + /* Tell HDF5 we're closing this group. */ + LOG((4, "nc4_rec_grp_del: closing group %s", grp->name)); + if (grp->hdf_grpid && H5Gclose(grp->hdf_grpid) < 0) + return NC_EHDFERR; + + /* Free the name. */ + free(grp->name); + + /* Finally, redirect pointers around this entry in the list, and + * nc_free its memory. */ + grp_list_del(list, grp); + + return NC_NOERR; +} + +/* Remove a NC_ATT_INFO_T from the linked list. This will nc_free the + memory too. +*/ +int +nc4_att_list_del(NC_ATT_INFO_T **list, NC_ATT_INFO_T *att) +{ + int i; + + /* Take this att out of the list. */ + if(*list == att) + *list = att->next; + else + att->prev->next = att->next; + + if(att->next) + att->next->prev = att->prev; + + /* Free memory that was malloced to hold data for this + * attribute. */ + if (att->data) + free(att->data); + + /* Free the name. */ + if (att->name) + free(att->name); + + /* Close the HDF5 typeid. */ + if (att->native_typeid && H5Tclose(att->native_typeid) < 0) + return NC_EHDFERR; + + /* If this is a string array attribute, delete all members of the + * string array, then delete the array of pointers to strings. (The + * array was filled with pointers by HDF5 when the att was read, + * and memory for each string was allocated by HDF5. That's why I + * use free and not nc_free, because the netCDF library didn't + * allocate the memory that is being freed.) */ + if (att->stdata) + { + for (i = 0; i < att->len; i++) + free(att->stdata[i]); + free(att->stdata); + } + + /* If this att has vlen data, release it. */ + if (att->vldata) + { + for (i = 0; i < att->len; i++) + nc_free_vlen(&att->vldata[i]); + free(att->vldata); + } + + free(att); + return NC_NOERR; +} + +/* Normalize a UTF8 name. Put the result in norm_name, which can be + * NC_MAX_NAME + 1 in size. This function makes sure the free() gets + * called on the return from utf8proc_NFC, and also ensures that the + * name is not too long. */ +int +nc4_normalize_name(const char *name, char *norm_name) +{ + char *temp_name; + if (!(temp_name = (char *)utf8proc_NFC((const unsigned char *)name))) + return NC_EINVAL; + if (strlen(temp_name) > NC_MAX_NAME) + { + free(temp_name); + return NC_EMAXNAME; + } + strcpy(norm_name, temp_name); + free(temp_name); + return NC_NOERR; +} + +/* Print out a bunch of info to stderr about the metadata for + debugging purposes. */ +#ifdef LOGGING +/* Use this to set the global log level. Set it to NC_TURN_OFF_LOGGING + (-1) to turn off all logging. Set it to 0 to show only errors, and + to higher numbers to show more and more logging details. */ +int +nc_set_log_level(int new_level) +{ + /* If the user wants to completely turn off logging, turn off HDF5 + logging too. Now I truely can't think of what to do if this + fails, so just ignore the return code. */ + if (new_level == NC_TURN_OFF_LOGGING) + { + H5Eset_auto(NULL, NULL); + LOG((1, "HDF5 error messages turned off!")); + } + + /* Do we need to turn HDF5 logging back on? */ + if (new_level > NC_TURN_OFF_LOGGING && + nc_log_level <= NC_TURN_OFF_LOGGING) + { + if (H5Eset_auto((H5E_auto_t)&H5Eprint, stderr) < 0) + LOG((0, "H5Eset_auto failed!")); + LOG((1, "HDF5 error messages turned on.")); + } + + /* Now remember the new level. */ + nc_log_level = new_level; + LOG((4, "log_level changed to %d", nc_log_level)); + return 0; +} + +/* Recursively print the metadata of a group. */ +#define MAX_NESTS 10 +static int +rec_print_metadata(NC_GRP_INFO_T *grp, int *tab_count) +{ + NC_GRP_INFO_T *g; + NC_ATT_INFO_T *att; + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim; + NC_TYPE_INFO_T *type; + NC_FIELD_INFO_T *field; + char tabs[MAX_NESTS] = ""; + char dims_string[NC_MAX_DIMS*4]; + char temp_string[10]; + int t, retval, d; + + /* Come up with a number of tabs relative to the group. */ + for (t = 0; t < *tab_count && t < MAX_NESTS; t++) + strcat(tabs, "\t"); + + LOG((2, "%s GROUP - %s nc_grpid: %d nvars: %d natts: %d", + tabs, grp->name, grp->nc_grpid, grp->nvars, grp->natts)); + + for(att = grp->att; att; att = att->next) + LOG((2, "%s GROUP ATTRIBUTE - attnum: %d name: %s type: %d len: %d", + tabs, att->attnum, att->name, att->xtype, att->len)); + + /* To display dims starting with 0 and going up, go through list is + * reverse order. */ + for(dim = grp->dim; dim && dim->next; dim = dim->next) + ; + for( ; dim; dim = dim->prev) + LOG((2, "%s DIMENSION - dimid: %d name: %s len: %d unlimited: %d", + tabs, dim->dimid, dim->name, dim->len, dim->unlimited)); + + /* To display vars starting with 0 and going up, go through list is + * reverse order. */ + for(var = grp->var; var && var->next; var = var->next) + ; + for( ; var; var = var->prev) + { + strcpy(dims_string, ""); + for (d = 0; d < var->ndims; d++) + { + sprintf(temp_string, " %d", var->dimids[d]); + strcat(dims_string, temp_string); + } + LOG((2, "%s VARIABLE - varid: %d name: %s type: %d ndims: %d dimscale: %d dimids:%s", + tabs, var->varid, var->name, var->xtype, var->ndims, var->dimscale, + dims_string)); + for(att = var->att; att; att = att->next) + LOG((2, "%s VAR ATTRIBUTE - attnum: %d name: %s type: %d len: %d", + tabs, att->attnum, att->name, att->xtype, att->len)); + } + + for (type = grp->type; type; type = type->next) + { + LOG((2, "%s TYPE - nc_typeid: %d hdf_typeid: 0x%x size: %d committed: %d " + "name: %s num_fields: %d base_nc_type: %d", tabs, type->nc_typeid, + type->hdf_typeid, type->size, type->committed, type->name, + type->num_fields, type->base_nc_type)); + /* Is this a compound type? */ + if (type->class == NC_COMPOUND) + { + LOG((3, "compound type")); + for (field = type->field; field; field = field->next) + LOG((4, "field %s offset %d nctype %d ndims %d", field->name, + field->offset, field->nctype, field->ndims)); + } + else if (type->class == NC_VLEN) + LOG((3, "VLEN type")); + else if (type->class == NC_OPAQUE) + LOG((3, "Opaque type")); + else if (type->class == NC_ENUM) + LOG((3, "Enum type")); + else + { + LOG((0, "Unknown class: %d", type->class)); + return NC_EBADTYPE; + } + } + + /* Call self for each child of this group. */ + if (grp->children) + { + (*tab_count)++; + for (g = grp->children; g; g = g->next) + if ((retval = rec_print_metadata(g, tab_count))) + return retval; + (*tab_count)--; + } + + return NC_NOERR; +} + +/* Print out the internal metadata for a file. This is useful to check + * that netCDF is working! Nonetheless, this function will print + * nothing if logging is not set to at least two. */ +int +log_metadata_nc(NC_FILE_INFO_T *nc) +{ + NC_HDF5_FILE_INFO_T *h5 = nc->nc4_info; + int tab_count = 0; + + LOG((2, "*** NetCDF-4 Internal Metadata: int_ncid 0x%x ext_ncid 0x%x", + nc->int_ncid, nc->ext_ncid)); + if (!h5) + { + LOG((2, "This is a netCDF-3 file.")); + return NC_NOERR; + } + LOG((2, "FILE - hdfid: 0x%x path: %s cmode: 0x%x parallel: %d redef: %d " + "fill_mode: %d no_write: %d next_nc_grpid: %d", h5->hdfid, h5->path, + h5->cmode, h5->parallel, h5->redef, h5->fill_mode, h5->no_write, + h5->next_nc_grpid)); + return rec_print_metadata(h5->root_grp, &tab_count); +} + +#endif /*LOGGING */ + +/* Show the in-memory metadata for a netcdf file. */ +int +NC4_show_metadata(int ncid) +{ + int retval = NC_NOERR; +#ifdef LOGGING + NC_FILE_INFO_T *nc; + int old_log_level = nc_log_level; + + /* Find file metadata. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + + /* Log level must be 2 to see metadata. */ + nc_log_level = 2; + retval = log_metadata_nc(nc); + nc_log_level = old_log_level; +#endif /*LOGGING*/ + return retval; +} + diff --git a/extern/src_netcdf4/nc4internal.h b/extern/src_netcdf4/nc4internal.h new file mode 100644 index 0000000000000000000000000000000000000000..3e6cc83480456901f2f64e2ee49173a68413f6c9 --- /dev/null +++ b/extern/src_netcdf4/nc4internal.h @@ -0,0 +1,425 @@ +/** \file + This header file contains the definitions of structs used to hold + netCDF file metadata in memory. + + Copyright 2005-2011 University Corporation for Atmospheric + Research/Unidata. +*/ + +#ifndef _NC4INTERNAL_ +#define _NC4INTERNAL_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_PARALLEL +#include +#else +#define MPI_Info int +#define MPI_Comm int +#include +#endif /* USE_PARALLEL */ +#include + +#ifdef USE_HDF4 +#include +#endif + +#define FILE_ID_MASK (0xffff0000) +#define GRP_ID_MASK (0x0000ffff) +#define ID_SHIFT (16) + +typedef enum {GET, PUT} NC_PG_T; +typedef enum {VAR, DIM, ATT} NC_OBJ_T; + +#define NC_MAX_HDF5_NAME (NC_MAX_NAME + 10) +#define NC_V2_ERR (-1) + +/* The name of the root group. */ +#define NC_GROUP_NAME "/" + +#define MEGABYTE 1048576 + +/* + * limits of the external representation + */ +#define X_SCHAR_MIN (-128) +#define X_SCHAR_MAX 127 +#define X_UCHAR_MAX 255U +#define X_SHORT_MIN (-32768) +#define X_SHRT_MIN X_SHORT_MIN /* alias compatible with limits.h */ +#define X_SHORT_MAX 32767 +#define X_SHRT_MAX X_SHORT_MAX /* alias compatible with limits.h */ +#define X_USHORT_MAX 65535U +#define X_USHRT_MAX X_USHORT_MAX /* alias compatible with limits.h */ +#define X_INT_MIN (-2147483647-1) +#define X_INT_MAX 2147483647 +#define X_LONG_MIN X_INT_MIN +#define X_LONG_MAX X_INT_MAX +#define X_UINT_MAX 4294967295U +#ifdef WIN32 /* Windows, of course, has to be a *little* different. */ +#define X_FLOAT_MAX 3.402823466e+38f +#else +#define X_FLOAT_MAX 3.40282347e+38f +#endif /* WIN32 */ +#define X_FLOAT_MIN (-X_FLOAT_MAX) +#define X_DOUBLE_MAX 1.7976931348623157e+308 +#define X_DOUBLE_MIN (-X_DOUBLE_MAX) + +/* These have to do with creating chuncked datasets in HDF5. */ +#define NC_HDF5_UNLIMITED_DIMSIZE (0) +#define NC_HDF5_CHUNKSIZE_FACTOR (10) +#define NC_HDF5_MIN_CHUNK_SIZE (2) + +#define NC_EMPTY_SCALE "NC_EMPTY_SCALE" + +/* This is an attribute I had to add to handle multidimensional + * coordinate variables. */ +#define COORDINATES "_Netcdf4Coordinates" +#define COORDINATES_LEN (NC_MAX_NAME * 5) + +/* This is used when the user defines a non-coordinate variable with + * same name as a dimension. */ +#define NON_COORD_PREPEND "_nc4_non_coord_" + +/* An attribute in the HDF5 root group of this name means that the + * file must follow strict netCDF classic format rules. */ +#define NC3_STRICT_ATT_NAME "_nc3_strict" + +/* If this attribute is present on a dimscale variable, use the value + * as the netCDF dimid. */ +#define NC_DIMID_ATT_NAME "_Netcdf4Dimid" + +/* This is a struct to handle the dim metadata. */ +typedef struct NC_DIM_INFO +{ + char *name; + size_t len; + int dimid; + int unlimited; + int extended; + struct NC_DIM_INFO *next; + struct NC_DIM_INFO *prev; + hid_t hdf_dimscaleid; + char *old_name; /* only used to rename dim */ + int dirty; + unsigned char coord_var_in_grp; + struct NC_VAR_INFO *coord_var; /* The coord var, if it exists. */ + int too_long; /* True if len it too big to fit in local size_t. */ +} NC_DIM_INFO_T; + +typedef struct NC_ATT_INFO +{ + int len; + char *name; + struct NC_ATT_INFO *next; + struct NC_ATT_INFO *prev; + int dirty; + int created; + nc_type xtype; + hid_t native_typeid; + int attnum; + void *data; + nc_vlen_t *vldata; /* only used for vlen */ + char **stdata; /* only for string type. */ + int class; +} NC_ATT_INFO_T; + +/* This is a struct to handle the var metadata. */ +typedef struct NC_VAR_INFO +{ + char *name; + char *hdf5_name; /* used if different from name */ + int ndims; + int *dimids; + NC_DIM_INFO_T **dim; + int varid; + int natts; + struct NC_VAR_INFO *next; + struct NC_VAR_INFO *prev; + int dirty; + int created; + int written_to; + int *dimscale_attached; + struct NC_TYPE_INFO *type_info; + nc_type xtype; + hid_t hdf_datasetid; + NC_ATT_INFO_T *att; + int no_fill; + void *fill_value; + size_t *chunksizes; + int contiguous; + int parallel_access; + int dimscale; + HDF5_OBJID_T *dimscale_hdf5_objids; + int deflate; + int deflate_level; + int shuffle; + int fletcher32; + int options_mask; + int pixels_per_block; + size_t chunk_cache_size, chunk_cache_nelems; + float chunk_cache_preemption; + /* Stuff below is for hdf4 files. */ + int sdsid; + int hdf4_data_type; + /* Stuff below for diskless data files. */ + void *diskless_data; +} NC_VAR_INFO_T; + +typedef struct NC_FIELD_INFO +{ + struct NC_FIELD_INFO *next; + struct NC_FIELD_INFO *prev; + nc_type nctype; + hid_t hdf_typeid; + hid_t native_typeid; + size_t offset; + char *name; + int fieldid; + int ndims; + int *dim_size; +} NC_FIELD_INFO_T; + +typedef struct NC_ENUM_MEMBER_INFO +{ + struct NC_ENUM_MEMBER_INFO *next; + struct NC_ENUM_MEMBER_INFO *prev; + char *name; + void *value; +} NC_ENUM_MEMBER_INFO_T; + +typedef struct NC_TYPE_INFO +{ + struct NC_TYPE_INFO *next; + struct NC_TYPE_INFO *prev; + nc_type nc_typeid; + hid_t hdf_typeid; + hid_t native_typeid; + size_t size; + int committed; /* What the pig is, but the hen isn't, at breakfast. */ + char *name; + int class; /* NC_VLEN, NC_COMPOUND, NC_OPAQUE, or NC_ENUM */ + int num_enum_members; + NC_ENUM_MEMBER_INFO_T *enum_member; + NC_FIELD_INFO_T *field; /* Used for compound types. */ + int num_fields; + nc_type base_nc_type; /* for VLEN and ENUM only */ + hid_t base_hdf_typeid; /* for VLEN only */ + int close_hdf_typeid; /* True when hdf_typeid must be H5Tclosed. */ + int endianness; +} NC_TYPE_INFO_T; + +/* This holds information for one group. Groups reproduce with + * parthenogenesis. */ +typedef struct NC_GRP_INFO +{ + int nc_grpid; + struct NC_GRP_INFO *parent; + struct NC_GRP_INFO *children; + struct NC_GRP_INFO *next; /* points to siblings */ + struct NC_GRP_INFO *prev; /* points to siblings */ + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim; + NC_ATT_INFO_T *att; + int nvars; + int ndims; + int natts; + struct NC_FILE_INFO *file; + char *name; + hid_t hdf_grpid; + NC_TYPE_INFO_T *type; +} NC_GRP_INFO_T; + +/* These constants apply to the cmode parameter in the + * HDF5_FILE_INFO_T defined below. */ +#define NC_CREAT 2 /* in create phase, cleared by ncendef */ +#define NC_INDEF 8 /* in define mode, cleared by ncendef */ +#define NC_NSYNC 0x10 /* synchronise numrecs on change */ +#define NC_HSYNC 0x20 /* synchronise whole header on change */ +#define NC_NDIRTY 0x40 /* numrecs has changed */ +#define NC_HDIRTY 0x80 /* header info has changed */ + +/* This is the metadata we need to keep track of for each + netcdf-4/HDF5 file. */ +typedef struct +{ + hid_t hdfid; + int flags; + int cmode; + int nvars; + int ndims; + int natts; + int parallel; /* true if file is open for parallel access */ + int redef; + char *path; + int fill_mode; + int no_write; /* true if nc_open has mode NC_NOWRITE. */ + NC_GRP_INFO_T *root_grp; + short next_nc_grpid; + NC_TYPE_INFO_T *type; + int next_typeid; + int next_dimid; + int ignore_creationorder; + int hdf4; + int sdid; +} NC_HDF5_FILE_INFO_T; + +/* In the nc_file array there will be one entry for each open file.*/ + + /* There's an external ncid (ext_ncid) and an internal ncid + * (int_ncid). The ext_ncid is the ncid returned to the user. If + * the user has opened or created a netcdf-4 file, then the + * ext_ncid is the same as the int_ncid. If he has opened or + * created a netcdf-3 file ext_ncid (which the user sees) is + * different from the int_ncid, which is the ncid returned by the + * netcdf-3 layer, which insists on inventing its own ncids, + * regardless of what is already in use due to previously opened + * netcdf-4 files. The ext_ncid contains the ncid for the root + * group (i.e. group zero). */ + +/* Warning: fields from BEGIN COMMON to END COMMON must be same for: + 1. NCcommon (include/ncdispatch.h) + 2. NC (libsrc/nc.h) + 3. NC_FILE_INFO (libsrc4/nc4internal.h) + 4. whatever libdiskless uses +*/ +typedef struct NC_FILE_INFO +{ +/*BEGIN COMMON*/ + int ext_ncid; + int int_ncid; + struct NC_Dispatch* dispatch; + void* dispatchdata; + char* path; + int substrate; +/*END COMMON*/ + +#ifdef USE_PNETCDF + /* pnetcdf_file will be true if the file is created/opened with the + * parallel-netcdf library. pnetcdf_access_mode keeps track of + * whether independpent or collective mode is + * desired. pnetcdf_ndims keeps track of how many dims each var + * has, which I need to know to convert start, count, and stride + * arrays from size_t to MPI_Offset. (I can't use an inq function + * to find out the number of dims, because these are collective in + * pnetcdf.) */ + int pnetcdf_file; + int pnetcdf_access_mode; + int pnetcdf_ndims[NC_MAX_VARS]; +#endif /* USE_PNETCDF */ + + /* The nc4_info pointer will remain NULL for netcdf3 files, + * otherwise it points to information about the netcdf-4 file. */ + NC_HDF5_FILE_INFO_T *nc4_info; +} NC_FILE_INFO_T; + +/* These functions only use the netcdf API calls, so they will work on + both new format and old format files. */ +/*int copy_dataset(int ncid_in, int ncid_out);*/ + + +/* These functions convert beteen netcdf and HDF5 types. */ +int nc4_get_typelen_mem(NC_HDF5_FILE_INFO_T *h5, nc_type xtype, + int is_long, size_t *len); +int nc4_convert_type(const void *src, void *dest, + const nc_type src_type, const nc_type dest_type, + const size_t len, int *range_error, + const void *fill_value, int strict_nc3, int src_long, + int dest_long); + +/* These functions do HDF5 things. */ +int nc4_open_var_grp2(NC_GRP_INFO_T *grp, int varid, hid_t *dataset); +int pg_var(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, nc_type xtype, int is_long, + void *ip); +int nc4_pg_var1(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *indexp, + nc_type xtype, int is_long, void *ip); +int nc4_put_vara(NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp, + const size_t *countp, nc_type xtype, int is_long, void *op); +int nc4_get_vara(NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp, + const size_t *countp, nc_type xtype, int is_long, void *op); +int nc4_pg_varm(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, nc_type xtype, int is_long, void *op); +int nc4_rec_match_dimscales(NC_GRP_INFO_T *grp); +int nc4_rec_write_metadata(NC_GRP_INFO_T *grp); +int nc4_rec_write_types(NC_GRP_INFO_T *grp); +int nc4_enddef_netcdf4_file(NC_HDF5_FILE_INFO_T *h5); +int nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var); +int nc4_adjust_var_cache(NC_GRP_INFO_T *grp, NC_VAR_INFO_T * var); + +/* The following functions manipulate the in-memory linked list of + metadata, without using HDF calls. */ +int nc4_find_nc_grp_h5(int ncid, NC_FILE_INFO_T **nc, NC_GRP_INFO_T **grp, + NC_HDF5_FILE_INFO_T **h5); +int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_HDF5_FILE_INFO_T **h5); +int nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp); +NC_GRP_INFO_T *nc4_find_nc_grp(int ncid); +NC_GRP_INFO_T *nc4_rec_find_grp(NC_GRP_INFO_T *start_grp, int target_nc_grpid); +NC_FILE_INFO_T *nc4_find_nc_file(int ncid); +int nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim, NC_GRP_INFO_T **dim_grp); +int nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len); +int nc4_find_type(NC_HDF5_FILE_INFO_T *h5, int typeid, NC_TYPE_INFO_T **type); +NC_TYPE_INFO_T *nc4_rec_find_nc_type(NC_GRP_INFO_T *start_grp, hid_t target_nc_typeid); +NC_TYPE_INFO_T *nc4_rec_find_hdf_type(NC_GRP_INFO_T *start_grp, hid_t target_hdf_typeid); +NC_TYPE_INFO_T *nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name); +NC_TYPE_INFO_T *nc4_rec_find_equal_type(NC_GRP_INFO_T *start_grp, int ncid1, NC_TYPE_INFO_T *type); +int nc4_find_nc_att(int ncid, int varid, const char *name, int attnum, + NC_ATT_INFO_T **att); +int nc4_find_g_var_nc(NC_FILE_INFO_T *nc, int ncid, int varid, + NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var); +int nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum, + NC_ATT_INFO_T **att); +int nc4_get_hdf_typeid(NC_HDF5_FILE_INFO_T *h5, nc_type xtype, + hid_t *hdf_typeid, int endianness); +/*int var_info_nc(NC_PG_T pg, hid_t dataset, NC_VAR_INFO_T *var_info);*/ + +/* These list functions add and delete vars, atts, and files. */ +int nc4_file_list_add(NC_FILE_INFO_T**, struct NC_Dispatch*); +void nc4_file_list_free(void); + +int nc4_nc4f_list_add(NC_FILE_INFO_T *nc, const char *path, int mode); +int nc4_var_list_add(NC_VAR_INFO_T **list, NC_VAR_INFO_T **var); +int nc4_dim_list_add(NC_DIM_INFO_T **list); +int nc4_dim_list_del(NC_DIM_INFO_T **list, NC_DIM_INFO_T *dim); +int nc4_att_list_add(NC_ATT_INFO_T **list); +int nc4_type_list_add(NC_TYPE_INFO_T **list, NC_TYPE_INFO_T **new_type); +int nc4_field_list_add(NC_FIELD_INFO_T **list, int fieldid, const char *name, + size_t offset, hid_t field_hdf_typeid, hid_t native_typeid, + nc_type xtype, int ndims, const int *dim_sizesp); +void nc4_file_list_del(NC_FILE_INFO_T *nc); +int nc4_att_list_del(NC_ATT_INFO_T **list, NC_ATT_INFO_T *att); +int nc4_grp_list_add(NC_GRP_INFO_T **list, int new_nc_grpid, NC_GRP_INFO_T *parent_grp, + NC_FILE_INFO_T *nc, char *name, NC_GRP_INFO_T **grp); +int nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp); +int nc4_enum_member_add(NC_ENUM_MEMBER_INFO_T **list, size_t size, + const char *name, const void *value); + +int NC_check_name(const char *name); + +/* Check and normalize names. */ +int nc4_check_name(const char *name, char *norm_name); +int nc4_normalize_name(const char *name, char *norm_name); + +/* Check for name collisions. */ +int nc4_check_dup_name(NC_GRP_INFO_T *grp, char *norm_name); + +/* Insert and read one element into an already allocated vlen array + * element (this is for F77). */ +/*int nc_put_vlen_element(int ncid, int typeid, void *vlen_element, size_t len, const void *data); + int nc_get_vlen_element(int ncid, int typeid, const void *vlen_element, size_t *len, void *data);*/ + +/* This is only included if --enable-logging is used for configure; it + prints info about the metadata to stderr. */ +#ifdef LOGGING +int log_metadata_nc(NC_FILE_INFO_T *nc); +#endif + +#endif /* _NETCDF4_ */ diff --git a/extern/src_netcdf4/nc4type.c b/extern/src_netcdf4/nc4type.c new file mode 100644 index 0000000000000000000000000000000000000000..d57a5aa4abb5caf22f800987d2402205b9a16414 --- /dev/null +++ b/extern/src_netcdf4/nc4type.c @@ -0,0 +1,741 @@ +/* + +This file is part of netcdf-4, a netCDF-like interface for HDF5, or a +HDF5 backend for netCDF, depending on your point of view. + +This file handles the nc4 user-defined type functions (i.e. compound +and opaque types). + +Copyright 2005, University Corporation for Atmospheric Research. See +the COPYRIGHT file for copying and redistribution conditions. + +$Id: nc4type.c,v 1.73 2010/05/25 17:54:24 dmh Exp $ +*/ + +#include "nc4internal.h" + +#define NUM_ATOMIC_TYPES 13 +char atomic_name[NUM_ATOMIC_TYPES][NC_MAX_NAME + 1] = {"none", "byte", "char", + "short", "int", "float", + "double", "ubyte", + "ushort", "uint", + "int64", "uint64", "string"}; + +EXTERNL int +NC4_inq_type_equal(int ncid1, nc_type typeid1, int ncid2, + nc_type typeid2, int *equalp) +{ + NC_GRP_INFO_T *grp1, *grp2; + NC_TYPE_INFO_T *type1, *type2; + int retval; + + LOG((2, "nc_inq_type_equal: ncid1 0x%x typeid1 %d ncid2 0x%x typeid2 %d", + ncid1, typeid1, ncid2, typeid2)); + + /* Check input. */ + if(equalp == NULL) return NC_NOERR; + + if (typeid1 <= NC_NAT || typeid2 <= NC_NAT) + return NC_EINVAL; + + /* If one is atomic, and the other user-defined, the types are not + * equal. */ + if ((typeid1 <= NC_STRING && typeid2 > NC_STRING) || + (typeid2 <= NC_STRING && typeid1 > NC_STRING)) + { + if (equalp) *equalp = 0; + return NC_NOERR; + } + + /* If both are atomic types, the answer is easy. */ + if (typeid1 <= NUM_ATOMIC_TYPES) + { + if (equalp) + { + if (typeid1 == typeid2) + *equalp = 1; + else + *equalp = 0; + } + return NC_NOERR; + } + + /* Not atomic types - so find type1 and type2 information. */ + if ((retval = nc4_find_nc4_grp(ncid1, &grp1))) + return retval; + if (!(type1 = nc4_rec_find_nc_type(grp1->file->nc4_info->root_grp, + typeid1))) + return NC_EBADTYPE; + if ((retval = nc4_find_nc4_grp(ncid2, &grp2))) + return retval; + if (!(type2 = nc4_rec_find_nc_type(grp2->file->nc4_info->root_grp, + typeid2))) + return NC_EBADTYPE; + + /* Are the two types equal? */ + if (equalp) + *equalp = (int)H5Tequal(type1->native_typeid, type2->native_typeid); + + return NC_NOERR; +} + +/* Get the id of a type from the name. */ +EXTERNL int +NC4_inq_typeid(int ncid, const char *name, nc_type *typeidp) +{ + NC_GRP_INFO_T *grp, *grp2; + NC_HDF5_FILE_INFO_T *h5; + NC_TYPE_INFO_T *type = NULL; + char *norm_name; + int i, retval; + + for (i = 0; i < NUM_ATOMIC_TYPES; i++) + if (!strcmp(name, atomic_name[i])) + { + if (typeidp) + *typeidp = i; + return NC_NOERR; + } + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + + /* Must be a netCDF-4 file. */ + if (!h5) + return NC_ENOTNC4; + + /* If the first char is a /, this is a fully-qualified + * name. Otherwise, this had better be a local name (i.e. no / in + * the middle). */ + if (name[0] != '/' && strstr(name, "/")) + return NC_EINVAL; + + /* Normalize name. */ + if (!(norm_name = malloc(strlen(name) + 1))) + return NC_ENOMEM; + if ((retval = nc4_normalize_name(name, norm_name))) + return retval; + + /* Is the type in this group? If not, search parents. */ + for (grp2 = grp; grp2; grp2 = grp2->parent) + for (type = grp2->type; type; type = type->next) + if (!strcmp(norm_name, type->name)) + { + if (typeidp) + *typeidp = type->nc_typeid; + break; + } + + /* Still didn't find type? Search file recursively, starting at the + * root group. */ + if (!type) + if ((type = nc4_rec_find_named_type(grp->file->nc4_info->root_grp, norm_name))) + if (typeidp) + *typeidp = type->nc_typeid; + + free(norm_name); + + /* OK, I give up already! */ + if (!type) + return NC_EBADTYPE; + + return NC_NOERR; +} + +/* Find all user-defined types for a location. This finds all + * user-defined types in a group. */ +int +NC4_inq_typeids(int ncid, int *ntypes, int *typeids) +{ + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_TYPE_INFO_T *type; + int num = 0; + int retval; + + LOG((2, "nc_inq_typeids: ncid 0x%x", ncid)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + + /* If this is a netCDF-4 file, count types. */ + if (h5 && grp->type) + for (type = grp->type; type; type = type->next) + { + if (typeids) + typeids[num] = type->nc_typeid; + num++; + } + + /* Give the count to the user. */ + if (ntypes) + *ntypes = num; + + return NC_NOERR; +} + + +/* This internal function adds a new user defined type to the metadata + * of a group of an open file. */ +static int +add_user_type(int ncid, size_t size, const char *name, nc_type base_typeid, + nc_type type_class, nc_type *typeidp) +{ + NC_HDF5_FILE_INFO_T *h5; + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type; + char norm_name[NC_MAX_NAME + 1]; + int retval; + + /* Check and normalize the name. */ + if ((retval = nc4_check_name(name, norm_name))) + return retval; + + LOG((2, "add_user_type: ncid 0x%x size %d name %s base_typeid %d ", + ncid, size, norm_name, base_typeid)); + + /* Find group metadata. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + + /* Only netcdf-4 files! */ + if (!h5) + return NC_ENOTNC4; + + /* Turn on define mode if it is not on. */ + if (!(h5->cmode & NC_INDEF)) + if ((retval = nc_redef(ncid))) + return retval; + + /* No size is provided for vlens or enums, get it from the base type. */ + if (type_class == NC_VLEN || type_class == NC_ENUM) + { + if ((retval = nc4_get_typelen_mem(grp->file->nc4_info, base_typeid, 0, + &size))) + return retval; + } + else if (size <= 0) + return NC_EINVAL; + + /* Check that this name is not in use as a var, grp, or type. */ + if ((retval = nc4_check_dup_name(grp, norm_name))) + return retval; + + /* Add to our list of types. */ + if ((retval = nc4_type_list_add(&(grp->type), &type))) + return retval; + + /* Remember info about this type. */ + type->nc_typeid = grp->file->nc4_info->next_typeid++; + type->size = size; + if (!(type->name = malloc((strlen(norm_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(type->name, norm_name); + type->class = type_class; + type->base_nc_type = base_typeid; + + /* Return the typeid to the user. */ + if (typeidp) + *typeidp = type->nc_typeid; + + return NC_NOERR; +} + + +/* The sizes of types may vary from platform to platform, but within + * netCDF files, type sizes are fixed. */ +#define NC_CHAR_LEN sizeof(char) +#define NC_STRING_LEN sizeof(char *) +#define NC_BYTE_LEN 1 +#define NC_SHORT_LEN 2 +#define NC_INT_LEN 4 +#define NC_FLOAT_LEN 4 +#define NC_DOUBLE_LEN 8 +#define NC_INT64_LEN 8 + +/* Get the name and size of a type. For strings, 1 is returned. For + * VLEN the base type len is returned. */ +int +NC4_inq_type(int ncid, nc_type typeid, char *name, size_t *size) +{ + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type; + int atomic_size[NUM_ATOMIC_TYPES] = {0, NC_BYTE_LEN, NC_CHAR_LEN, NC_SHORT_LEN, + NC_INT_LEN, NC_FLOAT_LEN, NC_DOUBLE_LEN, + NC_BYTE_LEN, NC_SHORT_LEN, NC_INT_LEN, NC_INT64_LEN, + NC_INT64_LEN, NC_STRING_LEN}; + + int retval; + + LOG((2, "nc_inq_type: ncid 0x%x typeid %d", ncid, typeid)); + + /* If this is an atomic type, the answer is easy. */ + if (typeid <= NUM_ATOMIC_TYPES) + { + if (name) + strcpy(name, atomic_name[typeid]); + if (size) + *size = atomic_size[typeid]; + return NC_NOERR; + } + + /* Not an atomic type - so find group. */ + if ((retval = nc4_find_nc4_grp(ncid, &grp))) + return retval; + + /* Find this type. */ + if (!(type = nc4_rec_find_nc_type(grp->file->nc4_info->root_grp, typeid))) + return NC_EBADTYPE; + + if (name) + strcpy(name, type->name); + + if (size) + { + if (type->class != NC_VLEN) + *size = type->size; + else + *size = sizeof(nc_vlen_t); + } + + return NC_NOERR; +} + +/* Create a compound type. */ +int +NC4_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp) +{ + return add_user_type(ncid, size, name, 0, NC_COMPOUND, typeidp); +} + +/* Insert a named field into a compound type. */ +int +NC4_insert_compound(int ncid, nc_type typeid, const char *name, size_t offset, + nc_type field_typeid) +{ + return nc_insert_array_compound(ncid, typeid, name, offset, + field_typeid, 0, NULL); +} + +/* Insert a named array into a compound type. */ +EXTERNL int +NC4_insert_array_compound(int ncid, int typeid, const char *name, + size_t offset, nc_type field_typeid, + int ndims, const int *dim_sizesp) +{ + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type; + char norm_name[NC_MAX_NAME + 1]; + int retval; + + LOG((2, "nc_insert_array_compound: ncid 0x%x, typeid %d name %s " + "offset %d field_typeid %d ndims %d", ncid, typeid, + name, offset, field_typeid, ndims)); + + /* Check and normalize the name. */ + if ((retval = nc4_check_name(name, norm_name))) + return retval; + + /* Find file metadata. */ + if ((retval = nc4_find_nc4_grp(ncid, &grp))) + return retval; + + /* Find type metadata. */ + if ((retval = nc4_find_type(grp->file->nc4_info, typeid, &type))) + return retval; + + /* Did the user give us a good compound type typeid? */ + if (!type || type->class != NC_COMPOUND) + return NC_EBADTYPE; + + /* If this type has already been written to the file, you can't + * change it. */ + if (type->committed) + return NC_ETYPDEFINED; + + /* Insert new field into this type's list of fields. */ + if ((retval = nc4_field_list_add(&type->field, type->num_fields, + norm_name, offset, 0, 0, field_typeid, + ndims, dim_sizesp))) + return retval; + + type->num_fields++; + + return NC_NOERR; +} + +/* Find info about any user defined type. */ +int +NC4_inq_user_type(int ncid, nc_type typeid, char *name, size_t *size, + nc_type *base_nc_typep, size_t *nfieldsp, int *classp) +{ + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type; + NC_FIELD_INFO_T *field; + int retval; + + LOG((2, "nc_inq_user_type: ncid 0x%x typeid %d", ncid, typeid)); + + /* Find group metadata. */ + if ((retval = nc4_find_nc4_grp(ncid, &grp))) + return retval; + + /* Find this type. */ + if (!(type = nc4_rec_find_nc_type(grp->file->nc4_info->root_grp, typeid))) + return NC_EBADTYPE; + + /* Count the number of fields. */ + if (nfieldsp) + { + *nfieldsp = 0; + if (type->class == NC_COMPOUND) + for (field = type->field; field; field = field->next) + (*nfieldsp)++; + else if (type->class == NC_ENUM) + *nfieldsp = type->num_enum_members; + } + + /* Fill in size and name info, if desired. */ + if (size) + { + if (type->class != NC_VLEN) + *size = type->size; + else + *size = sizeof(nc_vlen_t); + } + if (name) + strcpy(name, type->name); + + /* VLENS and ENUMs have a base type - that is, they type they are + * arrays of or enums of. */ + if (base_nc_typep) + *base_nc_typep = type->base_nc_type; + + /* If the user wants it, tell whether this is a compound, opaque, + * vlen, enum, or string class of type. */ + if (classp) + *classp = type->class; + + return NC_NOERR; +} + +/* Given the ncid, typeid and fieldid, get info about the field. */ +int +NC4_inq_compound_field(int ncid, nc_type typeid, int fieldid, char *name, + size_t *offsetp, nc_type *field_typeidp, int *ndimsp, + int *dim_sizesp) +{ + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type; + NC_FIELD_INFO_T *field; + int d, retval; + + /* Find file metadata. */ + if ((retval = nc4_find_nc4_grp(ncid, &grp))) + return retval; + + /* Find this type. */ + if (!(type = nc4_rec_find_nc_type(grp->file->nc4_info->root_grp, typeid))) + return NC_EBADTYPE; + + /* Find the field. */ + for (field = type->field; field; field = field->next) + if (field->fieldid == fieldid) + { + if (name) + strcpy(name, field->name); + if (offsetp) + *offsetp = field->offset; + if (field_typeidp) + *field_typeidp = field->nctype; + if (ndimsp) + *ndimsp = field->ndims; + if (dim_sizesp) + for (d = 0; d < field->ndims; d++) + dim_sizesp[d] = field->dim_size[d]; + return NC_NOERR; + } + + return NC_EBADFIELD; +} + +/* Find a netcdf-4 file. THis will return an error if it finds a + * netcdf-3 file, or a netcdf-4 file with strict nc3 rules. */ +static int +find_nc4_file(int ncid, NC_FILE_INFO_T **nc) +{ + + /* Find file metadata. */ + if (!((*nc) = nc4_find_nc_file(ncid))) + return NC_EBADID; + + /* Check for netcdf-3 files or netcdf-3 rules. */ + if (!(*nc)->nc4_info) + return NC_ENOTNC4; + if ((*nc)->nc4_info->cmode & NC_CLASSIC_MODEL) + return NC_ESTRICTNC3; + + return NC_NOERR; +} + +/* Given the typeid and the name, get the fieldid. */ +int +NC4_inq_compound_fieldindex(int ncid, nc_type typeid, const char *name, int *fieldidp) +{ + NC_FILE_INFO_T *nc; + NC_TYPE_INFO_T *type; + NC_FIELD_INFO_T *field; + char norm_name[NC_MAX_NAME + 1]; + int retval; + + LOG((2, "nc_inq_compound_fieldindex: ncid 0x%x typeid %d name %s", + ncid, typeid, name)); + + /* Find file metadata. */ + if ((retval = find_nc4_file(ncid, &nc))) + return retval; + + /* Find the type. */ + if ((retval = nc4_find_type(nc->nc4_info, typeid, &type))) + return retval; + + /* Did the user give us a good compound type typeid? */ + if (!type || type->class != NC_COMPOUND) + return NC_EBADTYPE; + + /* Normalize name. */ + if ((retval = nc4_normalize_name(name, norm_name))) + return retval; + + /* Find the field with this name. */ + for (field = type->field; field; field = field->next) + if (!strcmp(field->name, norm_name)) + break; + + if (!field) + return NC_EBADFIELD; + + if (fieldidp) + *fieldidp = field->fieldid; + return NC_NOERR; +} + + +/* Opaque type. */ + +/* Create an opaque type. Provide a size and a name. */ +int +NC4_def_opaque(int ncid, size_t datum_size, const char *name, + nc_type *typeidp) +{ + return add_user_type(ncid, datum_size, name, 0, NC_OPAQUE, typeidp); +} + + +/* Define a variable length type. */ +int +NC4_def_vlen(int ncid, const char *name, nc_type base_typeid, + nc_type *typeidp) +{ + return add_user_type(ncid, 0, name, base_typeid, NC_VLEN, typeidp); +} + +/* Create an enum type. Provide a base type and a name. At the moment + * only ints are accepted as base types. */ +int +NC4_def_enum(int ncid, nc_type base_typeid, const char *name, + nc_type *typeidp) +{ + return add_user_type(ncid, 0, name, base_typeid, NC_ENUM, typeidp); +} + + +/* Get enum name from enum value. Name size will be <= NC_MAX_NAME. */ +int +NC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier) +{ + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type; + NC_ENUM_MEMBER_INFO_T *enum_member; + long long ll_val; + int i; + int retval; + + LOG((3, "nc_inq_enum_ident: xtype %d value %d\n", xtype, value)); + + /* Find group metadata. */ + if ((retval = nc4_find_nc4_grp(ncid, &grp))) + return retval; + + /* Find this type. */ + if (!(type = nc4_rec_find_nc_type(grp->file->nc4_info->root_grp, xtype))) + return NC_EBADTYPE; + + /* Complain if they are confused about the type. */ + if (type->class != NC_ENUM) + return NC_EBADTYPE; + + /* Move to the desired enum member in the list. */ + enum_member = type->enum_member; + for (i = 0; i < type->num_enum_members; i++) + { + switch (type->base_nc_type) + { + case NC_BYTE: + ll_val = *(char *)enum_member->value; + break; + case NC_UBYTE: + ll_val = *(unsigned char *)enum_member->value; + break; + case NC_SHORT: + ll_val = *(short *)enum_member->value; + break; + case NC_USHORT: + ll_val = *(unsigned short *)enum_member->value; + break; + case NC_INT: + ll_val = *(int *)enum_member->value; + break; + case NC_UINT: + ll_val = *(unsigned int *)enum_member->value; + break; + case NC_INT64: + case NC_UINT64: + ll_val = *(long long *)enum_member->value; + break; + default: + return NC_EINVAL; + } + LOG((4, "ll_val=%d", ll_val)); + if (ll_val == value) + { + if (identifier) + strcpy(identifier, enum_member->name); + break; + } + else + enum_member = enum_member->next; + } + + /* If we didn't find it, life sucks for us. :-( */ + if (i == type->num_enum_members) + return NC_EINVAL; + + return NC_NOERR; +} + +/* Get information about an enum member: an identifier and + * value. Identifier size will be <= NC_MAX_NAME. */ +int +NC4_inq_enum_member(int ncid, nc_type typeid, int idx, char *identifier, + void *value) +{ + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type; + NC_ENUM_MEMBER_INFO_T *enum_member; + int i; + int retval; + + LOG((2, "nc_inq_enum_member: ncid 0x%x typeid %d", ncid, typeid)); + + /* Find group metadata. */ + if ((retval = nc4_find_nc4_grp(ncid, &grp))) + return retval; + + /* Find this type. */ + if (!(type = nc4_rec_find_nc_type(grp->file->nc4_info->root_grp, typeid))) + return NC_EBADTYPE; + + /* Complain if they are confused about the type. */ + if (type->class != NC_ENUM) + return NC_EBADTYPE; + + /* Check index. */ + if (idx >= type->num_enum_members) + return NC_EINVAL; + + /* Move to the desired enum member in the list. */ + enum_member = type->enum_member; + for (i = 0; i < idx; i++) + enum_member = enum_member->next; + + /* Give the people what they want. */ + if (identifier) + strcpy(identifier, enum_member->name); + if (value) + memcpy(value, enum_member->value, type->size); + + return NC_NOERR; +} + +/* Insert a identifierd value into an enum type. The value must fit within + * the size of the enum type, the identifier size must be <= NC_MAX_NAME. */ +int +NC4_insert_enum(int ncid, nc_type typeid, const char *identifier, + const void *value) +{ + NC_GRP_INFO_T *grp; + NC_TYPE_INFO_T *type; + char norm_name[NC_MAX_NAME + 1]; + int retval; + + LOG((2, "nc_insert_enum: ncid 0x%x, typeid %d identifier %s value %d", ncid, + typeid, identifier, value)); + + /* Check and normalize the name. */ + if ((retval = nc4_check_name(identifier, norm_name))) + return retval; + + /* Find file metadata. */ + if ((retval = nc4_find_nc4_grp(ncid, &grp))) + return retval; + + /* Find type metadata. */ + if ((retval = nc4_find_type(grp->file->nc4_info, typeid, &type))) + return retval; + + /* Did the user give us a good enum typeid? */ + if (!type || type->class != NC_ENUM) + return NC_EBADTYPE; + + /* If this type has already been written to the file, you can't + * change it. */ + if (type->committed) + return NC_ETYPDEFINED; + + /* Insert new field into this type's list of fields. */ + if ((retval = nc4_enum_member_add(&type->enum_member, type->size, + norm_name, value))) + return retval; + + type->num_enum_members++; + + return NC_NOERR; +} + +/* Insert one element into an already allocated vlen array element. */ +int +NC4_put_vlen_element(int ncid, int typeid, void *vlen_element, + size_t len, const void *data) +{ + nc_vlen_t *tmp = vlen_element; + tmp->len = len; + tmp->p = (void *)data; + return NC_NOERR; +} + +/* Insert one element into an already allocated vlen array element. */ +int +NC4_get_vlen_element(int ncid, int typeid, const void *vlen_element, + size_t *len, void *data) +{ + const nc_vlen_t *tmp = vlen_element; + int type_size = 4; + + *len = tmp->len; + memcpy(data, tmp->p, tmp->len * type_size); + return NC_NOERR; +} + diff --git a/extern/src_netcdf4/nc4var.c b/extern/src_netcdf4/nc4var.c new file mode 100644 index 0000000000000000000000000000000000000000..443e96b2dfb9e366fa4f6feedc7ba71f93d37f03 --- /dev/null +++ b/extern/src_netcdf4/nc4var.c @@ -0,0 +1,1485 @@ +/* +This file is part of netcdf-4, a netCDF-like interface for HDF5, or a +HDF5 backend for netCDF, depending on your point of view. + +This file handles the nc4 variable functions. + +Copyright 2003-2006, University Corporation for Atmospheric +Research. See COPYRIGHT file for copying and redistribution +conditions. +*/ + +#include +#include "nc4dispatch.h" +#include + +#ifdef USE_PNETCDF +#include +#endif + +/* Min and max deflate levels tolerated by HDF5. */ +#define MIN_DEFLATE_LEVEL 0 +#define MAX_DEFLATE_LEVEL 9 + +/* This is to track opened HDF5 objects to make sure they are + * closed. */ +#ifdef EXTRA_TESTS +extern int num_plists; +#endif /* EXTRA_TESTS */ + +/* One meg is the minimum buffer size. */ +#define ONE_MEG 1048576 + +/* Szip options. */ +#define NC_SZIP_EC_OPTION_MASK 4 +#define NC_SZIP_NN_OPTION_MASK 32 +#define NC_SZIP_MAX_PIXELS_PER_BLOCK 32 + +int nc4_get_default_fill_value(NC_TYPE_INFO_T *type_info, void *fill_value); + + +/* If the HDF5 dataset for this variable is open, then close it and + * reopen it, with the perhaps new settings for chunk caching. */ +int +nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var) +{ + hid_t access_pid; + + if (var->hdf_datasetid) + { + if ((access_pid = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + return NC_EHDFERR; +#ifdef EXTRA_TESTS + num_plists++; +#endif + if (H5Pset_chunk_cache(access_pid, var->chunk_cache_nelems, + var->chunk_cache_size, + var->chunk_cache_preemption) < 0) + return NC_EHDFERR; + if (H5Dclose(var->hdf_datasetid) < 0) + return NC_EHDFERR; + if ((var->hdf_datasetid = H5Dopen2(grp->hdf_grpid, var->name, + access_pid)) < 0) + return NC_EHDFERR; + if (H5Pclose(access_pid) < 0) + return NC_EHDFERR; +#ifdef EXTRA_TESTS + num_plists--; +#endif + + if (var->dimscale) + var->dim[0]->hdf_dimscaleid = var->hdf_datasetid; + } + + return NC_NOERR; +} + +/* Set chunk cache size for a variable. */ +int +NC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, + float preemption) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + int retval; + + /* Check input for validity. */ + if (preemption < 0 || preemption > 1) + return NC_EINVAL; + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + + /* An attempt to do any of these things on a netCDF-3 file is + * ignored with no error. */ + if (!h5) + return NC_NOERR; + + assert(nc && grp && h5); + + /* Find the var. */ + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + break; + if (!var) + return NC_ENOTVAR; + + /* Set the values. */ + var->chunk_cache_size = size; + var->chunk_cache_nelems = nelems; + var->chunk_cache_preemption = preemption; + + if ((retval = nc4_reopen_dataset(grp, var))) + return retval; + + return NC_NOERR; +} + +/* Need this version for fortran. Accept negative numbers to leave + * settings as they are. */ +int +nc_set_var_chunk_cache_ints(int ncid, int varid, int size, int nelems, + int preemption) +{ + size_t real_size = H5D_CHUNK_CACHE_NBYTES_DEFAULT; + size_t real_nelems = H5D_CHUNK_CACHE_NSLOTS_DEFAULT; + float real_preemption = H5D_CHUNK_CACHE_W0_DEFAULT; + + if (size >= 0) + real_size = size * MEGABYTE; + + if (nelems >= 0) + real_nelems = nelems; + + if (preemption >= 0) + real_preemption = preemption / 100.; + + return nc_set_var_chunk_cache(ncid, varid, real_size, real_nelems, + real_preemption); +} + +/* Get chunk cache size for a variable. */ +int +NC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep, + size_t *nelemsp, float *preemptionp) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + int retval; + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + + /* Attempting to do any of these things on a netCDF-3 file produces + * an error. */ + if (!h5) + return NC_ENOTNC4; + + assert(nc && grp && h5); + + /* Find the var. */ + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + break; + if (!var) + return NC_ENOTVAR; + + /* Give the user what they want. */ + if (sizep) + *sizep = var->chunk_cache_size; + if (nelemsp) + *nelemsp = var->chunk_cache_nelems; + if (preemptionp) + *preemptionp = var->chunk_cache_preemption; + + return NC_NOERR; +} + +/* Get chunk cache size for a variable. */ +int +nc_get_var_chunk_cache_ints(int ncid, int varid, int *sizep, + int *nelemsp, int *preemptionp) +{ + size_t real_size, real_nelems; + float real_preemption; + int ret; + + if ((ret = nc_get_var_chunk_cache(ncid, varid, &real_size, + &real_nelems, &real_preemption))) + return ret; + + if (sizep) + *sizep = real_size / MEGABYTE; + if (nelemsp) + *nelemsp = (int)real_nelems; + if(preemptionp) + *preemptionp = (int)(real_preemption * 100); + + return NC_NOERR; +} + +/* Check a set of chunksizes to see if they add up to a chunk that is too big. */ +static int +check_chunksizes(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, const size_t *chunksizes) +{ + NC_TYPE_INFO_T *type_info; + float total; + size_t type_len; + int d; + int retval; + + if ((retval = nc4_get_typelen_mem(grp->file->nc4_info, var->xtype, 0, &type_len))) + return retval; + if ((retval = nc4_find_type(grp->file->nc4_info, var->xtype, &type_info))) + return retval; + if (type_info && type_info->class == NC_VLEN) + total = sizeof(hvl_t); + else + total = type_len; + for (d = 0; d < var->ndims; d++) + { + if (chunksizes[d] < 1) + return NC_EINVAL; + total *= chunksizes[d]; + } + + if (total > NC_MAX_UINT) + return NC_EBADCHUNK; + + return NC_NOERR; +} + +/* Find the default chunk nelems (i.e. length of chunk along each + * dimension). */ +static int +nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var) +{ + int d; + size_t type_size, max_len = 0; + float num_values = 1, num_set = 0; + int retval; +#ifdef LOGGING + int max_dim; + float total_chunk_size; +#endif + + if (var->type_info->nc_typeid == NC_STRING) + type_size = sizeof(char *); + else + type_size = var->type_info->size; + + /* Later this will become the total number of bytes in the default + * chunk. */ +#ifdef LOGGING + total_chunk_size = type_size; +#endif + + /* How many values in the variable (or one record, if there are + * unlimited dimensions); which is the largest dimension, and how + * long is it? */ + for (d = 0; d < var->ndims; d++) + { + assert(var->dim[d]); + if (var->dim[d]->len) + num_values *= (float)var->dim[d]->len; + else + num_set++; + + if (var->dim[d]->len > max_len) + { + max_len = var->dim[d]->len; +#ifdef LOGGING + max_dim = d; +#endif + } + LOG((4, "d = %d max_dim %d max_len %ld num_values %f", d, max_dim, max_len, + num_values)); + } + + /* If a dim is several orders of magnitude smaller than the max + * dimension, set it's chunk size to the full extent of the smaller + * dimension. */ +#define NC_DIM_MULTIPLIER 10000 + for (d = 0; d < var->ndims; d++) + if (var->dim[d]->unlimited) + var->chunksizes[d] = 1; + else if (!var->dim[d]->unlimited && var->dim[d]->len * NC_DIM_MULTIPLIER < max_len) + { + var->chunksizes[d] = var->dim[d]->len; + num_set++; + } + + /* Pick a chunk length for each dimension, if one has not already + * been picked above. */ + for (d = 0; d < var->ndims; d++) + if (!var->chunksizes[d]) + { + size_t suggested_size; + suggested_size = (pow((double)DEFAULT_CHUNK_SIZE/(num_values * type_size), + 1/(double)(var->ndims - num_set)) * var->dim[d]->len - .5); + if (suggested_size > var->dim[d]->len) + suggested_size = var->dim[d]->len; + var->chunksizes[d] = suggested_size ? suggested_size : 1; + LOG((4, "nc_def_var_nc4: name %s dim %d DEFAULT_CHUNK_SIZE %d num_values %f type_size %d " + "chunksize %ld", var->name, d, DEFAULT_CHUNK_SIZE, num_values, type_size, var->chunksizes[d])); + } + + /* Find total chunk size. */ +#ifdef LOGGING + for (d = 0; d < var->ndims; d++) + total_chunk_size *= var->chunksizes[d]; + LOG((4, "total_chunk_size %f", total_chunk_size)); +#endif + + /* But did this add up to a chunk that is too big? */ + retval = check_chunksizes(grp, var, var->chunksizes); + if (retval) + { + /* Other error? */ + if (retval != NC_EBADCHUNK) + return retval; + + /* Chunk is too big! Reduce each dimension by half and try again. */ + for ( ; retval == NC_EBADCHUNK; retval = check_chunksizes(grp, var, var->chunksizes)) + for (d = 0; d < var->ndims; d++) + var->chunksizes[d] = var->chunksizes[d]/2 ? var->chunksizes[d]/2 : 1; + } + + /* Do we have any big data overhangs? They can be dangerous to + * babies, the elderly, or confused campers who have had too much + * beer. */ + for (d = 0; d < var->ndims; d++) + { + int num_chunks; + size_t overhang; + assert(var->chunksizes[d] > 0); + num_chunks = (var->dim[d]->len + var->chunksizes[d] - 1) / var->chunksizes[d]; + if(num_chunks > 0) { + overhang = (num_chunks * var->chunksizes[d]) - var->dim[d]->len; + var->chunksizes[d] -= overhang / num_chunks; + } + } + + return NC_NOERR; +} + +/* This is called when a new netCDF-4 variable is defined. Break it + * down! */ +static int +nc_def_var_nc4(int ncid, const char *name, nc_type xtype, + int ndims, const int *dimidsp, int *varidp) +{ + NC_GRP_INFO_T *grp; + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim; + NC_HDF5_FILE_INFO_T *h5; + NC_TYPE_INFO_T *type_info; + char norm_name[NC_MAX_NAME + 1]; + int new_varid = 0; + int num_unlim = 0; + int d; + size_t num_values = 1; + int retval; + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) + return retval; + assert(grp && h5); + + /* If it's not in define mode, strict nc3 files error out, + * otherwise switch to define mode. */ + if (!(h5->flags & NC_INDEF)) + { + if (h5->cmode & NC_CLASSIC_MODEL) + return NC_ENOTINDEFINE; + if ((retval = NC4_redef(ncid))) + return retval; + } + + /* Check and normalize the name. */ + if ((retval = nc4_check_name(name, norm_name))) + return retval; + + /* Not a Type is, well, not a type.*/ + if (xtype == NC_NAT) + return NC_EBADTYPE; + + /* For classic files, only classic types are allowed. */ + if (h5->cmode & NC_CLASSIC_MODEL && xtype > NC_DOUBLE) + return NC_ESTRICTNC3; + + /* If this is a user defined type, find it. */ + if (xtype > NC_STRING) + if (nc4_find_type(grp->file->nc4_info, xtype, &type_info)) + return NC_EBADTYPE; + + /* cast needed for braindead systems with signed size_t */ + if((unsigned long) ndims > X_INT_MAX) /* Backward compat */ + return NC_EINVAL; + + /* Classic model files have a limit on number of vars. */ + if(h5->cmode & NC_CLASSIC_MODEL && h5->nvars >= NC_MAX_VARS) + return NC_EMAXVARS; + + /* Check that this name is not in use as a var, grp, or type. */ + if ((retval = nc4_check_dup_name(grp, norm_name))) + return retval; + + /* If the file is read-only, return an error. */ + if (h5->no_write) + return NC_EPERM; + + /* Get the new varid. */ + for (var = grp->var; var; var = var->next) + new_varid++; + + /* Check all the dimids to make sure they exist. */ + for (d = 0; d < ndims; d++) + { + if ((retval = nc4_find_dim(grp, dimidsp[d], &dim, NULL))) + return retval; + if (dim->unlimited) + num_unlim++; + else + num_values *= dim->len; + } + + /* These degrubbing messages sure are handy! */ + LOG((3, "nc_def_var_nc4: name %s type %d ndims %d", norm_name, xtype, ndims)); +#ifdef LOGGING + { + int dd; + for (dd = 0; dd < ndims; dd++) + LOG((4, "dimid[%d] %d", dd, dimidsp[dd])); + } +#endif + + /* Add the var to the end of the list. */ + if ((retval = nc4_var_list_add(&grp->var, &var))) + return retval; + + /* Now fill in the values in the var info structure. */ + if (!(var->name = malloc((strlen(norm_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(var->name, norm_name); + var->varid = grp->nvars++; + var->xtype = xtype; + var->ndims = ndims; + var->dirty++; + + /* If this is a user-defined type, there is a type_info stuct with + * all the type information. For atomic types, fake up a type_info + * struct. */ + if (xtype > NC_STRING) + var->type_info = type_info; + else + { + if (!(var->type_info = calloc(1, sizeof(NC_TYPE_INFO_T)))) + return NC_ENOMEM; + var->type_info->nc_typeid = xtype; + if ((retval = nc4_get_hdf_typeid(h5, var->xtype, &var->type_info->hdf_typeid, + var->type_info->endianness))) + return retval; + if ((var->type_info->native_typeid = H5Tget_native_type(var->type_info->hdf_typeid, + H5T_DIR_DEFAULT)) < 0) + return NC_EHDFERR; + if ((retval = nc4_get_typelen_mem(h5, var->type_info->nc_typeid, 0, + &var->type_info->size))) + return retval; + } + if (!num_unlim) + var->contiguous = 1; + + /* Allocate space for dimension information. */ + if (ndims) + { + if (!(var->dim = calloc(ndims, sizeof(NC_DIM_INFO_T *)))) + return NC_ENOMEM; + if (!(var->dimids = calloc(ndims, sizeof(int)))) + return NC_ENOMEM; + } + + /* At the same time, check to see if this is a coordinate + * variable. If so, it will have the same name as one of its + * dimensions. If it is a coordinate var, is it a coordinate var in + * the same group as the dim? */ + for (d = 0; d < ndims; d++) + { + NC_GRP_INFO_T *dim_grp; + if ((retval = nc4_find_dim(grp, dimidsp[d], &dim, &dim_grp))) + return retval; + if (strcmp(dim->name, norm_name) == 0 && dim_grp == grp && d == 0) + { + var->dimscale++; + dim->coord_var = var; + dim->coord_var_in_grp++; + } + var->dimids[d] = dimidsp[d]; + var->dim[d] = dim; + } + + /* Determine default chunksizes for this variable. (Even for + * variables which may be contiguous. */ + LOG((4, "allocating array of %d size_t to hold chunksizes for var %s", + var->ndims, var->name)); + if (var->ndims) + if (!(var->chunksizes = calloc(var->ndims, sizeof(size_t)))) + return NC_ENOMEM; + + if ((retval = nc4_find_default_chunksizes2(grp, var))) + return retval; + + /* Is this a variable with a chunksize greater than the current + * cache size? */ + if ((retval = nc4_adjust_var_cache(grp, var))) + return retval; + + /* If the user names this variable the same as a dimension, but + * doesn't use that dimension first in its list of dimension ids, + * is not a coordinate variable. I need to change its HDF5 name, + * because the dimension will cause a HDF5 dataset to be created, + * and this var has the same name. */ + for (dim = grp->dim; dim; dim = dim->next) + if (!strcmp(dim->name, norm_name) && + (!var->ndims || dimidsp[0] != dim->dimid)) + { + /* Set a different hdf5 name for this variable to avoid name + * clash. */ + if (strlen(norm_name) + strlen(NON_COORD_PREPEND) > NC_MAX_NAME) + return NC_EMAXNAME; + if (!(var->hdf5_name = malloc((strlen(NON_COORD_PREPEND) + + strlen(norm_name) + 1) * sizeof(char)))) + return NC_ENOMEM; + + sprintf(var->hdf5_name, "%s%s", NON_COORD_PREPEND, norm_name); + } + + /* If this is a coordinate var, it is marked as a HDF5 dimension + * scale. (We found dim above.) Otherwise, allocate space to + * remember whether dimension scales have been attached to each + * dimension. */ + if (!var->dimscale && ndims) + if (ndims && !(var->dimscale_attached = calloc(ndims, sizeof(int)))) + return NC_ENOMEM; + + /* Return the varid. */ + if (varidp) + *varidp = var->varid; + LOG((4, "new varid %d", var->varid)); + + return retval; +} + +/* Create a new variable to hold user data. This is what it's all + * about baby! */ +int +NC4_def_var(int ncid, const char *name, nc_type xtype, int ndims, + const int *dimidsp, int *varidp) +{ + NC_FILE_INFO_T *nc; + + LOG((2, "nc_def_var: ncid 0x%x name %s xtype %d ndims %d", + ncid, name, xtype, ndims)); + + /* If there are dimensions, I need their ids. */ + if (ndims && !dimidsp) + return NC_EINVAL; + + /* Find metadata for this file. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + { + int ret; + + ret = ncmpi_def_var(nc->int_ncid, name, xtype, ndims, + dimidsp, varidp); + nc->pnetcdf_ndims[*varidp] = ndims; + return ret; + } +#endif /* USE_PNETCDF */ + + /* Netcdf-3 cases handled by dispatch layer. */ + assert(nc->nc4_info); + + /* Handle netcdf-4 cases. */ + return nc_def_var_nc4(ncid, name, xtype, ndims, dimidsp, varidp); +} + +/* Get all the information about a variable. Pass NULL for whatever + * you don't care about. This is an internal function, not exposed to + * the user. */ +int +NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp, + int *shufflep, int *deflatep, int *deflate_levelp, + int *fletcher32p, int *contiguousp, size_t *chunksizesp, + int *no_fill, void *fill_valuep, int *endiannessp, + int *options_maskp, int *pixels_per_blockp) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + NC_ATT_INFO_T *att; + int natts=0; + size_t type_size; + int d; + int retval; + + LOG((2, "nc_inq_var_all: ncid 0x%x varid %d", ncid, varid)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + assert(nc && grp && h5); + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_inq_var(nc->int_ncid, varid, name, xtypep, ndimsp, + dimidsp, nattsp); +#endif /* USE_PNETCDF */ + + /* Walk through the list of vars, and return the info about the one + with a matching varid. If the varid is -1, find the global + atts and call it a day. */ + if (varid == NC_GLOBAL) + { + if (nattsp) + { + for (att = grp->att; att; att = att->next) + natts++; + *nattsp = natts; + } + return NC_NOERR; + } + + /* Find the var. */ + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + break; + + /* Oh no! Maybe we couldn't find it (*sob*)! */ + if (!var) + return NC_ENOTVAR; + + /* Copy the data to the user's data buffers. */ + if (name) + strcpy(name, var->name); + if (xtypep) + *xtypep = var->xtype; + if (ndimsp) + *ndimsp = var->ndims; + if (dimidsp) + for (d = 0; d < var->ndims; d++) + dimidsp[d] = var->dimids[d]; + if (nattsp) + { + for (att = var->att; att; att = att->next) + natts++; + *nattsp = natts; + } + + /* Chunking stuff. */ + if (!var->contiguous && chunksizesp) + for (d = 0; d < var->ndims; d++) + { + chunksizesp[d] = var->chunksizes[d]; + LOG((4, "chunksizesp[%d]=%d", d, chunksizesp[d])); + } + + if (contiguousp) + *contiguousp = var->contiguous ? NC_CONTIGUOUS : NC_CHUNKED; + + /* Filter stuff. */ + if (deflatep) + *deflatep = var->deflate; + if (deflate_levelp) + *deflate_levelp = var->deflate_level; + if (shufflep) + *shufflep = var->shuffle; + if (fletcher32p) + *fletcher32p = var->fletcher32; + if (options_maskp) + *options_maskp = var->options_mask; + if (pixels_per_blockp) + *pixels_per_blockp = var->pixels_per_block; + + /* Fill value stuff. */ + if (no_fill) + *no_fill = var->no_fill; + + /* Don't do a thing with fill_valuep if no_fill mode is set for + * this var, or if fill_valuep is NULL. */ + if (!var->no_fill && fill_valuep) + { + /* Do we have a fill value for this var? */ + if (var->fill_value) + { + if ((retval = nc4_get_typelen_mem(grp->file->nc4_info, var->xtype, 0, &type_size))) + return retval; + memcpy(fill_valuep, var->fill_value, type_size); + } + else + { + if ((retval = nc4_get_default_fill_value(var->type_info, fill_valuep))) + return retval; + } + } + + /* Does the user want the endianness of this variable? */ + if (endiannessp) + *endiannessp = var->type_info->endianness; + + return NC_NOERR; +} + +/* This functions sets extra stuff about a netCDF-4 variable which + must be set before the enddef but after the def_var. This is an + internal function, deliberately hidden from the user so that we can + change the prototype of this functions without changing the API. */ +static int +nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate, + int *deflate_level, int *fletcher32, int *contiguous, + const size_t *chunksizes, int *no_fill, + const void *fill_value, int *endianness, + int *options_mask, int *pixels_per_block) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim; + size_t type_size; + int d; + int retval; + + LOG((2, "nc_def_var_extra: ncid 0x%x varid %d", ncid, varid)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + + /* Attempting to do any of these things on a netCDF-3 file produces + * an error. */ + if (!h5) + return NC_ENOTNC4; + + assert(nc && grp && h5); + + /* Find the var. */ + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + break; + + /* Oh no! Maybe we couldn't find it (*sob*)! */ + if (!var) + return NC_ENOTVAR; + + /* Can't turn on contiguous and deflate/fletcher32/szip. */ + if (contiguous) + if ((*contiguous != NC_CHUNKED && deflate) || + (*contiguous != NC_CHUNKED && fletcher32) || + (*contiguous != NC_CHUNKED && options_mask)) + return NC_EINVAL; + + /* If the HDF5 dataset has already been created, then it is too + * late to set all the extra stuff. */ + if (var->created) + return NC_ELATEDEF; + + /* Check compression options. */ + if ((deflate && options_mask) || + (deflate && !deflate_level) || + (options_mask && !pixels_per_block)) + return NC_EINVAL; + + /* Valid deflate level? */ + if (deflate && deflate_level) + { + if (*deflate) + if (*deflate_level < MIN_DEFLATE_LEVEL || + *deflate_level > MAX_DEFLATE_LEVEL) + return NC_EINVAL; + if (var->options_mask) + return NC_EINVAL; + + /* For scalars, just ignore attempt to deflate. */ + if (!var->ndims) + return NC_NOERR; + + /* Well, if we couldn't find any errors, I guess we have to take + * the users settings. Darn! */ + var->contiguous = 0; + var->deflate = *deflate; + if (*deflate) + var->deflate_level = *deflate_level; + LOG((3, "nc_def_var_extra: *deflate_level %d", *deflate_level)); + } + + /* Szip in use? */ + if (options_mask) + { +#ifndef USE_SZIP + return NC_EINVAL; +#endif + if (var->deflate) + return NC_EINVAL; + if ((*options_mask != NC_SZIP_EC_OPTION_MASK) && + (*options_mask != NC_SZIP_NN_OPTION_MASK)) + return NC_EINVAL; + if ((*pixels_per_block > NC_SZIP_MAX_PIXELS_PER_BLOCK) || + (var->type_info->nc_typeid >= NC_STRING)) + return NC_EINVAL; + var->options_mask = *options_mask; + var->pixels_per_block = *pixels_per_block; + var->contiguous = 0; + } + + /* Shuffle filter? */ + if (shuffle) + { + var->shuffle = *shuffle; + var->contiguous = 0; + } + + /* Fltcher32 checksum error protection? */ + if (fletcher32) + { + var->fletcher32 = *fletcher32; + var->contiguous = 0; + } + + /* Does the user want a contiguous dataset? Not so fast! Make sure + * that there are no unlimited dimensions, and no filters in use + * for this data. */ + if (contiguous && *contiguous) + { + if (var->deflate || var->fletcher32 || var->shuffle || var->options_mask) + return NC_EINVAL; + + for (d = 0; d < var->ndims; d++) + { + if ((retval = nc4_find_dim(grp, var->dimids[d], &dim, NULL))) + return retval; + if (dim->unlimited) + return NC_EINVAL; + } + + var->contiguous = NC_CONTIGUOUS; + } + + /* Chunksizes anyone? */ + if (contiguous && *contiguous == NC_CHUNKED) + { + var->contiguous = 0; + + /* If the user provided chunksizes, check that they are not too + * big, and that their total size of chunk is less than 4 GB. */ + if (chunksizes) + { + + if ((retval = check_chunksizes(grp, var, chunksizes))) + return retval; + + /* Set the chunksizes for this variable. */ + for (d = 0; d < var->ndims; d++) + var->chunksizes[d] = chunksizes[d]; + } + } + + /* Is this a variable with a chunksize greater than the current + * cache size? */ + if (var->contiguous == NC_CHUNKED && (chunksizes || deflate || contiguous)) + { + /* Determine default chunksizes for this variable. */ + if (!var->chunksizes[0]) + if ((retval = nc4_find_default_chunksizes2(grp, var))) + return retval; + + /* Adjust the cache. */ + if ((retval = nc4_adjust_var_cache(grp, var))) + return retval; + } + + /* Are we setting a fill modes? */ + if (no_fill) + { + if (*no_fill) + var->no_fill = 1; + else + var->no_fill = 0; + } + + /* Are we setting a fill value? */ + if (fill_value && !var->no_fill) + { + /* If fill value hasn't been set, allocate space. */ + if ((retval = nc4_get_typelen_mem(h5, var->xtype, 0, &type_size))) + return retval; + if (!var->fill_value) + if (!(var->fill_value = malloc(type_size))) + return NC_ENOMEM; + + /* Copy the fill_value. */ + LOG((4, "Copying fill value into metadata for variable %s", + var->name)); + memcpy(var->fill_value, fill_value, type_size); + + /* If there's a _FillValue attribute, delete it. */ + retval = nc_del_att(ncid, varid, _FillValue); + if (retval && retval != NC_ENOTATT) + return retval; + + /* Create a _FillValue attribute. */ + if ((retval = nc_put_att(ncid, varid, _FillValue, var->xtype, 1, fill_value))) + return retval; + } + + /* Is the user setting the endianness? */ + if (endianness) + var->type_info->endianness = *endianness; + + return NC_NOERR; +} + +/* Set the deflate level for a var, lower is faster, higher is + * better. Must be called after nc_def_var and before nc_enddef or any + * functions which writes data to the file. */ +int +NC4_def_var_deflate(int ncid, int varid, int shuffle, int deflate, + int deflate_level) +{ + return nc_def_var_extra(ncid, varid, &shuffle, &deflate, + &deflate_level, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +} + +/* Set checksum for a var. This must be called after the nc_def_var + * but before the nc_enddef. */ +int +NC4_def_var_fletcher32(int ncid, int varid, int fletcher32) +{ + return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, &fletcher32, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); +} + +/* Define chunking stuff for a var. This must be done after nc_def_var + and before nc_enddef. + + Chunking is required in any dataset with one or more unlimited + dimension in HDF5, or any dataset using a filter. + + Where chunksize is a pointer to an array of size ndims, with the + chunksize in each dimension. +*/ +int +NC4_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksizesp) +{ + return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL, + &contiguous, chunksizesp, NULL, NULL, NULL, NULL, NULL); +} + +/* Inquire about chunking stuff for a var. This is a private, + * undocumented function, used by the f77 API to avoid size_t + * problems. */ +int +nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + size_t *cs = NULL; + int i, retval; + + /* Find this ncid's file info. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + assert(nc); + + /* Must be netcdf-4. */ + if (!h5) + return NC_ENOTNC4; + + /* Find var cause I need the number of dims. */ + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; + + /* Allocate space for the size_t copy of the chunksizes array. */ + if (var->ndims) + if (!(cs = malloc(var->ndims * sizeof(size_t)))) + return NC_ENOMEM; + + retval = NC4_inq_var_all(ncid, varid, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, contiguousp, cs, NULL, + NULL, NULL, NULL, NULL); + + /* Copy to size_t array. */ + if (*contiguousp == NC_CHUNKED) + for (i = 0; i < var->ndims; i++) + { + chunksizesp[i] = cs[i]; + if (cs[i] > NC_MAX_INT) + retval = NC_ERANGE; + } + + if (var->ndims) + free(cs); + return retval; +} + +/* This function defines the chunking with ints, which works better + * with F77 portability. It is a secret function, which has been + * rendered unmappable, and it is impossible to apparate anywhere in + * this function. */ +int +nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + size_t *cs = NULL; + int i, retval; + + /* Find this ncid's file info. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + assert(nc); + + /* Must be netcdf-4. */ + if (!h5) + return NC_ENOTNC4; + + /* Find var cause I need the number of dims. */ + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; + + /* Allocate space for the size_t copy of the chunksizes array. */ + if (var->ndims) + if (!(cs = malloc(var->ndims * sizeof(size_t)))) + return NC_ENOMEM; + + /* Copy to size_t array. */ + for (i = 0; i < var->ndims; i++) + cs[i] = chunksizesp[i]; + + retval = nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL, + &contiguous, cs, NULL, NULL, NULL, NULL, NULL); + + if (var->ndims) + free(cs); + return retval; +} + +/* Define fill value behavior for a variable. This must be done after + nc_def_var and before nc_enddef. */ +int +NC4_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value) +{ + return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL, NULL, + NULL, &no_fill, fill_value, NULL, NULL, NULL); +} + + +/* Define the endianness of a variable. */ +int +NC4_def_var_endian(int ncid, int varid, int endianness) +{ + return nc_def_var_extra(ncid, varid, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, &endianness, NULL, NULL); +} + +/* Get var id from name. */ +int +NC4_inq_varid(int ncid, const char *name, int *varidp) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + char norm_name[NC_MAX_NAME + 1]; + int retval; + + if (!name) + return NC_EINVAL; + if (!varidp) + return NC_NOERR; + + LOG((2, "nc_inq_varid: ncid 0x%x name %s", ncid, name)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + + /* Handle netcdf-3. */ + assert(h5); + + /* Normalize name. */ + if ((retval = nc4_normalize_name(name, norm_name))) + return retval; + + /* Find var of this name. */ + for (var = grp->var; var; var = var->next) + if (!(strcmp(var->name, norm_name))) + { + *varidp = var->varid; + return NC_NOERR; + } + + return NC_ENOTVAR; +} + +/* Rename a var to "bubba," for example. + + According to the netcdf-3.5 docs: If the new name is longer than + the old name, the netCDF dataset must be in define mode. */ +int +NC4_rename_var(int ncid, int varid, const char *name) +{ + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + int retval = NC_NOERR; + + LOG((2, "nc_rename_var: ncid 0x%x varid %d name %s", + ncid, varid, name)); + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Take care of files created/opened with parallel-netcdf library. */ + if (nc->pnetcdf_file) + return ncmpi_rename_var(nc->int_ncid, varid, name); +#endif /* USE_PNETCDF */ + + /* Take care of netcdf-3 files. */ + assert(h5); + + /* Is the new name too long? */ + if (strlen(name) > NC_MAX_NAME) + return NC_EMAXNAME; + + /* Trying to write to a read-only file? No way, Jose! */ + if (h5->no_write) + return NC_EPERM; + + /* Check name validity, if strict nc3 rules are in effect for this + * file. */ + if ((retval = NC_check_name(name))) + return retval; + + /* Is name in use? */ + for (var = grp->var; var; var = var->next) + if (!strncmp(var->name, name, NC_MAX_NAME)) + return NC_ENAMEINUSE; + + /* Find the var. */ + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + break; + if (!var) + return NC_ENOTVAR; + + /* If we're not in define mode, new name must be of equal or + less size, if strict nc3 rules are in effect for this . */ + if (!(h5->flags & NC_INDEF) && strlen(name) > strlen(var->name) && + (h5->cmode & NC_CLASSIC_MODEL)) + return NC_ENOTINDEFINE; + + /* Change the HDF5 file, if this var has already been created + there. */ + if (var->created) + { + if (H5Gmove(grp->hdf_grpid, var->name, name) < 0) + BAIL(NC_EHDFERR); + } + + /* Now change the name in our metadata. */ + free(var->name); + if (!(var->name = malloc((strlen(name) + 1) * sizeof(char)))) + return NC_ENOMEM; + strcpy(var->name, name); + + exit: + return retval; +} + + +int +NC4_var_par_access(int ncid, int varid, int par_access) +{ +#ifndef USE_PARALLEL + return NC_ENOPAR; +#else + NC_FILE_INFO_T *nc; + NC_GRP_INFO_T *grp; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + int retval; + + LOG((1, "nc_var_par_access: ncid 0x%x varid %d par_access %d", ncid, + varid, par_access)); + + if (par_access != NC_INDEPENDENT && par_access != NC_COLLECTIVE) + return NC_EINVAL; + + /* Find info for this file and group, and set pointer to each. */ + if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) + return retval; + +#ifdef USE_PNETCDF + /* Handle files opened/created with parallel-netcdf library. */ + if (nc->pnetcdf_file) + { + if (par_access == nc->pnetcdf_access_mode) + return NC_NOERR; + + nc->pnetcdf_access_mode = par_access; + if (par_access == NC_INDEPENDENT) + return ncmpi_begin_indep_data(nc->int_ncid); + else + return ncmpi_end_indep_data(nc->int_ncid); + } +#endif /* USE_PNETCDF */ + + /* This function only for files opened with nc_open_par or nc_create_par. */ + if (!h5->parallel) + return NC_ENOPAR; + + /* Find the var, and set its preference. */ + for (var = grp->var; var; var = var->next) + if (var->varid == varid) + break; + if (!var) + return NC_ENOTVAR; + + if (par_access) + var->parallel_access = NC_COLLECTIVE; + else + var->parallel_access = NC_INDEPENDENT; + return NC_NOERR; +#endif /* USE_PARALLEL */ +} + +static int +nc4_put_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long, + const size_t *startp, const size_t *countp, const void *op) +{ + NC_FILE_INFO_T *nc; + + LOG((2, "nc4_put_vara_tc: ncid 0x%x varid %d mem_type %d mem_type_is_long %d", + ncid, varid, mem_type, mem_type_is_long)); + + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Handle files opened/created with the parallel-netcdf library. */ + if (nc->pnetcdf_file) + { + MPI_Offset mpi_start[NC_MAX_DIMS], mpi_count[NC_MAX_DIMS]; + int d; + + /* No NC_LONGs for parallel-netcdf library! */ + if (mem_type_is_long) + return NC_EINVAL; + + /* We must convert the start, count, and stride arrays to + * MPI_Offset type. */ + for (d = 0; d < nc->pnetcdf_ndims[varid]; d++) + { + mpi_start[d] = startp[d]; + mpi_count[d] = countp[d]; + } + + if (nc->pnetcdf_access_mode == NC_INDEPENDENT) + { + switch(mem_type) + { + case NC_BYTE: + return ncmpi_put_vara_schar(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_UBYTE: + return ncmpi_put_vara_uchar(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_CHAR: + return ncmpi_put_vara_text(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_SHORT: + return ncmpi_put_vara_short(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_INT: + return ncmpi_put_vara_int(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_FLOAT: + return ncmpi_put_vara_float(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_DOUBLE: + return ncmpi_put_vara_double(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_NAT: + default: + return NC_EBADTYPE; + } + } + else + { + switch(mem_type) + { + case NC_BYTE: + return ncmpi_put_vara_schar_all(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_UBYTE: + return ncmpi_put_vara_uchar_all(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_CHAR: + return ncmpi_put_vara_text_all(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_SHORT: + return ncmpi_put_vara_short_all(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_INT: + return ncmpi_put_vara_int_all(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_FLOAT: + return ncmpi_put_vara_float_all(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_DOUBLE: + return ncmpi_put_vara_double_all(nc->int_ncid, varid, mpi_start, mpi_count, op); + case NC_NAT: + default: + return NC_EBADTYPE; + } + } + } +#endif /* USE_PNETCDF */ + + /* NetCDF-3 cases handled by dispatch layer. */ + assert(nc->nc4_info); + + return nc4_put_vara(nc, ncid, varid, startp, countp, mem_type, + mem_type_is_long, (void *)op); +} + +int +nc4_get_hdf4_vara(NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp, + const size_t *countp, nc_type mem_nc_type, int is_long, void *data) +{ +#ifdef USE_HDF4 + NC_GRP_INFO_T *grp, *g; + NC_HDF5_FILE_INFO_T *h5; + NC_VAR_INFO_T *var; + NC_DIM_INFO_T *dim; + int32 start32[NC_MAX_VAR_DIMS], edge32[NC_MAX_VAR_DIMS]; + int retval, d; + + /* Find our metadata for this file, group, and var. */ + assert(nc); + if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) + return retval; + h5 = nc->nc4_info; + assert(grp && h5 && var && var->name); + + for (d = 0; d < var->ndims; d++) + { + start32[d] = startp[d]; + edge32[d] = countp[d]; + } + + if (SDreaddata(var->sdsid, start32, NULL, edge32, data)) + return NC_EHDFERR; + +#endif /* USE_HDF4 */ + return NC_NOERR; +} + +/* Get an array. */ +static int +nc4_get_vara_tc(int ncid, int varid, nc_type mem_type, int mem_type_is_long, + const size_t *startp, const size_t *countp, void *ip) +{ + NC_FILE_INFO_T *nc; + + LOG((2, "nc4_get_vara_tc: ncid 0x%x varid %d mem_type %d mem_type_is_long %d", + ncid, varid, mem_type, mem_type_is_long)); + + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + +#ifdef USE_PNETCDF + /* Handle files opened/created with the parallel-netcdf library. */ + if (nc->pnetcdf_file) + { + MPI_Offset mpi_start[NC_MAX_VAR_DIMS], mpi_count[NC_MAX_VAR_DIMS]; + int d; + + /* No NC_LONGs for parallel-netcdf library! */ + if (mem_type_is_long) + return NC_EINVAL; + + /* We must convert the start, count, and stride arrays to + * MPI_Offset type. */ + for (d = 0; d < nc->pnetcdf_ndims[varid]; d++) + { + mpi_start[d] = startp[d]; + mpi_count[d] = countp[d]; + } + + if (nc->pnetcdf_access_mode == NC_INDEPENDENT) + { + switch(mem_type) + { + case NC_BYTE: + return ncmpi_get_vara_schar(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_UBYTE: + return ncmpi_get_vara_uchar(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_CHAR: + return ncmpi_get_vara_text(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_SHORT: + return ncmpi_get_vara_short(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_INT: + return ncmpi_get_vara_int(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_FLOAT: + return ncmpi_get_vara_float(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_DOUBLE: + return ncmpi_get_vara_double(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_NAT: + default: + return NC_EBADTYPE; + } + } + else + { + switch(mem_type) + { + case NC_BYTE: + return ncmpi_get_vara_schar_all(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_UBYTE: + return ncmpi_get_vara_uchar_all(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_CHAR: + return ncmpi_get_vara_text_all(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_SHORT: + return ncmpi_get_vara_short_all(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_INT: + return ncmpi_get_vara_int_all(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_FLOAT: + return ncmpi_get_vara_float_all(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_DOUBLE: + return ncmpi_get_vara_double_all(nc->int_ncid, varid, mpi_start, mpi_count, ip); + case NC_NAT: + default: + return NC_EBADTYPE; + } + } + } +#endif /* USE_PNETCDF */ + + /* Handle netCDF-3 cases. */ + assert(nc->nc4_info); + + /* Handle HDF4 cases. */ + if (nc->nc4_info->hdf4) + return nc4_get_hdf4_vara(nc, ncid, varid, startp, countp, mem_type, + mem_type_is_long, (void *)ip); + + /* Handle HDF5 cases. */ + return nc4_get_vara(nc, ncid, varid, startp, countp, mem_type, + mem_type_is_long, (void *)ip); +} + +int +NC4_put_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, const void *op, int memtype) +{ + return nc4_put_vara_tc(ncid, varid, memtype, 0, startp, countp, op); +} + + +/* Read an array of values. */ +int +NC4_get_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, void *ip, int memtype) +{ + return nc4_get_vara_tc(ncid, varid, memtype, 0, startp, countp, ip); +} diff --git a/extern/src_netcdf4/nc_logging.h b/extern/src_netcdf4/nc_logging.h new file mode 100644 index 0000000000000000000000000000000000000000..36471ce39959e7560ab5ff963dbbe22e6c7044ef --- /dev/null +++ b/extern/src_netcdf4/nc_logging.h @@ -0,0 +1,62 @@ +/* Copyright 2010, University Corporation for Atmospheric Research. See + COPYRIGHT file for copying and redistribution conditions. + + This file is part of netcdf-4, a netCDF-like interface for HDF5, or + a HDF5 backend for netCDF, depending on your point of view. + + This file contains macros and prototyes relating to logging. + + $Id: nc_logging.h,v 1.1 2010/06/01 15:34:49 ed Exp $ +*/ + +#ifndef _NCLOGGING_ +#define _NCLOGGING_ + +#include +#include + +#ifdef LOGGING + +/* To log something... */ +void nc_log(int severity, const char *fmt, ...); +void nc_log_hdf5(void); + +#define LOG(e) nc_log e + +/* To log based on error code, and set retval. */ +#define BAIL2(e) do { \ +retval = e; \ +LOG((0, "file %s, line %d.\n%s", __FILE__, __LINE__, nc_strerror(e))); \ +nc_log_hdf5(); \ +} while (0) + +/* To log an error message, set retval, and jump to exit. */ +#define BAIL(e) do { \ +BAIL2(e); \ +goto exit; \ +} while (0) + +/* To set retval and jump to exit, without logging error message. */ +#define BAIL_QUIET(e) do { \ +retval = e; \ +goto exit; \ +} while (0) + +#else + +/* These definitions will be used unless LOGGING is defined. */ +#define LOG(e) +#define BAIL(e) do { \ +retval = e; \ +goto exit; \ +} while (0) +#define BAIL_QUIET BAIL +#define BAIL2(e) do { \ +goto exit; \ +} while (0) +#define nc_set_log_level(e) +#endif + +#endif /* _NCLOGGING_ */ + + diff --git a/extern/src_netcdf4/nc_tests.h b/extern/src_netcdf4/nc_tests.h new file mode 100644 index 0000000000000000000000000000000000000000..3904564ec4eef629a7b296acc70dfb915d86cdab --- /dev/null +++ b/extern/src_netcdf4/nc_tests.h @@ -0,0 +1,37 @@ +/** \internal +\file +Common includes, defines, etc., for test code in the libsrc4 and +nc_test4 directories. + +This is part of the netCDF package. Copyright 2005 University +Corporation for Atmospheric Research/Unidata. See \ref copyright file +for conditions of use. +*/ + +#ifndef _NC_TESTS_H +#define _NC_TESTS_H + +#include +#include +#include +#include +#include +#ifdef USE_PARALLEL +#include "netcdf_par.h" +#endif +#include "netcdf.h" +#include "err_macros.h" + +/** Useful define for tests. */ +/** \{ */ +#define MEGABYTE 1048576 +#define HALF_MEG (MEGABYTE/2) +#define MILLION 1000000 +#define SIXTEEN_MEG 16777216 +#define FOUR_MEG (SIXTEEN_MEG/4) +#define THIRTY_TWO_MEG (SIXTEEN_MEG * 2) +#define SIXTY_FOUR_MEG (SIXTEEN_MEG * 4) +#define ONE_TWENTY_EIGHT_MEG (SIXTEEN_MEG * 8) +/** \} */ + +#endif /* _NC_TESTS_H */ diff --git a/extern/src_netcdf4/nc_uri.c b/extern/src_netcdf4/nc_uri.c new file mode 100644 index 0000000000000000000000000000000000000000..aadf941aa3eceef71d7c6262ec5418a23be47a17 --- /dev/null +++ b/extern/src_netcdf4/nc_uri.c @@ -0,0 +1,466 @@ +/********************************************************************* + * Copyright 2010, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header$ + *********************************************************************/ + +#include "config.h" + +#include +#include +#include + +#include "nc_uri.h" + +#define NC_URIDEBUG + +#define LBRACKET '[' +#define RBRACKET ']' + +#ifndef FIX +#define FIX(s) ((s)==NULL?"":(s)) +#endif + +#ifndef NILLEN +#define NILLEN(s) ((s)==NULL?0:strlen(s)) +#endif + + +static char* legalprotocols[] = { +"file:", +"http:", +"https:", +"ftp:", +NULL /* NULL terminate*/ +}; + +static void nc_paramfree(char** params); +static int nc_find(char** params, const char* key); + +/* Do a simple uri parse: return 0 if fail, 1 otherwise*/ +int +nc_uriparse(const char* uri0, NC_URI** nc_urip) +{ + NC_URI* nc_uri = NULL; + char* uri; + char** pp; + char* p; + char* p1; + int c; + + /* accumulate parse points*/ + char* protocol = NULL; + char* params = NULL; + char* host = NULL; + char* port = NULL; + char* constraint = NULL; + char* user = NULL; + char* pwd = NULL; + char* file = NULL; + + nc_uri = (NC_URI*)calloc(1,sizeof(NC_URI)); + if(nc_uri == NULL) return 0; + + /* Temporary hack to remove escape characters inserted by Windows or MinGW */ + if(strchr(uri0,'\\') != NULL) { + char* u = strdup(uri0); + if(u == NULL) return 0; + p = u; + p1 = u; + while((c=*p1++)) {if(c != '\\') *p++ = c;} + uri0 = (const char*)u; + } + + /* make local copy of uri */ + uri = strdup(uri0); + + /* remove all whitespace*/ + p = uri; + p1 = uri; + while((c=*p1++)) {if(c != ' ' && c != '\t') *p++ = c;} + + p = uri; + + /* break up the uri string into pieces*/ + + /* 1. leading bracketed parameters */ + if(*p == LBRACKET) { + params = p+1; + /* find end of the clientparams*/ + for(;*p;p++) {if(p[0] == RBRACKET && p[1] != LBRACKET) break;} + if(*p == 0) goto fail; /* malformed client params*/ + *p = '\0'; /* leave off the trailing rbracket for now */ + p++; /* move past the params*/ + } + + /* verify that the uri starts with an acceptable protocol*/ + for(pp=legalprotocols;*pp;pp++) { + if(strncmp(p,*pp,strlen(*pp))==0) break; + } + if(*pp == NULL) goto fail; /* illegal protocol*/ + /* save the protocol */ + protocol = *pp; + + /* 4. skip protocol */ + p += strlen(protocol); + + /* 5. skip // */ + if(*p != '/' && *(p+1) != '/') + goto fail; + p += 2; + + /* 6. Mark the end of the host section */ + file = strchr(p,'/'); + if(file) { + *file++ = '\0'; /* warning: we just overwrote the leading / */ + } else + goto fail; /* url only has host part, no path */ + + /* 7. extract any user:pwd */ + p1 = strchr(p,'@'); + if(p1) {/* Assume we have user:pwd@ */ + *p1 = '\0'; + user = p; + pwd = strchr(p,':'); + if(!pwd) goto fail; /* malformed */ + *pwd++ = '\0'; + p = pwd+strlen(pwd)+1; + } + + /* 8. extract host and port */ + host = p; + port = strchr(p,':'); + if(port) { + *port++ = '\0'; + } + + /* 9. Look for '?' */ + constraint = strchr(file,'?'); + if(constraint) { + *constraint++ = '\0'; + } + + /* assemble the component pieces*/ + if(uri0 && strlen(uri0) > 0) + nc_uri->uri = strdup(uri0); + if(protocol && strlen(protocol) > 0) { + nc_uri->protocol = strdup(protocol); + /* remove trailing ':' */ + nc_uri->protocol[strlen(protocol)-1] = '\0'; + } + if(user && strlen(user) > 0) + nc_uri->user = strdup(user); + if(pwd && strlen(pwd) > 0) + nc_uri->password = strdup(pwd); + if(host && strlen(host) > 0) + nc_uri->host = strdup(host); + if(port && strlen(port) > 0) + nc_uri->port = strdup(port); + if(file && strlen(file) > 0) { + /* Add back the leading / */ + nc_uri->file = malloc(strlen(file)+2); + strcpy(nc_uri->file,"/"); + strcat(nc_uri->file,file); + } + if(constraint && strlen(constraint) > 0) + nc_uri->constraint = strdup(constraint); + nc_urisetconstraints(nc_uri,constraint); + if(params != NULL && strlen(params) > 0) { + nc_uri->params = (char*)malloc(1+2+strlen(params)); + strcpy(nc_uri->params,"["); + strcat(nc_uri->params,params); + strcat(nc_uri->params,"]"); + } + +#ifdef NC_XDEBUG + { + fprintf(stderr,"nc_uri:"); + fprintf(stderr," params=|%s|",FIX(nc_uri->params)); + fprintf(stderr," protocol=|%s|",FIX(nc_uri->protocol)); + fprintf(stderr," host=|%s|",FIX(nc_uri->host)); + fprintf(stderr," port=|%s|",FIX(nc_uri->port)); + fprintf(stderr," file=|%s|",FIX(nc_uri->file)); + fprintf(stderr," constraint=|%s|",FIX(nc_uri->constraint)); + fprintf(stderr,"\n"); + } +#endif + free(uri); + if(nc_urip != NULL) *nc_urip = nc_uri; + return 1; + +fail: + if(nc_uri) nc_urifree(nc_uri); + if(uri != NULL) free(uri); + return 0; +} + +void +nc_urifree(NC_URI* nc_uri) +{ + if(nc_uri == NULL) return; + if(nc_uri->uri != NULL) {free(nc_uri->uri);} + if(nc_uri->protocol != NULL) {free(nc_uri->protocol);} + if(nc_uri->user != NULL) {free(nc_uri->user);} + if(nc_uri->password != NULL) {free(nc_uri->password);} + if(nc_uri->host != NULL) {free(nc_uri->host);} + if(nc_uri->port != NULL) {free(nc_uri->port);} + if(nc_uri->file != NULL) {free(nc_uri->file);} + if(nc_uri->constraint != NULL) {free(nc_uri->constraint);} + if(nc_uri->projection != NULL) {free(nc_uri->projection);} + if(nc_uri->selection != NULL) {free(nc_uri->selection);} + if(nc_uri->params != NULL) {free(nc_uri->params);} + if(nc_uri->paramlist != NULL) nc_paramfree(nc_uri->paramlist); + free(nc_uri); +} + +/* Replace the constraints */ +void +nc_urisetconstraints(NC_URI* duri,const char* constraints) +{ + char* proj = NULL; + char* select = NULL; + const char* p; + + if(duri->constraint == NULL) free(duri->constraint); + if(duri->projection != NULL) free(duri->projection); + if(duri->selection != NULL) free(duri->selection); + duri->constraint = NULL; + duri->projection = NULL; + duri->selection = NULL; + + if(constraints == NULL || strlen(constraints)==0) return; + + duri->constraint = strdup(constraints); + if(*duri->constraint == '?') + strcpy(duri->constraint,duri->constraint+1); + + p = duri->constraint; + proj = (char*) p; + select = strchr(proj,'&'); + if(select != NULL) { + size_t plen = (select - proj); + if(plen == 0) { + proj = NULL; + } else { + proj = (char*)malloc(plen+1); + memcpy((void*)proj,p,plen); + proj[plen] = '\0'; + } + select = nulldup(select); + } else { + proj = nulldup(proj); + select = NULL; + } + duri->projection = proj; + duri->selection = select; +} + + +/* Construct a complete NC_ URI without the client params + and optionally with the constraints; + caller frees returned string +*/ + +char* +nc_uribuild(NC_URI* duri, const char* prefix, const char* suffix, int pieces) +{ + size_t len = 0; + char* newuri; + int withparams = ((pieces&NC_URIPARAMS) + && duri->params != NULL); + int withuserpwd = ((pieces&NC_URIUSERPWD) + && duri->user != NULL && duri->password != NULL); + int withconstraints = ((pieces&NC_URICONSTRAINTS) + && duri->constraint != NULL); + + if(prefix != NULL) len += NILLEN(prefix); + if(withparams) { + len += NILLEN(duri->params); + } + len += (NILLEN(duri->protocol)+NILLEN("://")); + if(withuserpwd) { + len += (NILLEN(duri->user)+NILLEN(duri->password)+NILLEN(":@")); + } + len += (NILLEN(duri->host)); + if(duri->port != NULL) { + len += (NILLEN(":")+NILLEN(duri->port)); + } + len += (NILLEN(duri->file)); + if(suffix != NULL) len += NILLEN(suffix); + if(withconstraints) { + len += (NILLEN("?")+NILLEN(duri->constraint)); + } + len += 1; /* null terminator */ + + newuri = (char*)malloc(len); + if(!newuri) return NULL; + + newuri[0] = '\0'; + if(prefix != NULL) strcat(newuri,prefix); + if(withparams) { + strcat(newuri,duri->params); + } + strcat(newuri,duri->protocol); + strcat(newuri,"://"); + if(withuserpwd) { + strcat(newuri,duri->user); + strcat(newuri,":"); + strcat(newuri,duri->password); + strcat(newuri,"@"); + } + if(duri->host != NULL) { /* may be null if using file: protocol */ + strcat(newuri,duri->host); + } + if(duri->port != NULL) { + strcat(newuri,":"); + strcat(newuri,duri->port); + } + strcat(newuri,duri->file); + if(suffix != NULL) strcat(newuri,suffix); + if(withconstraints) { + strcat(newuri,"?"); + strcat(newuri,duri->constraint); + } + return newuri; +} + +/**************************************************/ +/* Parameter support */ + +/* +Client parameters are assumed to be +one or more instances of bracketed pairs: +e.g "[...][...]...". +The bracket content in turn is assumed to be a +comma separated list of = pairs. +e.g. x=y,z=,a=b. +If the same parameter is specifed more than once, +then the first occurrence is used; this is so that +is possible to forcibly override user specified +parameters by prefixing. +IMPORTANT: client parameter string is assumed to +have blanks compress out. +Returns 1 if parse suceeded, 0 otherwise; +*/ + +int +nc_uridecodeparams(NC_URI* nc_uri) +{ + char* cp; + char* cq; + int c; + int i; + int nparams; + char* params0; + char* params; + char* params1; + char** plist; + + if(nc_uri == NULL) return 0; + if(nc_uri->params == NULL) return 1; + + params0 = nc_uri->params; + + /* Pass 1 to replace beginning '[' and ending ']' */ + if(params0[0] == '[') + params = strdup(params0+1); + else + params = strdup(params0); + + if(params[strlen(params)-1] == ']') + params[strlen(params)-1] = '\0'; + + /* Pass 2 to replace "][" pairs with ','*/ + params1 = strdup(params); + cp=params; cq = params1; + while((c=*cp++)) { + if(c == RBRACKET && *cp == LBRACKET) {cp++; c = ',';} + *cq++ = c; + } + *cq = '\0'; + free(params); + params = params1; + + /* Pass 3 to break string into pieces and count # of pairs */ + nparams=0; + for(cp=params;(c=*cp);cp++) { + if(c == ',') {*cp = '\0'; nparams++;} + } + nparams++; /* for last one */ + + /* plist is an env style list */ + plist = (char**)calloc(1,sizeof(char*)*(2*nparams+1)); /* +1 for null termination */ + + /* Pass 4 to break up each pass into a (name,value) pair*/ + /* and insert into the param list */ + /* parameters of the form name name= are converted to name=""*/ + cp = params; + for(i=0;iparamlist != NULL) + nc_paramfree(nc_uri->paramlist); + nc_uri->paramlist = plist; + return 1; +} + +int +nc_urilookup(NC_URI* uri, const char* key, const char** resultp) +{ + int i; + char* value = NULL; + if(uri == NULL || key == NULL || uri->params == NULL) return 0; + if(uri->paramlist == NULL) { + i = nc_uridecodeparams(uri); + if(!i) return 0; + } + i = nc_find(uri->paramlist,key); + if(i < 0) return 0; + value = uri->paramlist[(2*i)+1]; + if(resultp) *resultp = value; + return 1; +} + +int +nc_urisetparams(NC_URI* uri, const char* newparams) +{ + if(uri == NULL) return 0; + if(uri->paramlist != NULL) nc_paramfree(uri->paramlist); + uri->paramlist = NULL; + if(uri->params != NULL) free(uri->params); + uri->params = nulldup(newparams); + return 1; +} + +/* Internal version of lookup; returns the paired index of the key */ +static int +nc_find(char** params, const char* key) +{ + int i; + char** p; + for(i=0,p=params;*p;p+=2,i++) { + if(strcmp(key,*p)==0) return i; + } + return -1; +} + +static void +nc_paramfree(char** params) +{ + char** p; + if(params == NULL) return; + for(p=params;*p;p+=2) { + free(*p); + if(p[1] != NULL) free(p[1]); + } + free(params); +} diff --git a/extern/src_netcdf4/nc_uri.h b/extern/src_netcdf4/nc_uri.h new file mode 100644 index 0000000000000000000000000000000000000000..6fbdeafd734098576e4dac62610e5ae8973b40c7 --- /dev/null +++ b/extern/src_netcdf4/nc_uri.h @@ -0,0 +1,50 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef NC_URI_H +#define NC_URI_H + +/*! This is an open structure meaning + it is ok to directly access its fields*/ +typedef struct NC_URI { + char* uri; /* as passed by the caller */ + char* protocol; + char* user; /* from user:password@ */ + char* password; /* from user:password@ */ + char* host; /*!< host*/ + char* port; /*!< host */ + char* file; /*!< file */ + char* constraint; /*!< projection+selection */ + char* projection; /*!< without leading '?'*/ + char* selection; /*!< with leading '&'*/ + char* params; /* all params */ + char** paramlist; /*! entry not found; 1=>found; result holds value (may be null). + In any case, the result is imutable and should not be free'd. +*/ +extern int nc_urilookup(NC_URI*, const char* param, const char** result); + +#endif /*NC_URI_H*/ diff --git a/extern/src_netcdf4/ncaux.c b/extern/src_netcdf4/ncaux.c new file mode 100644 index 0000000000000000000000000000000000000000..9c0c2f32baf562039b09bc98e4198fd83206ee6c --- /dev/null +++ b/extern/src_netcdf4/ncaux.c @@ -0,0 +1,390 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* +This code is a variant of the H5detect.c code from HDF5. +Author: D. Heimbigner 10/7/2008 +*/ + +#include +#include +#include +#include + +#include "ncaux.h" + +struct NCAUX_FIELD { + char* name; + nc_type fieldtype; + int ndims; + int dimsizes[NC_MAX_VAR_DIMS]; + size_t size; + size_t offset; + size_t alignment; +}; + +struct NCAUX_CMPD { + int ncid; + int mode; + char* name; + int nfields; + struct NCAUX_FIELD* fields; + size_t size; + size_t offset; /* cumulative as fields are added */ + size_t alignment; +}; + +static int ncaux_initialized = 0; + +static void compute_alignments(void); +static int computefieldinfo(struct NCAUX_CMPD* cmpd); + +int +ncaux_begin_compound(int ncid, const char *name, int alignmode, void** tagp) +{ + int status = NC_NOERR; + struct NCAUX_CMPD* cmpd = NULL; + + if(!ncaux_initialized) { + compute_alignments(); + ncaux_initialized = 1; + } + + if(tagp) *tagp = NULL; + + cmpd = (struct NCAUX_CMPD*)calloc(1,sizeof(struct NCAUX_CMPD)); + if(cmpd == NULL) {status = NC_ENOMEM; goto fail;} + cmpd->ncid = ncid; + cmpd->mode = alignmode; + cmpd->nfields = 0; + cmpd->name = strdup(name); + if(cmpd->name == NULL) {status = NC_ENOMEM; goto fail;} + + if(tagp) *tagp = (void*)cmpd; + + return status; + +fail: + ncaux_abort_compound((void*)cmpd); + return status; +} + +int +ncaux_abort_compound(void* tag) +{ + int i; + struct NCAUX_CMPD* cmpd = (struct NCAUX_CMPD*)tag; + if(cmpd == NULL) goto done; + if(cmpd->name) free(cmpd->name); + for(i=0;infields;i++) { + struct NCAUX_FIELD* field = &cmpd->fields[i]; + if(field->name) free(field->name); + } + if(cmpd->fields) free(cmpd->fields); + free(cmpd); + +done: + return NC_NOERR; +} + +int +ncaux_add_field(void* tag, const char *name, nc_type field_type, + int ndims, const int* dimsizes) +{ + int i; + int status = NC_NOERR; + struct NCAUX_CMPD* cmpd = (struct NCAUX_CMPD*)tag; + struct NCAUX_FIELD* newfields = NULL; + struct NCAUX_FIELD* field = NULL; + + if(cmpd == NULL) goto done; + if(ndims < 0) {status = NC_EINVAL; goto done;} + for(i=0;ifields == NULL) { + newfields = (struct NCAUX_FIELD*)calloc(1,sizeof(struct NCAUX_FIELD)); + } else { + newfields = (struct NCAUX_FIELD*)realloc(cmpd->fields,cmpd->nfields+1*sizeof(struct NCAUX_FIELD)); + } + if(cmpd->fields == NULL) {status = NC_ENOMEM; goto done;} + cmpd->fields = newfields; + field = &cmpd->fields[cmpd->nfields+1]; + field->name = strdup(name); + field->fieldtype = field_type; + if(field->name == NULL) {status = NC_ENOMEM; goto done;} + field->ndims = ndims; + memcpy(field->dimsizes,dimsizes,sizeof(int)*ndims); + cmpd->nfields++; + +done: + return status; +} + +static size_t +dimproduct(int ndims, int* dimsizes) +{ + int i; + size_t product = 1; + for(i=0;incid, cmpd->size, cmpd->name, idp); + if(status != NC_NOERR) goto done; + + for(i=0;infields;i++) { + struct NCAUX_FIELD* field = &cmpd->fields[i]; + if(field->ndims > 0) { + status = nc_insert_compound(cmpd->ncid, *idp, field->name, + field->offset, field->fieldtype); + } else { + status = nc_insert_array_compound(cmpd->ncid, *idp, field->name, + field->offset, field->fieldtype, + field->ndims,field->dimsizes); + } + if(status != NC_NOERR) goto done; + } + +done: + return status; +} + +/**************************************************/ + +/* +The heart of this is the following macro, +which computes the offset of a field x +when preceded by a char field. +The assumptions appear to be as follows: +1. the offset produced in this situation indicates + the alignment for x relative in such a way that it + depends only on the types that precede it in the struct. +2. the compiler does not reorder fields. +3. arrays are tightly packed. +4. nested structs are alignd according to their first member + (this actually follows from C language requirement that + a struct can legally be cast to an instance of its first member). +Given the alignments for the various common primitive types, +it is assumed that one can use them anywhere to construct +the layout of a struct of such types. +It seems to work for HDF5 for a wide variety of machines. +*/ + +#define COMP_ALIGNMENT(DST,TYPE) {\ + struct {char f1; TYPE x;} tmp; \ + DST.typename = #TYPE ; \ + DST.alignment = (size_t)((char*)(&(tmp.x)) - (char*)(&tmp));} + +/* Define indices for every primitive C type */ +/* NAT => NOT-A-TYPE*/ +#define NATINDEX 0 +#define CHARINDEX 1 +#define UCHARINDEX 2 +#define SHORTINDEX 3 +#define USHORTINDEX 4 +#define INTINDEX 5 +#define UINTINDEX 6 +#define LONGINDEX 7 +#define ULONGINDEX 8 +#define LONGLONGINDEX 9 +#define ULONGLONGINDEX 10 +#define FLOATINDEX 11 +#define DOUBLEINDEX 12 +#define PTRINDEX 13 +#define NCVLENINDEX 14 + +#define NCTYPES 15 + +typedef struct Alignment { + char* typename; + int alignment; +} Alignment; + +typedef Alignment Typealignvec; + +/* Capture in struct and in a vector*/ +typedef struct Typealignset { + Alignment charalign; /* char*/ + Alignment ucharalign; /* unsigned char*/ + Alignment shortalign; /* short*/ + Alignment ushortalign; /* unsigned short*/ + Alignment intalign; /* int*/ + Alignment uintalign; /* unsigned int*/ + Alignment longalign; /* long*/ + Alignment ulongalign; /* unsigned long*/ + Alignment longlongalign; /* long long*/ + Alignment ulonglongalign; /* unsigned long long*/ + Alignment floatalign; /* float*/ + Alignment doublealign; /* double*/ + Alignment ptralign; /* void**/ + Alignment ncvlenalign; /* nc_vlen_t*/ +} Typealignset; + +static Typealignvec vec[NCTYPES]; +static Typealignset set; + +static void +compute_alignments(void) +{ + /* Compute the alignments for all the common C data types*/ + /* First for the struct*/ + /* initialize*/ + memset((void*)&set,0,sizeof(set)); + memset((void*)vec,0,sizeof(vec)); + + COMP_ALIGNMENT(set.charalign,char); + COMP_ALIGNMENT(set.ucharalign,unsigned char); + COMP_ALIGNMENT(set.shortalign,short); + COMP_ALIGNMENT(set.ushortalign,unsigned short); + COMP_ALIGNMENT(set.intalign,int); + COMP_ALIGNMENT(set.uintalign,unsigned int); + COMP_ALIGNMENT(set.longalign,long); + COMP_ALIGNMENT(set.ulongalign,unsigned long); + COMP_ALIGNMENT(set.longlongalign,long long); + COMP_ALIGNMENT(set.ulonglongalign,unsigned long long); + COMP_ALIGNMENT(set.floatalign,float); + COMP_ALIGNMENT(set.doublealign,double); + COMP_ALIGNMENT(set.ptralign,void*); + COMP_ALIGNMENT(set.ncvlenalign,nc_vlen_t); + + /* Then the vector*/ + COMP_ALIGNMENT(vec[CHARINDEX],char); + COMP_ALIGNMENT(vec[UCHARINDEX],unsigned char); + COMP_ALIGNMENT(vec[SHORTINDEX],short); + COMP_ALIGNMENT(vec[USHORTINDEX],unsigned short); + COMP_ALIGNMENT(vec[INTINDEX],int); + COMP_ALIGNMENT(vec[UINTINDEX],unsigned int); + COMP_ALIGNMENT(vec[LONGINDEX],long); + COMP_ALIGNMENT(vec[ULONGINDEX],unsigned long); + COMP_ALIGNMENT(vec[LONGLONGINDEX],long long); + COMP_ALIGNMENT(vec[ULONGLONGINDEX],unsigned long long); + COMP_ALIGNMENT(vec[FLOATINDEX],float); + COMP_ALIGNMENT(vec[DOUBLEINDEX],double); + COMP_ALIGNMENT(vec[PTRINDEX],void*); + COMP_ALIGNMENT(vec[NCVLENINDEX],nc_vlen_t); +} + +static size_t +nctypealignment(nc_type nctype) +{ + Alignment* align = NULL; + int index = 0; + switch (nctype) { + case NC_BYTE: index = UCHARINDEX; break; + case NC_CHAR: index = CHARINDEX; break; + case NC_SHORT: index = SHORTINDEX; break; + case NC_INT: index = INTINDEX; break; + case NC_FLOAT: index = FLOATINDEX; break; + case NC_DOUBLE: index = DOUBLEINDEX; break; + case NC_UBYTE: index = UCHARINDEX; break; + case NC_USHORT: index = USHORTINDEX; break; + case NC_UINT: index = UINTINDEX; break; + case NC_INT64: index = LONGLONGINDEX; break; + case NC_UINT64: index = ULONGLONGINDEX; break; + case NC_STRING: index = PTRINDEX; break; + case NC_VLEN: index = NCVLENINDEX; break; + case NC_OPAQUE: index = UCHARINDEX; break; + default: assert(0); + } + align = &vec[index]; + return align->alignment; +} + +static int +getpadding(int offset, int alignment) +{ + int rem = (alignment==0?0:(offset % alignment)); + int pad = (rem==0?0:(alignment - rem)); + return pad; +} + +/* Find first primitive field of a possibly nested sequence of compounds */ +static nc_type +findfirstfield(int ncid, nc_type xtype) +{ + int status = NC_NOERR; + nc_type fieldtype = xtype; + if(xtype <= NC_MAX_ATOMIC_TYPE) goto done; + + status = nc_inq_compound_fieldtype(ncid, xtype, 0, &fieldtype); + if(status != NC_NOERR) goto done; + fieldtype = findfirstfield(ncid,fieldtype); + +done: + return (status == NC_NOERR?fieldtype:NC_NAT); +} + +static int +computefieldinfo(struct NCAUX_CMPD* cmpd) +{ + int i; + int status = NC_NOERR; + size_t offset = 0; + size_t totaldimsize; + + /* Assign the sizes for the fields */ + for(i=0;infields;i++) { + struct NCAUX_FIELD* field = &cmpd->fields[i]; + status = nc_inq_type(cmpd->ncid,field->fieldtype,NULL,&field->size); + if(status != NC_NOERR) goto done; + totaldimsize = dimproduct(field->ndims,field->dimsizes); + field->size *= totaldimsize; + } + + for(offset=0,i=0;infields;i++) { + struct NCAUX_FIELD* field = &cmpd->fields[i]; + int alignment = 0; + nc_type firsttype = findfirstfield(cmpd->ncid,field->fieldtype); + + /* only support 'c' alignment for now*/ + switch (field->fieldtype) { + case NC_OPAQUE: + field->alignment = 1; + break; + case NC_ENUM: + field->alignment = nctypealignment(firsttype); + break; + case NC_VLEN: /*fall thru*/ + case NC_COMPOUND: + field->alignment = nctypealignment(firsttype); + break; + default: + field->alignment = nctypealignment(field->fieldtype); + break; + } + offset += getpadding(offset,alignment); + field->offset = offset; + offset += field->size; + } + cmpd->size = offset; + cmpd->alignment = cmpd->fields[0].alignment; + +done: + return status; +} diff --git a/extern/src_netcdf4/ncaux.h b/extern/src_netcdf4/ncaux.h new file mode 100644 index 0000000000000000000000000000000000000000..876647ad22a6d0c800391c856ca2e095b0ab2562 --- /dev/null +++ b/extern/src_netcdf4/ncaux.h @@ -0,0 +1,25 @@ +/********************************************************************* + * Copyright 2010, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Id$ + * $Header$ + *********************************************************************/ + +#ifndef NCAUX_H +#define NCAUX_H + +#define NCAUX_ALIGN_C 0 +#define NCAUX_ALIGN_UNIFORM 1 + +extern int ncaux_begin_compound(int ncid, const char *name, int alignmode, + void** tag); + +extern int ncaux_end_compound(void* tag, nc_type* typeid); + +extern int ncaux_abort_compound(void* tag); + +extern int ncaux_add_field(void* tag, const char *name, nc_type field_type, + int ndims, const int* dimsizes); + +#endif /*NCAUX_H*/ + diff --git a/extern/src_netcdf4/ncbytes.c b/extern/src_netcdf4/ncbytes.c new file mode 100644 index 0000000000000000000000000000000000000000..677007793debca7b7228aa47797ea40cfe640804 --- /dev/null +++ b/extern/src_netcdf4/ncbytes.c @@ -0,0 +1,191 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include +#include +#include + +#include "ncbytes.h" + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define DEFAULTALLOC 1024 +#define ALLOCINCR 1024 + +static int ncbytesdebug = 1; + +static long +ncbytesfail(void) +{ + fflush(stdout); + fprintf(stderr,"bytebuffer failure\n"); + fflush(stderr); + if(ncbytesdebug) abort(); + return FALSE; +} + +NCbytes* +ncbytesnew(void) +{ + NCbytes* bb = (NCbytes*)malloc(sizeof(NCbytes)); + if(bb == NULL) return (NCbytes*)ncbytesfail(); + bb->alloc=0; + bb->length=0; + bb->content=NULL; + bb->nonextendible = 0; + return bb; +} + +int +ncbytessetalloc(NCbytes* bb, unsigned int sz) +{ + char* newcontent; + if(bb == NULL) return ncbytesfail(); + if(sz <= 0) {sz = (bb->alloc?2*bb->alloc:DEFAULTALLOC);} + if(bb->alloc >= sz) return TRUE; + if(bb->nonextendible) return ncbytesfail(); + newcontent=(char*)calloc(sz,sizeof(char)); + if(bb->alloc > 0 && bb->length > 0 && bb->content != NULL) { + memcpy((void*)newcontent,(void*)bb->content,sizeof(char)*bb->length); + } + if(bb->content != NULL) free(bb->content); + bb->content=newcontent; + bb->alloc=sz; + return TRUE; +} + +void +ncbytesfree(NCbytes* bb) +{ + if(bb == NULL) return; + if(!bb->nonextendible && bb->content != NULL) free(bb->content); + free(bb); +} + +int +ncbytessetlength(NCbytes* bb, unsigned int sz) +{ + if(bb == NULL) return ncbytesfail(); + if(sz > bb->alloc) {if(!ncbytessetalloc(bb,sz)) return ncbytesfail();} + bb->length = sz; + return TRUE; +} + +int +ncbytesfill(NCbytes* bb, char fill) +{ + unsigned int i; + if(bb == NULL) return ncbytesfail(); + for(i=0;ilength;i++) bb->content[i] = fill; + return TRUE; +} + +int +ncbytesget(NCbytes* bb, unsigned int index) +{ + if(bb == NULL) return -1; + if(index >= bb->length) return -1; + return bb->content[index]; +} + +int +ncbytesset(NCbytes* bb, unsigned int index, char elem) +{ + if(bb == NULL) return ncbytesfail(); + if(index >= bb->length) return ncbytesfail(); + bb->content[index] = elem; + return TRUE; +} + +int +ncbytesappend(NCbytes* bb, char elem) +{ + if(bb == NULL) return ncbytesfail(); + if(bb->length >= bb->alloc) if(!ncbytessetalloc(bb,0)) return ncbytesfail(); + bb->content[bb->length] = elem; + bb->length++; + return TRUE; +} + +/* This assumes s is a null terminated string*/ +int +ncbytescat(NCbytes* bb, char* s) +{ + ncbytesappendn(bb,(void*)s,strlen(s)+1); /* include trailing null*/ + /* back up over the trailing null*/ + if(bb->length == 0) return ncbytesfail(); + bb->length--; + return 1; +} + +int +ncbytesappendn(NCbytes* bb, void* elem, unsigned int n) +{ + if(bb == NULL || elem == NULL) return ncbytesfail(); + if(n == 0) {n = strlen((char*)elem);} + while(!ncbytesavail(bb,n)) {if(!ncbytessetalloc(bb,0)) return ncbytesfail();} + memcpy((void*)&bb->content[bb->length],(void*)elem,n); + bb->length += n; + return TRUE; +} + +int +ncbytesprepend(NCbytes* bb, char elem) +{ + int i; /* do not make unsigned */ + if(bb == NULL) return ncbytesfail(); + if(bb->length >= bb->alloc) if(!ncbytessetalloc(bb,0)) return ncbytesfail(); + /* could we trust memcpy? instead */ + for(i=bb->alloc;i>=1;i--) {bb->content[i]=bb->content[i-1];} + bb->content[0] = elem; + bb->length++; + return TRUE; +} + +char* +ncbytesdup(NCbytes* bb) +{ + char* result = (char*)malloc(bb->length+1); + memcpy((void*)result,(const void*)bb->content,bb->length); + result[bb->length] = '\0'; /* just in case it is a string*/ + return result; +} + +char* +ncbytesextract(NCbytes* bb) +{ + char* result = bb->content; + bb->alloc = 0; + bb->length = 0; + bb->content = NULL; + return result; +} + +int +ncbytessetcontents(NCbytes* bb, char* contents, unsigned int alloc) +{ + if(bb == NULL) return ncbytesfail(); + ncbytesclear(bb); + if(!bb->nonextendible && bb->content != NULL) free(bb->content); + bb->content = contents; + bb->length = 0; + bb->alloc = alloc; + bb->nonextendible = 1; + return 1; +} + +/* Null terminate the byte string without extending its length */ +/* For debugging */ +int +ncbytesnull(NCbytes* bb) +{ + ncbytesappend(bb,'\0'); + bb->length--; + return 1; +} + diff --git a/extern/src_netcdf4/ncbytes.h b/extern/src_netcdf4/ncbytes.h new file mode 100644 index 0000000000000000000000000000000000000000..09700af92b647eaeb1f7003761caea95cf099e21 --- /dev/null +++ b/extern/src_netcdf4/ncbytes.h @@ -0,0 +1,58 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef NCBYTES_H +#define NCBYTES_H 1 + +typedef struct NCbytes { + int nonextendible; /* 1 => fail if an attempt is made to extend this buffer*/ + unsigned int alloc; + unsigned int length; + char* content; +} NCbytes; + +#if defined(_CPLUSPLUS_) || defined(__CPLUSPLUS__) || defined(__CPLUSPLUS) +#define EXTERNC extern "C" +#else +#define EXTERNC extern +#endif + +EXTERNC NCbytes* ncbytesnew(void); +EXTERNC void ncbytesfree(NCbytes*); +EXTERNC int ncbytessetalloc(NCbytes*,unsigned int); +EXTERNC int ncbytessetlength(NCbytes*,unsigned int); +EXTERNC int ncbytesfill(NCbytes*, char fill); + +/* Produce a duplicate of the contents*/ +EXTERNC char* ncbytesdup(NCbytes*); +/* Extract the contents and leave buffer empty */ +EXTERNC char* ncbytesextract(NCbytes*); + +/* Return the ith byte; -1 if no such index */ +EXTERNC int ncbytesget(NCbytes*,unsigned int); +/* Set the ith byte */ +EXTERNC int ncbytesset(NCbytes*,unsigned int,char); + +/* Append one byte */ +EXTERNC int ncbytesappend(NCbytes*,char); /* Add at Tail */ +/* Append n bytes */ +EXTERNC int ncbytesappendn(NCbytes*,void*,unsigned int); /* Add at Tail */ + +/* Null terminate the byte string without extending its length (for debugging) */ +EXTERNC int ncbytesnull(NCbytes*); + +/* Concatenate a null-terminated string to the end of the buffer */ +EXTERNC int ncbytescat(NCbytes*,char*); + +/* Set the contents of the buffer; mark the buffer as non-extendible */ +EXTERNC int ncbytessetcontents(NCbytes*, char*, unsigned int); + +/* Following are always "in-lined"*/ +#define ncbyteslength(bb) ((bb)?(bb)->length:0U) +#define ncbytesalloc(bb) ((bb)?(bb)->alloc:0U) +#define ncbytescontents(bb) ((bb && bb->content)?(bb)->content:(char*)"") +#define ncbytesextend(bb,len) ncbytessetalloc((bb),(len)+(bb->alloc)) +#define ncbytesclear(bb) ((bb)?(bb)->length=0:0U) +#define ncbytesavail(bb,n) ((bb)?((bb)->alloc - (bb)->length) >= (n):0U) + +#endif /*NCBYTES_H*/ diff --git a/extern/src_netcdf4/nccommon.h b/extern/src_netcdf4/nccommon.h new file mode 100644 index 0000000000000000000000000000000000000000..30ea32f939bbb52a88b80147818043b049700d26 --- /dev/null +++ b/extern/src_netcdf4/nccommon.h @@ -0,0 +1,333 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libnccommon/nccommon.h,v 1.40 2010/05/30 19:45:52 dmh Exp $ + *********************************************************************/ +#ifndef NCCOMMON_H +#define NCCOMMON_H 1 + +/* Mnemonics */ +#ifndef BOOL +#define BOOL int +#endif +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifndef nullfree +#define nullfree(m) {if((m)!=NULL) {free(m);} else {}} +#endif + + +#define FILLCONSTRAINT TRUE + + +/* Use an extended version of the netCDF-4 type system */ +#define NC_URL 50 +#define NC_SET 51 +/* Merge relevant translations of OC types */ +#define NC_Dataset 52 +#define NC_Sequence 53 +#define NC_Structure 54 +#define NC_Grid 55 +#define NC_Dimension 56 +#define NC_Primitive 57 + +#undef OCCOMPILEBYDEFAULT + +#define DEFAULTSTRINGLENGTH 64 +/* The sequence limit default is zero because + most servers do not implement projections + on sequences. +*/ +#define DEFAULTSEQLIMIT 0 + +/**************************************************/ +/* sigh, do the forwards */ +struct NCDAPCOMMON; +struct NCprojection; +struct NCselection; +struct Getvara; +struct NCcachenode; +struct NCcache; +struct NCslice; +struct NCsegment; +struct OClist; +/**************************************************/ +/* +Collect single bit flags that +affect the operation of the system. +*/ + +typedef unsigned int NCFLAGS; +# define SETFLAG(controls,flag) ((controls.flags) |= (flag)) +# define CLRFLAG(controls,flag) ((controls.flags) &= ~(flag)) +# define FLAGSET(controls,flag) (((controls.flags) & (flag)) != 0) + +/* Defined flags */ +#define NCF_NC3 (0x0001) /* DAP->netcdf-3 */ +#define NCF_NC4 (0x0002) /* DAP->netcdf-4 */ +#define NCF_NCDAP (0x0004) /* Do libnc-dap mimic */ +#define NCF_CACHE (0x0008) /* Cache enabled/disabled */ +#define NCF_PREFETCH (0x0010) /* Cache prefetch enabled/disabled */ +#define NCF_UPGRADE (0x0020) /* Do proper type upgrades */ +#define NCF_UNCONSTRAINABLE (0x0040) /* Not a constrainable URL */ +#define NCF_SHOWFETCH (0x0080) /* show fetch calls */ +#define NCF_ONDISK (0x0100) /* cause oc to store data on disk */ +#define NCF_WHOLEVAR (0x0200) /* retrieve only whole variables (as opposed to partial variable) + into cache */ + +/* Define all the default on flags */ +#define DFALT_ON_FLAGS (NCF_PREFETCH) + +typedef struct NCCONTROLS { + NCFLAGS flags; +} NCCONTROLS; + +struct NCTMODEL { + int translation; + char* model; + unsigned int flags; +}; + +/* Detail information about each cache item */ +typedef struct NCcachenode { + int wholevariable; /* does this node only have wholevariables? */ + int prefetch; /* is this the prefetch cache entry? */ + size_t xdrsize; + DCEconstraint* constraint; /* as used to create this node */ + NClist* vars; /* vars potentially covered by this cache node */ + struct CDFnode* datadds; + OCobject ocroot; + OCdata content; +} NCcachenode; + +/* All cache info */ +typedef struct NCcache { + size_t cachelimit; /* max total size for all cached entries */ + size_t cachesize; /* current size */ + size_t cachecount; /* max # nodes in cache */ + NCcachenode* prefetch; + NClist* nodes; /* cache nodes other than prefetch */ +} NCcache; + +/**************************************************/ +/* The DAP packet info from OC */ +typedef struct NCOC { + OCconnection conn; + char* rawurltext; /* as given to nc3d_open */ + char* urltext; /* as modified by nc3d_open */ + NC_URI* url; /* parse of rawuritext */ + OCobject ocdasroot; + DCEconstraint* dapconstraint; /* from url */ + int inmemory; /* store fetched data in memory? */ +} NCOC; + +typedef struct NCCDF { + struct CDFnode* ddsroot; /* constrained dds */ + struct CDFnode* fullddsroot; /* unconstrained dds */ + /* Collected sets of useful nodes (in ddsroot tree space) */ + NClist* varnodes; /* nodes which can represent netcdf variables */ + NClist* seqnodes; /* sequence nodes; */ + NClist* gridnodes; /* grid nodes */ + NClist* dimnodes; /* (base) dimension nodes */ + unsigned int defaultstringlength; + unsigned int defaultsequencelimit; /* global sequence limit;0=>no limit */ + struct NCcache* cache; + size_t fetchlimit; + size_t smallsizelimit; /* what constitutes a small object? */ + size_t totalestimatedsize; + const char* separator; /* constant; do not free */ + /* global string dimension */ + struct CDFnode* globalstringdim; + char* recorddimname; /* From DODS_EXTRA */ + struct CDFnode* recorddim; + /* libncdap4 only */ + NClist* usertypes; /* nodes which will represent netcdf types */ +} NCCDF; + +/* Define a structure holding common info for NCDAP{3,4} */ + +typedef struct NCDAPCOMMON { + NC* controller; /* Parent instance of NCDAPCOMMON */ + NCCDF cdf; + NCOC oc; + NCCONTROLS controls; /* Control flags and parameters */ +} NCDAPCOMMON; + +/**************************************************/ +/* Create our own node tree to mimic ocnode trees*/ + +/* Each root CDFnode contains info about the whole tree */ +typedef struct CDFtree { + OCobject ocroot; + OCdxd occlass; + NClist* nodes; /* all nodes in tree*/ + struct CDFnode* root; /* cross link */ + struct NCDAPCOMMON* owner; + /* Classification flags */ + int regridded; /* Was this tree passed thru regrid3? */ +} CDFtree; + +/* Track the kinds of dimensions */ +typedef int CDFdimflags; +#define CDFDIMNORMAL 0x0 +#define CDFDIMSEQ 0x1 +#define CDFDIMSTRING 0x2 +#define CDFDIMCLONE 0x4 +#define CDFDIMRECORD 0x20 + +#define DIMFLAG(d,flag) ((d)->dim.dimflags & (flag)) +#define DIMFLAGSET(d,flag) ((d)->dim.dimflags |= (flag)) +#define DIMFLAGCLR(d,flag) ((d)->dim.dimflags &= ~(flag)) + +typedef struct CDFdim { + CDFdimflags dimflags; + struct CDFnode* basedim; /* for duplicate dimensions*/ + struct CDFnode* array; /* parent array node */ + size_t declsize; /* from constrained DDS*/ + size_t declsize0; /* from unconstrained DDS*/ + int index1; /* dimension name index +1; 0=>no index */ +} CDFdim; + +typedef struct CDFarray { + NClist* dimsetall; /* inherited+originals+pseudo */ + NClist* dimsetplus; /* originals+pseudo */ + NClist* dimset0; /* original dims from the dds */ + struct CDFnode* stringdim; + /* Track sequence related information */ + struct CDFnode* seqdim; /* if this node is a sequence */ + /* note: unlike string dim; seqdim is also stored in dimensions vector */ + struct CDFnode* sequence; /* containing usable sequence, if any */ + struct CDFnode* basevar; /* for duplicate grid variables*/ +} CDFarray; + +typedef struct NCattribute { + char* name; + nc_type etype; /* dap type of the attribute */ + NClist* values; /* strings come from the oc values */ + int invisible; /* Do not materialize to the user */ +} NCattribute; + +/* Extend as additional DODS attribute values are defined */ +typedef struct NCDODS { + size_t maxstrlen; + char* dimname; +} NCDODS; + +typedef struct NCalignment { + unsigned long size; /* size of single instance of this type*/ + unsigned long alignment; /* alignment of this field */ + unsigned long offset; /* offset of this field in parent */ +} NCalignment; + +typedef struct NCtypesize { + BOOL aligned; /* have instance and field been defined? */ + NCalignment instance; /* Alignment, etc for instance data */ + NCalignment field; /* Alignment, etc WRT to parent */ +} NCtypesize; + +/* Closely mimics struct OCnode*/ +typedef struct CDFnode { + nc_type nctype; /* e.g. var, dimension */ + nc_type etype; /* e.g. NC_INT, NC_FLOAT if applicable,*/ + char* ocname; /* oc base name */ + char* ncbasename; /* generally cdflegalname(ocname) */ + char* ncfullname; /* complete path name from root to this node*/ + OCobject ocnode; /* oc mirror node*/ + struct CDFnode* group; /* null => in root group */ + struct CDFnode* container; /* e.g. struct or sequence, but not group */ + struct CDFnode* root; + CDFtree* tree; /* root level metadata;only defined if root*/ + CDFdim dim; /* nctype == dimension */ + CDFarray array; /* nctype == grid,var,etc. with dimensions */ + NClist* subnodes; /* if nctype == grid, sequence, etc. */ + NClist* attributes; /*NClist*/ + NCDODS dodsspecial; /* special attributes like maxStrlen */ + nc_type externaltype; /* the type as represented to nc_inq*/ + int ncid; /* relevant NC id for this object*/ + unsigned long maxstringlength; + unsigned long sequencelimit; /* 0=>unlimited */ + BOOL usesequence; /* If this sequence is usable */ + BOOL elided; /* 1 => node does not partipate in naming*/ + struct CDFnode* basenode; /* derived tree map to template tree */ + BOOL visible; /* 1 => node is present in derived tree; independent of elided flag */ + BOOL zerodim; /* 1 => node has a zero dimension */ + /* These two flags track the effects on grids of constraints */ + BOOL virtual; /* node added by regrid */ +#ifdef PROJECTED + BOOL projected; /* node referenced by projection */ +#endif + struct CDFnode* attachment; /* DDS<->DATADDS cross link*/ + struct CDFnode* template; /* temporary field for regridding */ + /* Fields for use by libncdap4 */ + NCtypesize typesize; + int typeid; /* when treating field as type */ + int basetypeid; /* when typeid is vlen */ + char* typename; + char* vlenname; /* for sequence types */ + int singleton; /* for singleton sequences */ + unsigned long estimatedsize; /* > 0 Only for var nodes */ +} CDFnode; + +/**************************************************/ +/* Shared procedures */ + +/* From ncdap3.c*/ +extern NCerror freeNCDAPCOMMON(struct NCDAPCOMMON*); +extern NCerror fetchtemplatemetadata3(NCDAPCOMMON*); + +/* From error.c*/ +extern NCerror ocerrtoncerr(OCerror); + +/* From: common34.c */ +extern NCerror fixgrid34(struct NCDAPCOMMON* drno, CDFnode* grid); +extern NCerror computecdfinfo34(struct NCDAPCOMMON*, NClist*); +extern char* cdfname34(char* basename); +extern NCerror augmentddstree34(struct NCDAPCOMMON*, NClist*); +extern NCerror computecdfdimnames34(struct NCDAPCOMMON*); +extern NCerror buildcdftree34(struct NCDAPCOMMON*, OCobject, OCdxd, CDFnode**); +extern CDFnode* makecdfnode34(struct NCDAPCOMMON*, char* nm, OCtype, + /*optional*/ OCobject ocnode, CDFnode* container); +extern void freecdfroot34(CDFnode*); + +extern NCerror findnodedds34(struct NCDAPCOMMON* drno, CDFnode* ddssrc); +extern NCerror makegetvar34(struct NCDAPCOMMON*, struct CDFnode*, void*, nc_type, struct Getvara**); +extern NCerror applyclientparams34(struct NCDAPCOMMON* drno); +extern NCerror attach34(CDFnode* xroot, CDFnode* ddstarget); +extern NCerror attachall34(CDFnode* xroot, CDFnode* ddsroot); +extern NCerror attachsubset34(CDFnode*, CDFnode*); +extern void unattach34(CDFnode*); +extern int nodematch34(CDFnode* node1, CDFnode* node2); +extern int simplenodematch34(CDFnode* node1, CDFnode* node2); +extern CDFnode* findxnode34(CDFnode* target, CDFnode* xroot); +extern int constrainable34(NC_URI*); +extern char* makeconstraintstring34(DCEconstraint*); +extern size_t estimatedataddssize34(CDFnode* datadds); +extern void canonicalprojection34(NClist*, NClist*); +extern NClist* getalldims34(NCDAPCOMMON* nccomm, int visibleonly); + +/* From cdf3.c */ +extern NCerror dimimprint3(NCDAPCOMMON*); +extern NCerror definedimsets3(struct NCDAPCOMMON*); + +/* From cache.c */ +extern int iscached(NCDAPCOMMON*, CDFnode* target, NCcachenode** cachenodep); +extern NCerror prefetchdata3(NCDAPCOMMON*); +extern NCerror buildcachenode34(NCDAPCOMMON*, + DCEconstraint* constraint, + NClist* varlist, + NCcachenode** cachep, + int isprefetch); +extern NCcachenode* createnccachenode(void); +extern void freenccachenode(NCDAPCOMMON*, NCcachenode* node); +extern NCcache* createnccache(void); +extern void freenccache(NCDAPCOMMON*, NCcache* cache); + +/* Add an extra function whose sole purpose is to allow + configure(.ac) to test for the presence of thiscode. +*/ +extern int nc__opendap(void); + +#endif /*NCCOMMON_H*/ diff --git a/extern/src_netcdf4/ncconfigure.h b/extern/src_netcdf4/ncconfigure.h new file mode 100644 index 0000000000000000000000000000000000000000..6a554d7387d1d5d7e67b88cc03dc24de9e4371c9 --- /dev/null +++ b/extern/src_netcdf4/ncconfigure.h @@ -0,0 +1,58 @@ +/* + * Copyright 2010 University Corporation for Atmospheric + * Research/Unidata. See COPYRIGHT file for more info. + * + * This header file is for the parallel I/O functions of netCDF. + * + */ +/* "$Id: netcdf_par.h,v 1.1 2010/06/01 15:46:49 ed Exp $" */ + +#ifndef NCCONFIGURE_H +#define NCCONFIGURE_H 1 + +/* +This is included in bottom +of config.h. It is where, +typically, alternatives to +missing functions should be +defined. +*/ + +#ifndef HAVE_STRDUP +extern char* strdup(const char*); +#endif + +/* handle null arguments */ +#ifndef nulldup +#ifdef HAVE_STRDUP +#define nulldup(s) ((s)==NULL?NULL:strdup(s)) +#else +char *nulldup(const char* s); +#endif +#endif + + +#ifndef nulldup +#define nulldup(s) ((s)==NULL?NULL:strdup(s)) +#endif +#ifndef nulllen +#define nulllen(s) ((s)==NULL?0:strlen(s)) +#endif +#ifndef nullfree +#define nullfree(s) {if((s)!=NULL) {free(s);} else {}} +#endif + +#ifndef HAVE_UCHAR +typedef unsigned char uchar; +#endif + +#ifndef HAVE_LONGLONG +typedef long long longlong; +typedef unsigned long long ulonglong; +#endif + +#ifndef HAVE_UINT +typedef unsigned int uint; +#endif + +#endif /* NCCONFIGURE_H */ diff --git a/extern/src_netcdf4/ncd3dispatch.c b/extern/src_netcdf4/ncd3dispatch.c new file mode 100644 index 0000000000000000000000000000000000000000..1d0d99492c50d0536b1790b4893fa46f8aec013f --- /dev/null +++ b/extern/src_netcdf4/ncd3dispatch.c @@ -0,0 +1,218 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/ncd3dispatch.c,v 1.7 2010/05/27 21:34:09 dmh Exp $ + *********************************************************************/ + +#include "config.h" +#include +#include + +#include "nc.h" +#include "ncdap3.h" +#include "ncdispatch.h" +#include "ncd3dispatch.h" + +static int +NCD3_create(const char *path, int cmode, + size_t initialsz, int basepe, size_t *chunksizehintp, + int use_parallel, void* mpidata, + NC_Dispatch*,NC** ncp); + +static int NCD3_redef(int ncid); +static int NCD3__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align); +static int NCD3_sync(int ncid); +static int NCD3_abort(int ncid); + +static int NCD3_put_vara(int ncid, int varid, + const size_t *start, const size_t *edges0, + const void *value0, + nc_type memtype); + +static int NCD3_get_vara(int ncid, int varid, + const size_t *start, const size_t *edges, + void *value, + nc_type memtype); + +static int NCD3_put_vars(int ncid, int varid, + const size_t *start, const size_t *edges, const ptrdiff_t* stride, + const void *value0, nc_type memtype); + +static int NCD3_get_vars(int ncid, int varid, + const size_t *start, const size_t *edges, const ptrdiff_t* stride, + void *value, nc_type memtype); + +NC_Dispatch NCD3_dispatch_base = { + +NC_DISPATCH_NC3 | NC_DISPATCH_NCD, + +/* Note: we are using the standard substrate struct NC creator */ +NULL, + +NCD3_create, +NCD3_open, + +NCD3_redef, +NCD3__enddef, +NCD3_sync, +NCD3_abort, +NCD3_close, +NULL, /*set_fill*/ +NULL, /*inq_base_pe*/ +NULL, /*set_base_pe*/ +NULL, /*inq_format*/ + +NULL, /*inq*/ +NULL, /*inq_type*/ + +NULL, /*def_dim*/ +NULL, /*inq_dimid*/ +NULL, /*inq_dim*/ +NULL, /*inq_unlimdim*/ +NULL, /*rename_dim*/ + +NULL, /*inq_att*/ +NULL, /*inq_attid*/ +NULL, /*inq_attname*/ +NULL, /*rename_att*/ +NULL, /*del_att*/ +NULL, /*get_att*/ +NULL, /*put_att*/ + +NULL, /*def_var*/ +NULL, /*inq_varid*/ +NULL, /*rename_var*/ +NCD3_get_vara, +NCD3_put_vara, +NCD3_get_vars, +NCD3_put_vars, +NCDEFAULT_get_varm, +NCDEFAULT_put_varm, + +NULL, /*inq_var_all*/ + +#ifdef USE_NETCDF4 +NULL, /*show_metadata*/ +NULL, /*inq_unlimdims*/ +NULL, /*var_par_access*/ +NULL, /*inq_ncid*/ +NULL, /*inq_grps*/ +NULL, /*inq_grpname*/ +NULL, /*inq_grpname_full*/ +NULL, /*inq_grp_parent*/ +NULL, /*inq_grp_full_ncid*/ +NULL, /*inq_varids*/ +NULL, /*inq_dimids*/ +NULL, /*inq_typeids*/ +NULL, /*inq_type_equal*/ +NULL, /*def_grp*/ +NULL, /*inq_user_type*/ +NULL, /*inq_typeid*/ + +NULL, /*def_compound*/ +NULL, /*insert_compound*/ +NULL, /*insert_array_compound*/ +NULL, /*inq_compound_field*/ +NULL, /*inq_compound_fieldindex*/ +NULL, /*def_vlen*/ +NULL, /*put_vlen_element*/ +NULL, /*get_vlen_element*/ +NULL, /*def_enum*/ +NULL, /*insert_enum*/ +NULL, /*inq_enum_member*/ +NULL, /*inq_enum_ident*/ +NULL, /*def_opaque*/ +NULL, /*def_var_deflate*/ +NULL, /*def_var_fletcher32*/ +NULL, /*def_var_chunking*/ +NULL, /*def_var_fill*/ +NULL, /*def_var_endian*/ +NULL, /*set_var_chunk_cache*/ +NULL, /*get_var_chunk_cache*/ + +#endif /*USE_NETCDF4*/ + +}; + +NC_Dispatch* NCD3_dispatch_table = NULL; /* moved here from ddispatch.c */ + +NC_Dispatch NCD3_dispatcher; /* overlay result */ + +int +NCD3_initialize(void) +{ + /* Create our dispatch table as the merge of NCD3 table and NCSUBSTRATE */ + /* watch the order because we want NCD3 to overwrite NCSUBSTRATE */ + NC_dispatch_overlay(&NCD3_dispatch_base, NCSUBSTRATE_dispatch_table, &NCD3_dispatcher); + NCD3_dispatch_table = &NCD3_dispatcher; + return NC_NOERR; +} + +static int +NCD3_redef(int ncid) +{ + return (NC_EPERM); +} + +static int +NCD3__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align) +{ + return (NC_EPERM); +} + +static int +NCD3_sync(int ncid) +{ + return (NC_EINVAL); +} + +static int +NCD3_abort(int ncid) +{ + return NCD3_close(ncid); +} + +static int +NCD3_create(const char *path, int cmode, + size_t initialsz, int basepe, size_t *chunksizehintp, + int use_parallel, void* mpidata, + NC_Dispatch* dispatch, NC** ncp) +{ + return NC_EPERM; +} + +static int +NCD3_put_vara(int ncid, int varid, + const size_t *start, const size_t *edges, + const void *value, + nc_type memtype) +{ + return NC_EPERM; +} + +static int +NCD3_get_vara(int ncid, int varid, + const size_t *start, const size_t *edges, + void *value, + nc_type memtype) +{ + int stat = nc3d_getvarx(ncid, varid, start, edges, nc_ptrdiffvector1, value,memtype); + return stat; +} + +static int +NCD3_put_vars(int ncid, int varid, + const size_t *start, const size_t *edges, const ptrdiff_t* stride, + const void *value0, nc_type memtype) +{ + return NC_EPERM; +} + +static int +NCD3_get_vars(int ncid, int varid, + const size_t *start, const size_t *edges, const ptrdiff_t* stride, + void *value, nc_type memtype) +{ + int stat = nc3d_getvarx(ncid, varid, start, edges, stride, value, memtype); + return stat; +} diff --git a/extern/src_netcdf4/ncd3dispatch.h b/extern/src_netcdf4/ncd3dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..d1d6765f0f6a63df565e79a8818ad05cb827f71c --- /dev/null +++ b/extern/src_netcdf4/ncd3dispatch.h @@ -0,0 +1,67 @@ +/* + * Copyright 1993-1996 University Corporation for Atmospheric Research/Unidata + * + * Portions of this software were developed by the Unidata Program at the + * University Corporation for Atmospheric Research. + * + * Access and use of this software shall impose the following obligations + * and understandings on the user. The user is granted the right, without + * any fee or cost, to use, copy, modify, alter, enhance and distribute + * this software, and any derivative works thereof, and its supporting + * documentation for any purpose whatsoever, provided that this entire + * notice appears in all copies of the software, derivative works and + * supporting documentation. Further, UCAR requests that the user credit + * UCAR/Unidata in any publications that result from the use of this + * software or in any product that includes this software. The names UCAR + * and/or Unidata, however, may not be used in any advertising or publicity + * to endorse or promote any products or commercial entity unless specific + * written permission is obtained from UCAR/Unidata. The user also + * understands that UCAR/Unidata is not obligated to provide the user with + * any support, consulting, training or assistance of any kind with regard + * to the use, operation and performance of this software nor to provide + * the user with any updates, revisions, new versions or "bug fixes." + * + * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "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 UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* "$Id: ncd3dispatch.h,v 1.3 2010/05/27 21:34:09 dmh Exp $" */ + +#ifndef _NCD3DISPATCH_H +#define _NCD3DISPATCH_H + +#include /* size_t, ptrdiff_t */ +#include "netcdf.h" +#include "ncdispatch.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +EXTERNL int +NCD3_new_nc(struct NC**); + +/* WARNING: this signature differs from external nc_open API*/ +EXTERNL int +NCD3_open(const char *path, int mode, + int basepe, size_t *chunksizehintp, + int use_parallel, void* mpidata, + struct NC_Dispatch* dispatch, NC** ncp); + +EXTERNL int +NCD3_close(int ncid); + +/* End _var */ + +extern int NCD3_initialize(void); + +#if defined(__cplusplus) +} +#endif + +#endif /*_NCD3DISPATCH_H*/ diff --git a/extern/src_netcdf4/ncdap3.c b/extern/src_netcdf4/ncdap3.c new file mode 100644 index 0000000000000000000000000000000000000000..597aa14ba9de799d6a7b45cda51b730d77a1c6ca --- /dev/null +++ b/extern/src_netcdf4/ncdap3.c @@ -0,0 +1,692 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/ncdap3.c,v 1.94 2010/05/28 01:05:34 dmh Exp $ + *********************************************************************/ + +#include "ncdap3.h" + +#ifdef HAVE_GETRLIMIT +# ifdef HAVE_SYS_RESOURCE_H +# include +# endif +# ifdef HAVE_SYS_RESOURCE_H +# include +# endif +#endif + +#include "nc3dispatch.h" +#include "ncd3dispatch.h" +#include "dapalign.h" +#include "dapdump.h" + +static NCerror buildncstructures3(NCDAPCOMMON*); +static NCerror builddims(NCDAPCOMMON*); +static NCerror buildvars(NCDAPCOMMON*); +static NCerror buildglobalattrs3(NCDAPCOMMON*,CDFnode* root); +static NCerror buildattribute3a(NCDAPCOMMON*, NCattribute*, nc_type, int); + + +static char* getdefinename(CDFnode* node); + +extern CDFnode* v4node; +int nc3dinitialized = 0; + +/**************************************************/ +/* Add an extra function whose sole purpose is to allow + configure(.ac) to test for the presence of thiscode. +*/ +int nc__opendap(void) {return 0;} + +/**************************************************/ +/* Do local initialization */ + +int +nc3dinitialize(void) +{ + compute_nccalignments(); + nc3dinitialized = 1; + return NC_NOERR; +} + +/**************************************************/ + +/* See ncd3dispatch.c for other version */ +int +NCD3_open(const char * path, int mode, + int basepe, size_t *chunksizehintp, + int useparallel, void* mpidata, + NC_Dispatch* dispatch, NC** ncpp) +{ + NCerror ncstat = NC_NOERR; + OCerror ocstat = OC_NOERR; + NC* drno = NULL; + NCDAPCOMMON* dapcomm = NULL; + const char* value; + /* We will use a fake file descriptor as our internal in-memory filename */ + char tmpname[32]; + + if(!nc3dinitialized) nc3dinitialize(); + + if(path == NULL) + return NC_EDAPURL; + if(dispatch == NULL) PANIC("NC3D_open: no dispatch table"); + + /* Setup our NC and NCDAPCOMMON state*/ + drno = (NC*)calloc(1,sizeof(NC)); + if(drno == NULL) {ncstat = NC_ENOMEM; goto done;} + + /* compute an ncid */ + ncstat = add_to_NCList(drno); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + + dapcomm = (NCDAPCOMMON*)calloc(1,sizeof(NCDAPCOMMON)); + if(dapcomm == NULL) {ncstat = NC_ENOMEM; goto done;} + + drno->dispatch = dispatch; + drno->dispatchdata = dapcomm; + drno->int_ncid = nc__pseudofd(); /* create a unique id */ + dapcomm->controller = (NC*)drno; + + dapcomm->cdf.separator = "."; + dapcomm->cdf.smallsizelimit = DFALTSMALLLIMIT; + dapcomm->cdf.cache = createnccache(); + +#ifdef HAVE_GETRLIMIT + { struct rlimit rl; + if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) { + dapcomm->cdf.cache->cachecount = (size_t)(rl.rlim_cur / 2); + } + } +#endif + +#ifdef OCCOMPILEBYDEFAULT + /* set the compile flag by default */ + dapcomm->oc.rawurltext = (char*)emalloc(strlen(path)+strlen("[compile]")+1); + strcpy(dapcomm->oc.rawurltext,"[compile]"); + strcat(dapcomm->oc.rawurltext, path); +#else + dapcomm->oc.rawurltext = strdup(path); +#endif + + nc_uriparse(dapcomm->oc.rawurltext,&dapcomm->oc.url); + + /* parse the client parameters */ + nc_uridecodeparams(dapcomm->oc.url); + + if(!constrainable34(dapcomm->oc.url)) + SETFLAG(dapcomm->controls,NCF_UNCONSTRAINABLE); + + /* Use libsrc code for storing metadata */ + + snprintf(tmpname,sizeof(tmpname),"%d",drno->int_ncid); + /* Now, use the file to create the netcdf file */ + if(sizeof(size_t) == sizeof(unsigned int)) + ncstat = nc_create(tmpname,NC_DISKLESS,&drno->substrate); + else + ncstat = nc_create(tmpname,NC_DISKLESS|NC_64BIT_OFFSET,&drno->substrate); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + + /* Avoid fill */ + nc_set_fill(drno->substrate,NC_NOFILL,NULL); + + dapcomm->oc.dapconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT); + dapcomm->oc.dapconstraint->projections = nclistnew(); + dapcomm->oc.dapconstraint->selections = nclistnew(); + + /* Parse constraints to make sure they are syntactically correct */ + ncstat = parsedapconstraints(dapcomm,dapcomm->oc.url->constraint,dapcomm->oc.dapconstraint); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + + /* Complain if we are unconstrainable but have constraints */ + if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { + if(dapcomm->oc.url->constraint != NULL + && strlen(dapcomm->oc.url->constraint) > 0) { + nclog(NCLOGWARN,"Attempt to constrain an unconstrainable data source: %s", + dapcomm->oc.url->constraint); + } + } + + /* Construct a url for oc minus any parameters */ + dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL, + (NC_URIALL ^ NC_URICONSTRAINTS)); + + /* Pass to OC */ + ocstat = oc_open(dapcomm->oc.urltext,&dapcomm->oc.conn); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} + + nullfree(dapcomm->oc.urltext); /* clean up */ + dapcomm->oc.urltext = NULL; + + /* process control client parameters */ + applyclientparamcontrols3(dapcomm); + + /* Turn on logging; only do this after oc_open*/ + if((value = paramvalue34(dapcomm,"log")) != NULL) { + ncloginit(); + ncsetlogging(1); + nclogopen(value); + oc_loginit(); + oc_setlogging(1); + oc_logopen(value); + } + + /* fetch and build the (almost) unconstrained DDS for use as + template */ + ncstat = fetchtemplatemetadata3(dapcomm); + if(ncstat != NC_NOERR) goto done; + + /* fetch and build the constrained DDS */ + ncstat = fetchconstrainedmetadata3(dapcomm); + if(ncstat != NC_NOERR) goto done; + +#ifdef DEBUG2 +fprintf(stderr,"constrained dds: %s\n",dumptree(dapcomm->cdf.ddsroot)); +#endif + + + /* The following actions are (mostly) WRT to the constrained tree */ + + /* Accumulate useful nodes sets */ + ncstat = computecdfnodesets3(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* Fix grids */ + ncstat = fixgrids3(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* Locate and mark usable sequences */ + ncstat = sequencecheck3(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* suppress variables not in usable sequences */ + ncstat = suppressunusablevars3(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* apply client parameters */ + ncstat = applyclientparams34(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* Add (as needed) string dimensions*/ + ncstat = addstringdims(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + if(nclistlength(dapcomm->cdf.seqnodes) > 0) { + /* Build the sequence related dimensions */ + ncstat = defseqdims(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + } + + /* Define the dimsetplus and dimsetall lists */ + ncstat = definedimsets3(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* Re-compute the dimension names*/ + ncstat = computecdfdimnames34(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* Deal with zero size dimensions */ + ncstat = fixzerodims3(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* Attempt to use the DODS_EXTRA info to turn + one of the dimensions into unlimited. + Assume computecdfdimnames34 has already been called. + */ + ncstat = defrecorddim3(dapcomm); + if(ncstat) {THROWCHK(ncstat); goto done;} + if(dapcomm->cdf.recorddimname != NULL + && nclistlength(dapcomm->cdf.seqnodes) > 0) { + /*nclog(NCLOGWARN,"unlimited dimension specified, but sequences exist in DDS");*/ + PANIC("unlimited dimension specified, but sequences exist in DDS"); + } + + /* Re-compute the var names*/ + ncstat = computecdfvarnames3(dapcomm,dapcomm->cdf.ddsroot,dapcomm->cdf.varnodes); + if(ncstat) {THROWCHK(ncstat); goto done;} + + /* Transfer data from the unconstrained DDS data to the unconstrained DDS */ + ncstat = dimimprint3(dapcomm); + if(ncstat) goto done; + + /* Process the constraints to map to the constrained CDF tree */ + /* (must follow fixgrids3 */ + ncstat = mapconstraints3(dapcomm->oc.dapconstraint,dapcomm->cdf.ddsroot); + if(ncstat != NC_NOERR) goto done; + + /* Canonicalize the constraint */ + ncstat = fixprojections(dapcomm->oc.dapconstraint->projections); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + + /* Fill in segment information */ + ncstat = qualifyconstraints3(dapcomm->oc.dapconstraint); + if(ncstat != NC_NOERR) goto done; + + /* using the modified constraint, rebuild the constraint string */ + if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { + /* ignore all constraints */ + dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,0); + } else { + char* constraintstring = buildconstraintstring3(dapcomm->oc.dapconstraint); + nc_urisetconstraints(dapcomm->oc.url,constraintstring); + nullfree(constraintstring); + dapcomm->oc.urltext = nc_uribuild(dapcomm->oc.url,NULL,NULL,NC_URICONSTRAINTS); + } + +#ifdef DEBUG +fprintf(stderr,"ncdap3: final constraint: %s\n",dapcomm->oc.url->constraint); +#endif + + /* Estimate the variable sizes */ + estimatevarsizes3(dapcomm); + + /* Build the meta data */ + ncstat = buildncstructures3(dapcomm); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + + /* Do any necessary data prefetch */ + if(FLAGSET(dapcomm->controls,NCF_PREFETCH)) { + ncstat = prefetchdata3(dapcomm); + if(ncstat != NC_NOERR) { + del_from_NCList((NC*)drno); /* undefine here */ + {THROWCHK(ncstat); goto done;} + } + } + +#ifdef BUG + /* The libsrc code (NC_begins) assumes that + a created files is new and hence must have an + unlimited dimension of 0 initially, which will + wipe out the effect of the NC_set_numrecs in builddims. + There is no easy workaround, so we suppress the call + to nc_enddef + */ + ncstat = nc_enddef(drno->substrate); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} +#endif + + if(ncpp) *ncpp = (NC*)drno; + + return ncstat; + +done: + if(drno != NULL) NCD3_close(drno->ext_ncid); + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); + return THROW(ncstat); +} + +int +NCD3_close(int ncid) +{ + NC* drno; + NCDAPCOMMON* dapcomm; + int ncstatus = NC_NOERR; + + ncstatus = NC_check_id(ncid, (NC**)&drno); + if(ncstatus != NC_NOERR) return THROW(ncstatus); + + dapcomm = (NCDAPCOMMON*)drno->dispatchdata; + ncstatus = nc_abort(drno->substrate); + + /* remove ourselves from NClist */ + del_from_NCList(drno); + /* clean NC* */ + freeNCDAPCOMMON(dapcomm); + if(drno->path != NULL) free(drno->path); + free(drno); + return THROW(ncstatus); +} + +/**************************************************/ +static NCerror +buildncstructures3(NCDAPCOMMON* dapcomm) +{ + NCerror ncstat = NC_NOERR; + CDFnode* dds = dapcomm->cdf.ddsroot; + NC* ncsub; + NC_check_id(dapcomm->controller->substrate,&ncsub); + + ncstat = buildglobalattrs3(dapcomm,dds); + if(ncstat != NC_NOERR) goto done; + + ncstat = builddims(dapcomm); + if(ncstat != NC_NOERR) goto done; + + ncstat = buildvars(dapcomm); + if(ncstat != NC_NOERR) goto done; + +done: + return THROW(ncstat); +} + +static NCerror +builddims(NCDAPCOMMON* dapcomm) +{ + int i; + NCerror ncstat = NC_NOERR; + int dimid; + NClist* dimset = NULL; + NC* drno = dapcomm->controller; + NC* ncsub; + char* definename; + + /* collect all dimensions from variables */ + dimset = dapcomm->cdf.dimnodes; + + /* Sort by fullname just for the fun of it */ + for(;;) { + int last = nclistlength(dimset) - 1; + int swap = 0; + for(i=0;incfullname,dim2->ncfullname) > 0) { + nclistset(dimset,i,(ncelem)dim2); + nclistset(dimset,i+1,(ncelem)dim1); + swap = 1; + break; + } + } + if(!swap) break; + } + + /* Define unlimited only if needed */ + if(dapcomm->cdf.recorddim != NULL) { + CDFnode* unlimited = dapcomm->cdf.recorddim; + definename = getdefinename(unlimited); + ncstat = nc_def_dim(drno->substrate, + definename, + NC_UNLIMITED, + &unlimited->ncid); + nullfree(definename); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + + /* get the id for the substrate */ + ncstat = NC_check_id(drno->substrate,&ncsub); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + + /* Set the effective size of UNLIMITED; + note that this cannot easily be done thru the normal API.*/ + NC_set_numrecs(ncsub,unlimited->dim.declsize); + } + + for(i=0;idim.basedim != NULL) continue; /* handle below */ + if(DIMFLAG(dim,CDFDIMRECORD)) continue; /* defined above */ +#ifdef DEBUG1 +fprintf(stderr,"define: dim: %s=%ld\n",dim->ncfullname,(long)dim->dim.declsize); +#endif + definename = getdefinename(dim); + ncstat = nc_def_dim(drno->substrate,definename,dim->dim.declsize,&dimid); + if(ncstat != NC_NOERR) { + THROWCHK(ncstat); goto done; + } + nullfree(definename); + dim->ncid = dimid; + } + + /* Make all duplicate dims have same dimid as basedim*/ + /* (see computecdfdimnames)*/ + for(i=0;idim.basedim != NULL) { + dim->ncid = dim->dim.basedim->ncid; + } + } +done: + nclistfree(dimset); + return THROW(ncstat); +} + +/* Simultaneously build any associated attributes*/ +/* and any necessary pseudo-dimensions for string types*/ +static NCerror +buildvars(NCDAPCOMMON* dapcomm) +{ + int i,j; + NCerror ncstat = NC_NOERR; + int varid; + NClist* varnodes = dapcomm->cdf.varnodes; + NC* drno = dapcomm->controller; + char* definename; + + ASSERT((varnodes != NULL)); + for(i=0;ivisible) continue; + if(var->array.basevar != NULL) continue; + +#ifdef DEBUG1 +fprintf(stderr,"buildvars.candidate=|%s|\n",var->ncfullname); +#endif + + vardims = var->array.dimsetall; + ncrank = nclistlength(vardims); + if(ncrank > 0) { + for(j=0;jncid; + } + } + + + + definename = getdefinename(var); + +#ifdef DEBUG1 +fprintf(stderr,"define: var: %s/%s", + definename,var->ocname); +if(ncrank > 0) { +int k; +for(k=0;kdim.declsize); + } + } +fprintf(stderr,"\n"); +#endif + ncstat = nc_def_var(drno->substrate, + definename, + var->externaltype, + ncrank, + (ncrank==0?NULL:dimids), + &varid); + nullfree(definename); + if(ncstat != NC_NOERR) { + THROWCHK(ncstat); + goto done; + } + var->ncid = varid; + if(var->attributes != NULL) { + for(j=0;jattributes);j++) { + NCattribute* att = (NCattribute*)nclistget(var->attributes,j); + ncstat = buildattribute3a(dapcomm,att,var->etype,varid); + if(ncstat != NC_NOERR) goto done; + } + } + /* Tag the variable with its DAP path */ + if(paramcheck34(dapcomm,"show","projection")) + showprojection3(dapcomm,var); + } +done: + return THROW(ncstat); +} + +static NCerror +buildglobalattrs3(NCDAPCOMMON* dapcomm, CDFnode* root) +{ + int i; + NCerror ncstat = NC_NOERR; + const char* txt; + char *nltxt, *p; + NCbytes* buf = NULL; + NClist* cdfnodes; + NC* drno = dapcomm->controller; + + if(root->attributes != NULL) { + for(i=0;iattributes);i++) { + NCattribute* att = (NCattribute*)nclistget(root->attributes,i); + ncstat = buildattribute3a(dapcomm,att,NC_NAT,NC_GLOBAL); + if(ncstat != NC_NOERR) goto done; + } + } + + /* Add global attribute identifying the sequence dimensions */ + if(paramcheck34(dapcomm,"show","seqdims")) { + buf = ncbytesnew(); + cdfnodes = dapcomm->cdf.ddsroot->tree->nodes; + for(i=0;inctype != NC_Dimension) continue; + if(DIMFLAG(dim,CDFDIMSEQ)) { + char* cname = cdflegalname3(dim->ocname); + if(ncbyteslength(buf) > 0) ncbytescat(buf,", "); + ncbytescat(buf,cname); + nullfree(cname); + } + } + if(ncbyteslength(buf) > 0) { + ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_sequence_dimensions", + ncbyteslength(buf),ncbytescontents(buf)); + } + } + + /* Define some additional system global attributes + depending on show= clientparams*/ + /* Ignore failures*/ + + if(paramcheck34(dapcomm,"show","translate")) { + /* Add a global attribute to show the translation */ + ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_translate", + strlen("netcdf-3"),"netcdf-3"); + } + if(paramcheck34(dapcomm,"show","url")) { + if(dapcomm->oc.rawurltext != NULL) + ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_url", + strlen(dapcomm->oc.rawurltext),dapcomm->oc.rawurltext); + } + if(paramcheck34(dapcomm,"show","dds")) { + txt = NULL; + if(dapcomm->cdf.ddsroot != NULL) + txt = oc_inq_text(dapcomm->oc.conn,dapcomm->cdf.ddsroot->ocnode); + if(txt != NULL) { + /* replace newlines with spaces*/ + nltxt = nulldup(txt); + for(p=nltxt;*p;p++) {if(*p == '\n' || *p == '\r' || *p == '\t') {*p = ' ';}}; + ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_dds",strlen(nltxt),nltxt); + nullfree(nltxt); + } + } + if(paramcheck34(dapcomm,"show","das")) { + txt = NULL; + if(dapcomm->oc.ocdasroot != OCNULL) + txt = oc_inq_text(dapcomm->oc.conn,dapcomm->oc.ocdasroot); + if(txt != NULL) { + nltxt = nulldup(txt); + for(p=nltxt;*p;p++) {if(*p == '\n' || *p == '\r' || *p == '\t') {*p = ' ';}}; + ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_das",strlen(nltxt),nltxt); + nullfree(nltxt); + } + } + +done: + ncbytesfree(buf); + return THROW(ncstat); +} + +static NCerror +buildattribute3a(NCDAPCOMMON* dapcomm, NCattribute* att, nc_type vartype, int varid) +{ + int i; + NCerror ncstat = NC_NOERR; + unsigned int nvalues = nclistlength(att->values); + NC* drno = dapcomm->controller; + + /* If the type of the attribute is string, then we need*/ + /* to convert to a single character string by concatenation. + modified: 10/23/09 to insert newlines. + modified: 10/28/09 to interpret escapes + */ + if(att->etype == NC_STRING || att->etype == NC_URL) { + char* newstring; + size_t newlen = 0; + for(i=0;ivalues,i); + newlen += (1+strlen(s)); + } + newstring = (char*)malloc(newlen); + MEMCHECK(newstring,NC_ENOMEM); + newstring[0] = '\0'; + for(i=0;ivalues,i); + if(i > 0) strcat(newstring,"\n"); + strcat(newstring,s); + } + dapexpandescapes(newstring); + if(newstring[0]=='\0') + ncstat = nc_put_att_text(drno->substrate,varid,att->name,1,newstring); + else + ncstat = nc_put_att_text(drno->substrate,varid,att->name,strlen(newstring),newstring); + free(newstring); + } else { + nc_type atype; + unsigned int typesize; + void* mem; + /* It turns out that some servers upgrade the type + of _FillValue in order to correctly preserve the + original value. However, since the type of the + underlying variable is not changes, we get a type + mismatch. So, make sure the type of the fillvalue + is the same as that of the controlling variable. + */ + if(varid != NC_GLOBAL && strcmp(att->name,"_FillValue")==0) + atype = nctypeconvert(dapcomm,vartype); + else + atype = nctypeconvert(dapcomm,att->etype); + typesize = nctypesizeof(atype); + mem = malloc(typesize * nvalues); + ncstat = dapcvtattrval3(atype,mem,att->values); + ncstat = nc_put_att(drno->substrate,varid,att->name,atype,nvalues,mem); + nullfree(mem); + } + return THROW(ncstat); +} + +static char* +getdefinename(CDFnode* node) +{ + char* spath = NULL; + NClist* path = NULL; + + switch (node->nctype) { + case NC_Primitive: + /* The define name is same as the fullname with elided nodes */ + path = nclistnew(); + collectnodepath3(node,path,!WITHDATASET); + spath = makepathstring3(path,".",PATHNC|PATHELIDE); + nclistfree(path); + break; + + case NC_Dimension: + /* Return just the node's ncname */ + spath = nulldup(node->ncbasename); + break; + + default: + PANIC("unexpected nctype"); + } + return spath; +} + +int +NCDAP_ping(const char* url) +{ + OCerror ocstat = OC_NOERR; + ocstat = oc_ping(url); + return ocerrtoncerr(ocstat); +} diff --git a/extern/src_netcdf4/ncdap3.h b/extern/src_netcdf4/ncdap3.h new file mode 100644 index 0000000000000000000000000000000000000000..668df4d6c54bd5bc196630e96908c16417118a20 --- /dev/null +++ b/extern/src_netcdf4/ncdap3.h @@ -0,0 +1,149 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/ncdap3.h,v 1.40 2010/05/30 19:45:52 dmh Exp $ + *********************************************************************/ +#ifndef NCDAP3_H +#define NCDAP3_H 1 + +#include "config.h" +#include +#include +#include +#include +#include +#include + +#include "ncbytes.h" +#include "nclist.h" +#include "nchashmap.h" +#include "nclog.h" +#include "nc_uri.h" +#include "fbits.h" +#include "dceconstraints.h" + +#include "oc.h" + +#include "nc.h" +#include "netcdf.h" +#include "ncdispatch.h" + /* netcdf overrides*/ +#include "dapnc.h" + +#include "dapdebug.h" +#include "daputil.h" + +/**************************************************/ +/* sigh, do the forwards */ +struct NCprojection; +struct NCselection; +struct Getvara; +struct NCcachenode; +struct NCcache; +struct NCslice; +struct NCsegment; + +/**************************************************/ + +#include "nccommon.h" +#include "getvara.h" +#include "constraints3.h" + +/**************************************************/ + +#ifndef USE_NETCDF4 +#define NC_UBYTE 7 /* unsigned 1 byte int */ +#define NC_USHORT 8 /* unsigned 2-byte int */ +#define NC_UINT 9 /* unsigned 4-byte int */ +#define NC_INT64 10 /* signed 8-byte int */ +#define NC_UINT64 11 /* unsigned 8-byte int */ +#define NC_STRING 12 /* string */ + +#define NC_MAX_BYTE 127 +#define NC_MIN_BYTE (-NC_MAX_BYTE-1) +#define NC_MAX_CHAR 255 +#define NC_MAX_SHORT 32767 +#define NC_MIN_SHORT (-NC_MAX_SHORT - 1) +#define NC_MAX_INT 2147483647 +#define NC_MIN_INT (-NC_MAX_INT - 1) +#define NC_MAX_FLOAT 3.402823466e+38f +#define NC_MIN_FLOAT (-NC_MAX_FLOAT) +#define NC_MAX_DOUBLE 1.7976931348623157e+308 +#define NC_MIN_DOUBLE (-NC_MAX_DOUBLE) +#define NC_MAX_UBYTE NC_MAX_CHAR +#define NC_MAX_USHORT 65535U +#define NC_MAX_UINT 4294967295U +#define NC_MAX_INT64 (9223372036854775807LL) +#define NC_MIN_INT64 (-9223372036854775807LL-1) +#define NC_MAX_UINT64 (18446744073709551615ULL) +#define X_INT64_MAX (9223372036854775807LL) +#define X_INT64_MIN (-X_INT64_MAX - 1) +#define X_UINT64_MAX (18446744073709551615ULL) +#endif /*USE_NETCDF4*/ + + +/**************************************************/ + +extern struct NCTMODEL nctmodels[]; + +/**************************************************/ +/* Import some internal procedures from libsrc*/ + +/* Internal, but non-static procedures */ +extern NCerror computecdfvarnames3(NCDAPCOMMON*,CDFnode*,NClist*); +extern NCerror computecdfnodesets3(NCDAPCOMMON* drno); +extern NCerror computevarnodes3(NCDAPCOMMON*, NClist*, NClist*); +extern NCerror collectvardefdims(NCDAPCOMMON* drno, CDFnode* var, NClist* dimset); +extern NCerror fixgrids3(NCDAPCOMMON* drno); +extern NCerror dapmerge3(NCDAPCOMMON* drno, CDFnode* node, OCobject dasroot); +extern NCerror sequencecheck3(NCDAPCOMMON* drno); +extern NCerror computecdfdimnames3(NCDAPCOMMON*); +extern NCerror attachdatadds3(struct NCDAPCOMMON*); +extern NCerror detachdatadds3(struct NCDAPCOMMON*); +extern void dapdispatch3init(void); + +/* +extern void dereference3(NCconstraint* constraint); +extern NCerror rereference3(NCconstraint*, NClist*); +*/ + +extern NCerror buildvaraprojection3(struct Getvara*, + const size_t* startp, const size_t* countp, const ptrdiff_t* stridep, + struct DCEprojection** projectionlist); + +extern NCerror nc3d_getvarx(int ncid, int varid, + const size_t *startp, + const size_t *countp, + const ptrdiff_t *stridep, + void *data, + nc_type dsttype0); + +/**************************************************/ + +/* From: ncdap3.c*/ +extern NCerror nc3d_open(const char* path, int mode, int* ncidp); +extern int nc3d_close(int ncid); +extern int nc3dinitialize(void); +extern NCerror regrid3(CDFnode* ddsroot, CDFnode* template, NClist*); +extern void setvisible(CDFnode* root, int visible); +extern NCerror mapnodes3(CDFnode* dstroot, CDFnode* srcroot); +extern void unmap3(CDFnode* root); + +/* From: ncdap3a.c*/ +extern NCerror fetchtemplatemetadata3(NCDAPCOMMON* nccomm); +extern NCerror fetchconstrainedmetadata3(NCDAPCOMMON* nccomm); +extern void applyclientparamcontrols3(NCDAPCOMMON*); +extern NCerror suppressunusablevars3(NCDAPCOMMON*); +extern NCerror addstringdims(NCDAPCOMMON* drno); +extern NCerror defseqdims(NCDAPCOMMON* drno); +extern NCerror fixzerodims3(NCDAPCOMMON*); +extern void estimatevarsizes3(NCDAPCOMMON*); +extern NCerror defrecorddim3(NCDAPCOMMON*); +extern NCerror showprojection3(NCDAPCOMMON*, CDFnode* var); + + +/* From: dapcvt.c*/ +extern NCerror dapconvert3(nc_type, nc_type, char*, char*, size_t); +extern int dapcvtattrval3(nc_type, void*, NClist*); + +#endif /*NCDAP3_H*/ diff --git a/extern/src_netcdf4/ncdap3a.c b/extern/src_netcdf4/ncdap3a.c new file mode 100644 index 0000000000000000000000000000000000000000..f30d7a7c80a67996a14e84aa2e9b887cb5efc097 --- /dev/null +++ b/extern/src_netcdf4/ncdap3a.c @@ -0,0 +1,800 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + *********************************************************************/ + +#include "ncdap3.h" +#include "nc3dispatch.h" +#include "ncd3dispatch.h" +#include "dapalign.h" +#include "dapdump.h" +#include "oc.h" + +#define getncid(drno) (((NC*)drno)->ext_ncid) + +/*Forward*/ +static NCerror getseqdimsize(NCDAPCOMMON*, CDFnode* seq, size_t* sizep); +static int fieldindex(CDFnode* parent, CDFnode* child); +static NCerror countsequence(NCDAPCOMMON*, CDFnode* node, size_t*); +static NCerror makeseqdim(NCDAPCOMMON*, CDFnode* node, size_t, CDFnode**); +static NCerror computeseqcountconstraints3(NCDAPCOMMON*,CDFnode*,NCbytes*); +static void computeseqcountconstraints3r(NCDAPCOMMON*, CDFnode*, CDFnode**); + +void +freegetvara(Getvara* vara) +{ + if(vara == NULL) return; + dcefree((DCEnode*)vara->varaprojection); + nullfree(vara); +} + +NCerror +freeNCDAPCOMMON(NCDAPCOMMON* dapcomm) +{ + /* abort the metadata file */ + (void)nc_abort(getncid(dapcomm)); + freenccache(dapcomm,dapcomm->cdf.cache); + nclistfree(dapcomm->cdf.varnodes); + nclistfree(dapcomm->cdf.seqnodes); + nclistfree(dapcomm->cdf.gridnodes); + nclistfree(dapcomm->cdf.usertypes); + nullfree(dapcomm->cdf.recorddimname); + + /* free the trees */ + freecdfroot34(dapcomm->cdf.ddsroot); + dapcomm->cdf.ddsroot = NULL; + freecdfroot34(dapcomm->cdf.fullddsroot); + dapcomm->cdf.fullddsroot = NULL; + if(dapcomm->oc.ocdasroot != NULL) + oc_root_free(dapcomm->oc.conn,dapcomm->oc.ocdasroot); + dapcomm->oc.ocdasroot = NULL; + oc_close(dapcomm->oc.conn); /* also reclaims remaining OC trees */ + nc_urifree(dapcomm->oc.url); + nullfree(dapcomm->oc.urltext); + nullfree(dapcomm->oc.rawurltext); + + dcefree((DCEnode*)dapcomm->oc.dapconstraint); + dapcomm->oc.dapconstraint = NULL; + + free(dapcomm); + + return NC_NOERR; +} + +NCerror +addstringdims(NCDAPCOMMON* dapcomm) +{ + /* for all variables of string type, we will need another dimension + to represent the string; Accumulate the needed sizes and create + the dimensions with a specific name: either as specified + in DODS{...} attribute set or defaulting to the variable name. + All such dimensions are global. + */ + int i; + NClist* varnodes = dapcomm->cdf.varnodes; + CDFnode* globalsdim = NULL; + char dimname[4096]; + size_t dimsize; + + /* Start by creating the global string dimension */ + snprintf(dimname,sizeof(dimname),"maxStrlen%lu", + (unsigned long)dapcomm->cdf.defaultstringlength); + globalsdim = makecdfnode34(dapcomm, dimname, OC_Dimension, OCNULL, + dapcomm->cdf.ddsroot); + nclistpush(dapcomm->cdf.ddsroot->tree->nodes,(ncelem)globalsdim); + DIMFLAGSET(globalsdim,CDFDIMSTRING); + globalsdim->dim.declsize = dapcomm->cdf.defaultstringlength; + globalsdim->dim.declsize0 = globalsdim->dim.declsize; + globalsdim->dim.array = dapcomm->cdf.ddsroot; + globalsdim->ncbasename = cdflegalname3(dimname); + globalsdim->ncfullname = nulldup(globalsdim->ncbasename); + dapcomm->cdf.globalstringdim = globalsdim; + + for(i=0;ietype != NC_STRING && var->etype != NC_URL) continue; + + dimsize = 0; + if(var->dodsspecial.maxstrlen > 0) + dimsize = var->dodsspecial.maxstrlen; + else + dimsize = var->maxstringlength; + + /* check is a variable-specific string length was specified */ + if(dimsize == 0) + sdim = dapcomm->cdf.globalstringdim; /* use default */ + else { + /* create a psuedo dimension for the charification of the string*/ + if(var->dodsspecial.dimname != NULL) + strncpy(dimname,var->dodsspecial.dimname,sizeof(dimname)); + else + snprintf(dimname,sizeof(dimname),"maxStrlen%lu", + (unsigned long)dimsize); + sdim = makecdfnode34(dapcomm, dimname, OC_Dimension, OCNULL, + dapcomm->cdf.ddsroot); + if(sdim == NULL) return THROW(NC_ENOMEM); + nclistpush(dapcomm->cdf.ddsroot->tree->nodes,(ncelem)sdim); + DIMFLAGSET(sdim,CDFDIMSTRING); + sdim->dim.declsize = dimsize; + sdim->dim.declsize0 = dimsize; + sdim->dim.array = var; + sdim->ncbasename = cdflegalname3(sdim->ocname); + sdim->ncfullname = nulldup(sdim->ncbasename); + } + /* tag the variable with its string dimension*/ + var->array.stringdim = sdim; + } + return NC_NOERR; +} + +NCerror +defrecorddim3(NCDAPCOMMON* dapcomm) +{ + unsigned int i; + NCerror ncstat = NC_NOERR; + NClist* basedims; + + if(dapcomm->cdf.recorddimname == NULL) return NC_NOERR; /* ignore */ + /* Locate the base dimension matching the record dim */ + basedims = dapcomm->cdf.dimnodes; + for(i=0;iocname,dapcomm->cdf.recorddimname) != 0) continue; + DIMFLAGSET(dim,CDFDIMRECORD); + dapcomm->cdf.recorddim = dim; + break; + } + + return ncstat; +} + +NCerror +defseqdims(NCDAPCOMMON* dapcomm) +{ + unsigned int i; + NCerror ncstat = NC_NOERR; + int seqdims = 1; /* default is to compute seq dims counts */ + + /* Does the user want to compute actual sequence sizes? */ + if(paramvalue34(dapcomm,"noseqdims")) seqdims = 0; + + /* + Compute and define pseudo dimensions for sequences + meeting the following qualifications: + 1. all parents (transitively) of the sequence must + be either a dataset or a scalar structure. + 2. it must be possible to find a usable sequence constraint. + All other sequences will be ignored. + */ + + for(i=0;icdf.seqnodes);i++) { + CDFnode* seq = (CDFnode*)nclistget(dapcomm->cdf.seqnodes,i); + size_t seqsize; + CDFnode* sqdim = NULL; + CDFnode* container; + /* Does this sequence match the requirements for use ? */ + seq->usesequence = 1; /* assume */ + for(container=seq->container;container != NULL;container=container->container) { + if(container->nctype == NC_Dataset) break; + if(container->nctype != NC_Structure + || nclistlength(container->array.dimset0) > 0) + {seq->usesequence = 0; break;}/* no good */ + } + /* Does the user want us to compute the actual sequence dim size? */ + if(seq->usesequence && seqdims) { + ncstat = getseqdimsize(dapcomm,seq,&seqsize); + if(ncstat != NC_NOERR) { + /* Cannot read sequence; mark as unusable */ + seq->usesequence = 0; + } + } else { /* !seqdims default to size = 1 */ + seqsize = 1; + } + if(seq->usesequence) { + /* Note: we are making the dimension in the dds root tree */ + ncstat = makeseqdim(dapcomm,seq,seqsize,&sqdim); + if(ncstat) goto fail; + seq->array.seqdim = sqdim; + } else + seq->array.seqdim = NULL; + } + +fail: + return ncstat; +} + +static NCerror +getseqdimsize(NCDAPCOMMON* dapcomm, CDFnode* seq, size_t* sizep) +{ + NCerror ncstat = NC_NOERR; + OCerror ocstat = OC_NOERR; + OCconnection conn = dapcomm->oc.conn; + OCdata rootcontent = OCNULL; + OCobject ocroot; + CDFnode* dxdroot; + CDFnode* xseq; + NCbytes* seqcountconstraints = ncbytesnew(); + size_t seqsize; + + /* Read the minimal amount of data in order to get the count */ + /* If the url is unconstrainable, then get the whole thing */ + computeseqcountconstraints3(dapcomm,seq,seqcountconstraints); +#ifdef DEBUG +fprintf(stderr,"seqcountconstraints: %s\n",ncbytescontents(seqcountconstraints)); +#endif + + /* Fetch the minimal data */ + if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) + ocstat = dap_fetch(dapcomm,conn,NULL,OCDATADDS,&ocroot); + else + ocstat = dap_fetch(dapcomm,conn,ncbytescontents(seqcountconstraints),OCDATADDS,&ocroot); + if(ocstat) goto fail; + + ncstat = buildcdftree34(dapcomm,ocroot,OCDATA,&dxdroot); + if(ncstat) goto fail; + /* attach DATADDS to DDS */ + ncstat = attach34(dxdroot,seq); + if(ncstat) goto fail; + + /* WARNING: we are now switching to datadds tree */ + xseq = seq->attachment; + ncstat = countsequence(dapcomm,xseq,&seqsize); + if(ncstat) goto fail; + +#ifdef DEBUG +fprintf(stderr,"sequencesize: %s = %lu\n",seq->ocname,(unsigned long)seqsize); +#endif + + /* throw away the fetch'd trees */ + unattach34(dapcomm->cdf.ddsroot); + freecdfroot34(dxdroot); + if(ncstat != NC_NOERR) { + /* Cannot get DATADDDS*/ + char* code; + char* msg; + long httperr; + oc_svcerrordata(dapcomm->oc.conn,&code,&msg,&httperr); + if(code != NULL) { + nclog(NCLOGERR,"oc_fetch_datadds failed: %s %s %l", + code,msg,httperr); + } + ocstat = OC_NOERR; + } + if(sizep) *sizep = seqsize; + +fail: + ncbytesfree(seqcountconstraints); + oc_data_free(conn,rootcontent); + if(ocstat) ncstat = ocerrtoncerr(ocstat); + return ncstat; +} + +static NCerror +makeseqdim(NCDAPCOMMON* dapcomm, CDFnode* seq, size_t count, CDFnode** sqdimp) +{ + CDFnode* sqdim; + CDFnode* root = seq->root; + CDFtree* tree = root->tree; + + /* build the dimension with given size; keep the dimension anonymous */ + sqdim = makecdfnode34(dapcomm,seq->ocname,OC_Dimension,OCNULL,root); + if(sqdim == NULL) return THROW(NC_ENOMEM); + nclistpush(tree->nodes,(ncelem)sqdim); + /* Assign a name to the sequence node */ + sqdim->ncbasename = cdflegalname3(seq->ocname); + sqdim->ncfullname = nulldup(sqdim->ncbasename); + DIMFLAGSET(sqdim,CDFDIMSEQ); + sqdim->dim.declsize = count; + sqdim->dim.declsize0 = count; + sqdim->dim.array = seq; + if(sqdimp) *sqdimp = sqdim; + return NC_NOERR; +} + +static NCerror +countsequence(NCDAPCOMMON* dapcomm, CDFnode* xseq, size_t* sizep) +{ + unsigned int i; + NClist* path = nclistnew(); + int index; + OCerror ocstat = OC_NOERR; + NCerror ncstat = NC_NOERR; + OCconnection conn = dapcomm->oc.conn; + size_t recordcount; + CDFnode* xroot; + CDFnode* current; + OCdata datacontainer = OCNULL; + OCmode mode; + + ASSERT((xseq->nctype == NC_Sequence)); + + /* collect the path to the sequence node */ + collectnodepath3(xseq,path,WITHDATASET); + + /* Get tree root */ + xroot = xseq->root; + datacontainer = oc_data_new(conn); + ocstat = oc_data_root(conn,xroot->tree->ocroot,datacontainer); + if(ocstat) goto fail; + + /* walk to the sequence object; control the movement to the next node + based on mode */ + current = (CDFnode*)nclistget(path,0); + for(i=0;;) { + OCdata child = OCNULL; + CDFnode* next = NULL; + ocstat = oc_data_mode(conn,datacontainer,&mode); + if(ocstat != OC_NOERR) goto fail; + switch (mode) { + case OCFIELDMODE: + i++; + next = (CDFnode*)nclistget(path,i); + index = fieldindex(current,next); + break; + case OCARRAYMODE: + index = 0; + break; + case OCSEQUENCEMODE: + goto exitloop; + default: + PANIC("unexpected mode"); + return NC_EINVAL; + } + child = oc_data_new(conn); + ocstat = oc_data_ith(conn,datacontainer,index,child); + if(ocstat) goto fail; + /* move to the next node only if it is defined */ + if(next != NULL) + current = next; + oc_data_free(conn,datacontainer); + datacontainer = child; + } +exitloop: + ASSERT(current == xseq && mode == OCSEQUENCEMODE); + oc_data_count(conn,datacontainer,&recordcount); + if(sizep) *sizep = recordcount; + +fail: + oc_data_free(conn,datacontainer); + nclistfree(path); + if(ocstat) ncstat = ocerrtoncerr(ocstat); + return THROW(ncstat); +} + +static int +fieldindex(CDFnode* parent, CDFnode* child) +{ + unsigned int i; + for(i=0;isubnodes);i++) { + CDFnode* node = (CDFnode*)nclistget(parent->subnodes,i); + if(node == child) return i; + } + return -1; +} + +NCerror +showprojection3(NCDAPCOMMON* dapcomm, CDFnode* var) +{ + int i,rank; + NCerror ncstat = NC_NOERR; + NCbytes* projection = ncbytesnew(); + NClist* path = nclistnew(); + NC* drno = dapcomm->controller; + + /* Collect the set of DDS node name forming the xpath */ + collectnodepath3(var,path,WITHOUTDATASET); + for(i=0;i 0) ncbytescat(projection,"."); + ncbytescat(projection,node->ocname); + } + /* Now, add the dimension info */ + rank = nclistlength(var->array.dimset0); + for(i=0;iarray.dimset0,i); + char tmp[32]; + ncbytescat(projection,"["); + snprintf(tmp,sizeof(tmp),"%lu",(unsigned long)dim->dim.declsize); + ncbytescat(projection,tmp); + ncbytescat(projection,"]"); + } + /* Define the attribute */ + ncstat = nc_put_att_text(getncid(drno),var->ncid, + "_projection", + ncbyteslength(projection), + ncbytescontents(projection)); + return ncstat; +} + +/* +This is more complex than one might think. We want to find +a path to a variable inside the given node so that we can +ask for a single instance of that variable to minimize the +amount of data we retrieve. However, we want to avoid passing +through any nested sequence. This is possible because of the way +that sequencecheck() works. +TODO: some servers will not accept an unconstrained fetch, so +make sure we always have a constraint. +*/ + +static NCerror +computeseqcountconstraints3(NCDAPCOMMON* dapcomm, CDFnode* seq, NCbytes* seqcountconstraints) +{ + int i,j; + NClist* path = NULL; + CDFnode* var = NULL; + + ASSERT(seq->nctype == NC_Sequence); + computeseqcountconstraints3r(dapcomm,seq,&var); + + ASSERT((var != NULL)); + + /* Compute var path */ + path = nclistnew(); + collectnodepath3(var,path,WITHOUTDATASET); + + /* construct the projection path using minimal index values */ + for(i=0;i 0) ncbytescat(seqcountconstraints,"."); + ncbytescat(seqcountconstraints,node->ocname); + if(node == seq) { + /* Use the limit */ + if(node->sequencelimit > 0) { + char tmp[64]; + snprintf(tmp,sizeof(tmp),"[0:%lu]", + (unsigned long)(node->sequencelimit - 1)); + ncbytescat(seqcountconstraints,tmp); + } + } else if(nclistlength(node->array.dimset0) > 0) { + int ndims = nclistlength(node->array.dimset0); + for(j=0;jarray.dimset0,j); + if(DIMFLAG(dim,CDFDIMSTRING)) { + ASSERT((j == (ndims - 1))); + break; + } + ncbytescat(seqcountconstraints,"[0]"); + } + } + } + /* Finally, add in any selection from the original URL */ + if(dapcomm->oc.url->selection != NULL) + ncbytescat(seqcountconstraints,dapcomm->oc.url->selection); + nclistfree(path); + return NC_NOERR; +} + + +/* Given an existing candidate, see if we prefer newchoice */ +static CDFnode* +prefer(CDFnode* candidate, CDFnode* newchoice) +{ + nc_type newtyp; + nc_type cantyp; + int newisstring; + int canisstring; + int newisscalar; + int canisscalar; + + /* always choose !null over null */ + if(newchoice == NULL) + return candidate; + if(candidate == NULL) + return newchoice; + + newtyp = newchoice->etype; + cantyp = candidate->etype; + newisstring = (newtyp == NC_STRING || newtyp == NC_URL); + canisstring = (cantyp == NC_STRING || cantyp == NC_URL); + newisscalar = (nclistlength(newchoice->array.dimset0) == 0); + canisscalar = (nclistlength(candidate->array.dimset0) == 0); + + ASSERT(candidate->nctype == NC_Primitive && newchoice->nctype == NC_Primitive); + + /* choose non-string over string */ + if(canisstring && !newisstring) + return newchoice; + if(!canisstring && newisstring) + return candidate; + + /* choose scalar over array */ + if(canisscalar && !newisscalar) + return candidate; + if(!canisscalar && newisscalar) + return candidate; + + /* otherwise choose existing candidate */ + return candidate; +} + +/* computeseqcountconstraints3 recursive helper function */ +static void +computeseqcountconstraints3r(NCDAPCOMMON* dapcomm, CDFnode* node, CDFnode** candidatep) +{ + CDFnode* candidate; + CDFnode* compound; + unsigned int i; + + candidate = NULL; + compound = NULL; + + for(i=0;isubnodes);i++){ + CDFnode* subnode = (CDFnode*)nclistget(node->subnodes,i); + if(subnode->nctype == NC_Structure || subnode->nctype == NC_Grid) + compound = subnode; /* save for later recursion */ + else if(subnode->nctype == NC_Primitive) { + candidate = prefer(candidate,subnode); + } + } + if(candidate == NULL && compound == NULL) { + PANIC("cannot find candidate for seqcountconstraints for a sequence"); + } else if(candidate != NULL && candidatep != NULL) { + *candidatep = candidate; + } else { /* compound != NULL by construction */ + /* recurse on a nested grids or strucures */ + computeseqcountconstraints3r(dapcomm,compound,candidatep); + } +} + + +static unsigned long +cdftotalsize3(NClist* dimensions) +{ + unsigned int i; + unsigned long total = 1; + if(dimensions != NULL) { + for(i=0;idim.declsize; + } + } + return total; +} + +/* Estimate variables sizes and then resort the variable list + by that size +*/ +void +estimatevarsizes3(NCDAPCOMMON* dapcomm) +{ + int ivar; + unsigned int rank; + size_t totalsize = 0; + + for(ivar=0;ivarcdf.varnodes);ivar++) { + CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,ivar); + NClist* ncdims = var->array.dimset0; + rank = nclistlength(ncdims); + if(rank == 0) { /* use instance size of the type */ + var->estimatedsize = nctypesizeof(var->etype); +#ifdef DEBUG1 +fprintf(stderr,"scalar %s.estimatedsize = %lu\n", + makecdfpathstring3(var,"."),var->estimatedsize); +#endif + } else { + unsigned long size = cdftotalsize3(ncdims); + size *= nctypesizeof(var->etype); +#ifdef DEBUG1 +fprintf(stderr,"array %s(%u).estimatedsize = %lu\n", + makecdfpathstring3(var,"."),rank,size); +#endif + var->estimatedsize = size; + } + totalsize += var->estimatedsize; + } +#ifdef DEBUG1 +fprintf(stderr,"total estimatedsize = %lu\n",totalsize); +#endif + dapcomm->cdf.totalestimatedsize = totalsize; +} + +NCerror +fetchtemplatemetadata3(NCDAPCOMMON* dapcomm) +{ + NCerror ncstat = NC_NOERR; + OCerror ocstat = OC_NOERR; + OCobject ocroot = OCNULL; + CDFnode* ddsroot = NULL; + char* ce = NULL; + + /* Temporary hack: we need to get the selection string + from the url + */ + /* Get (almost) unconstrained DDS; In order to handle functions + correctly, those selections must always be included + */ + if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) + ce = NULL; + else + ce = nulldup(dapcomm->oc.url->selection); + + /* Get selection constrained DDS */ + ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot); + if(ocstat != OC_NOERR) { + /* Special Hack. If the protocol is file, then see if + we can get the dds from the .dods file + */ + if(strcmp(dapcomm->oc.url->protocol,"file") != 0) { + THROWCHK(ocstat); goto done; + } + /* Fetch the data dds */ + ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDATADDS,&ocroot); + if(ocstat != OC_NOERR) { + THROWCHK(ocstat); goto done; + } + /* Note what we did */ + nclog(NCLOGWARN,"Cannot locate .dds file, using .dods file"); + } + + /* Get selection constrained DAS */ + ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDAS,&dapcomm->oc.ocdasroot); + if(ocstat != OC_NOERR) { + /* Ignore but complain */ + nclog(NCLOGWARN,"Could not read DAS; ignored"); + dapcomm->oc.ocdasroot = OCNULL; + ocstat = OC_NOERR; + } + + /* Construct our parallel dds tree */ + ncstat = buildcdftree34(dapcomm,ocroot,OCDDS,&ddsroot); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} + dapcomm->cdf.fullddsroot = ddsroot; + +done: + nullfree(ce); + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); + return ncstat; +} + +NCerror +fetchconstrainedmetadata3(NCDAPCOMMON* dapcomm) +{ + NCerror ncstat = NC_NOERR; + OCerror ocstat = OC_NOERR; + OCobject ocroot; + CDFnode* ddsroot; /* constrained */ + char* ce = NULL; + + if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) + ce = NULL; + else + ce = buildconstraintstring3(dapcomm->oc.dapconstraint); + + { + ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot); + if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} + + /* Construct our parallel dds tree; including attributes*/ + ncstat = buildcdftree34(dapcomm,ocroot,OCDDS,&ddsroot); + if(ncstat) goto fail; + + dapcomm->cdf.ddsroot = ddsroot; + + if(!FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) { + /* fix DAP server problem by adding back any missing grid structure nodes */ + ncstat = regrid3(ddsroot,dapcomm->cdf.fullddsroot,dapcomm->oc.dapconstraint->projections); + if(ncstat) goto fail; + } + +#ifdef DEBUG +fprintf(stderr,"constrained:\n%s",dumptree(ddsroot)); +#endif + + /* Combine DDS and DAS */ + if(dapcomm->oc.ocdasroot != NULL) { + ncstat = dapmerge3(dapcomm,ddsroot,dapcomm->oc.ocdasroot); + if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;} + } + + /* map the constrained DDS to the unconstrained DDS */ + ncstat = mapnodes3(ddsroot,dapcomm->cdf.fullddsroot); + if(ncstat) goto fail; + + } + +fail: + nullfree(ce); + if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); + return ncstat; +} + +/* Suppress variables not in usable sequences*/ +NCerror +suppressunusablevars3(NCDAPCOMMON* dapcomm) +{ + int i,j; + int found = 1; + NClist* path = nclistnew(); + + while(found) { + found = 0; + /* Walk backwards to aid removal semantics */ + for(i=nclistlength(dapcomm->cdf.varnodes)-1;i>=0;i--) { + CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i); + /* See if this var is under an unusable sequence */ + nclistclear(path); + collectnodepath3(var,path,WITHOUTDATASET); + for(j=0;jnctype == NC_Sequence + && !node->usesequence) { +#ifdef DEBUG +fprintf(stderr,"suppressing var in unusable sequence: %s.%s\n",node->ncfullname,var->ncbasename); +#endif + found = 1; + break; + } + } + if(found) break; + } + if(found) nclistremove(dapcomm->cdf.varnodes,i); + } + nclistfree(path); + return NC_NOERR; +} + + +/* +For variables which have a zero size dimension, +make them invisible. +*/ +NCerror +fixzerodims3(NCDAPCOMMON* dapcomm) +{ + int i,j; + for(i=0;icdf.varnodes);i++) { + CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i); + NClist* ncdims = var->array.dimsetplus; + if(nclistlength(ncdims) == 0) continue; + for(j=0;jdim.declsize == 0) { + /* make node invisible */ + var->visible = 0; + var->zerodim = 1; + } + } + } + return NC_NOERR; +} + +void +applyclientparamcontrols3(NCDAPCOMMON* dapcomm) +{ + /* clear the flags */ + CLRFLAG(dapcomm->controls,NCF_CACHE); + CLRFLAG(dapcomm->controls,NCF_PREFETCH); + CLRFLAG(dapcomm->controls,NCF_SHOWFETCH); + CLRFLAG(dapcomm->controls,NCF_NC3); + CLRFLAG(dapcomm->controls,NCF_NCDAP); + + /* Turn on any default on flags */ + SETFLAG(dapcomm->controls,DFALT_ON_FLAGS); + SETFLAG(dapcomm->controls,(NCF_NC3|NCF_NCDAP)); + + /* enable/disable caching */ + if(paramcheck34(dapcomm,"cache",NULL)) + SETFLAG(dapcomm->controls,NCF_CACHE); + else if(paramcheck34(dapcomm,"nocache",NULL)) + CLRFLAG(dapcomm->controls,NCF_CACHE); + + /* enable/disable cache prefetch */ + if(paramcheck34(dapcomm,"prefetch",NULL)) + SETFLAG(dapcomm->controls,NCF_PREFETCH); + else if(paramcheck34(dapcomm,"noprefetch",NULL)) + CLRFLAG(dapcomm->controls,NCF_PREFETCH); + + + if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) + SETFLAG(dapcomm->controls,NCF_CACHE); + + if(paramcheck34(dapcomm,"show","fetch")) + SETFLAG(dapcomm->controls,NCF_SHOWFETCH); + + nclog(NCLOGNOTE,"Caching=%d",FLAGSET(dapcomm->controls,NCF_CACHE)); + +} diff --git a/extern/src_netcdf4/ncdaperr.c b/extern/src_netcdf4/ncdaperr.c new file mode 100644 index 0000000000000000000000000000000000000000..f031c27f7b4060e24718e2ad24af82e772f23d37 --- /dev/null +++ b/extern/src_netcdf4/ncdaperr.c @@ -0,0 +1,43 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/ncdaperr.c,v 1.10 2009/09/23 22:26:08 dmh Exp $ + *********************************************************************/ + +#include "ncdap3.h" + +NCerror +ocerrtoncerr(OCerror ocerr) +{ + if(ocerr >= 0) return ocerr; /* really a system error*/ + switch (ocerr) { + case OC_NOERR: return NC_NOERR; + case OC_EBADID: return NC_EBADID; + case OC_ECHAR: return NC_ECHAR; + case OC_EDIMSIZE: return NC_EDIMSIZE; + case OC_EEDGE: return NC_EEDGE; + case OC_EINVAL: return NC_EINVAL; + case OC_EINVALCOORDS: return NC_EINVALCOORDS; + case OC_ENOMEM: return NC_ENOMEM; + case OC_ENOTVAR: return NC_ENOTVAR; + case OC_EPERM: return NC_EPERM; + case OC_ESTRIDE: return NC_ESTRIDE; + case OC_EDAP: return NC_EDAP; + case OC_EXDR: return NC_EDAP; + case OC_ECURL: return NC_EIO; + case OC_EBADURL: return NC_EDAPURL; + case OC_EBADVAR: return NC_EDAP; + case OC_EOPEN: return NC_EIO; + case OC_EIO: return NC_EIO; + case OC_ENODATA: return NC_ENODATA; + case OC_EDAPSVC: return NC_EDAPSVC; + case OC_ENAMEINUSE: return NC_ENAMEINUSE; + case OC_EDAS: return NC_EDAS; + case OC_EDDS: return NC_EDDS; + case OC_EDATADDS: return NC_EDATADDS; + case OC_ERCFILE: return NC_EDAP; + case OC_ENOFILE: return NC_ECANTREAD; + default: break; + } + return NC_EDAP; /* default;*/ +} diff --git a/extern/src_netcdf4/ncdimscale.h b/extern/src_netcdf4/ncdimscale.h new file mode 100644 index 0000000000000000000000000000000000000000..d0b1224c1ba9702f09665e14bff8bd18a8930fe6 --- /dev/null +++ b/extern/src_netcdf4/ncdimscale.h @@ -0,0 +1,12 @@ +/* This is part of the netCDF package. + Copyright 2011 University Corporation for Atmospheric Research/Unidata + See COPYRIGHT file for conditions of use. + + Includes for some HDF5 stuff needed by tests. +*/ + +typedef struct hdf5_objid +{ + unsigned long fileno[2]; /* file number */ + haddr_t objno[2]; /* object number */ +} HDF5_OBJID_T; diff --git a/extern/src_netcdf4/ncdispatch.h b/extern/src_netcdf4/ncdispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..4842aae598ce2935cb179676c69bbc102e501108 --- /dev/null +++ b/extern/src_netcdf4/ncdispatch.h @@ -0,0 +1,386 @@ +/********************************************************************* + * Copyright 2010, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + *********************************************************************/ + +/* $Id: ncdispatch.h,v 1.18 2010/06/01 20:11:59 dmh Exp $ */ +/* $Header: /upc/share/CVS/netcdf-3/libdispatch/ncdispatch.h,v 1.18 2010/06/01 20:11:59 dmh Exp $ */ + +#ifndef _DISPATCH_H +#define _DISPATCH_H + +#include "config.h" +#include +#include +#include +#include +#ifdef USE_PARALLEL +#include "netcdf_par.h" +#endif +#include "netcdf.h" +#include "nc.h" +#include "nc_uri.h" + +#define longtype ((sizeof(long) == sizeof(int) ? NC_INT : NC_INT64)) + +extern int nc_get_vara_ubyte(int ncid, int varid, + const size_t* start, const size_t* count, + unsigned char* value); +extern int nc_get_vara_ushort(int ncid, int varid, + const size_t* start, const size_t* count, + unsigned short* value); +extern int nc_get_vara_uint(int ncid, int varid, + const size_t* start, const size_t* count, + unsigned int* value); +extern int nc_get_vara_ulonglong(int ncid, int varid, + const size_t* start, const size_t* count, + unsigned long long* value); + +extern int nc_put_vara_ushort(int ncid, int varid, + const size_t* start, const size_t* count, + const unsigned short* value); +extern int nc_put_vara_uint(int ncid, int varid, + const size_t* start, const size_t* count, + const unsigned int* value); +extern int nc_put_vara_ulonglong(int ncid, int varid, + const size_t* start, const size_t* count, + const unsigned long long* value); + +#define X_INT_MAX 2147483647 + +/* Given a filename, check its magic number */ +#define MAGIC_NUMBER_LEN 4 +#define MAGIC_HDF5_FILE 1 +#define MAGIC_HDF4_FILE 2 +#define MAGIC_CDF1_FILE 1 /* std classic format */ +#define MAGIC_CDF2_FILE 2 /* classic 64 bit */ + +/* Define the mappings from fcn name types + to corresponding NC types. */ +#define T_text NC_CHAR +#define T_schar NC_BYTE +#define T_char NC_CHAR +#define T_short NC_SHORT +#define T_int NC_INT +#define T_float NC_FLOAT +#define T_double NC_DOUBLE +#define T_ubyte NC_UBYTE +#define T_ushort NC_USHORT +#define T_uint NC_UINT +#define T_longlong NC_INT64 +#define T_ulonglong NC_UINT64 +#ifdef USE_NETCDF4 +#define T_string NC_STRING +#endif + +/* Synthetic type to handle special memtypes */ +#define T_uchar NC_UBYTE +#define T_long longtype +#define T_ulong ulongtype + +/**************************************************/ +/* Define the known classes of dispatchers */ +/* Flags may be or'd => powers of 2*/ +#define NC_DISPATCH_NC3 1 +#define NC_DISPATCH_NC4 2 +#define NC_DISPATCH_NCD 4 +#define NC_DISPATCH_NCR 8 + +/* Define a type for use when doing e.g. nc_get_vara_long, etc. */ +/* Should matche values in libsrc4/netcdf.h */ +#ifndef NC_UINT64 +#define NC_UBYTE 7 /* unsigned 1 byte int */ +#define NC_USHORT 8 /* unsigned 2-byte int */ +#define NC_UINT 9 /* unsigned 4-byte int */ +#define NC_INT64 10 /* signed 8-byte int */ +#define NC_UINT64 11 /* unsigned 8-byte int */ +#define NC_STRING 12 /* char* */ +#endif + +/* Define the range of Atomic types */ +#ifdef USE_NETCDF4 +#define ATOMICTYPEMAX NC_STRING +#else +#define ATOMICTYPEMAX NC_DOUBLE +#endif + +/* Define an alias for int to indicate an error return */ +typedef int NCerror; + +/* Define a struct to hold the MPI info so it can be passed down the + * call stack. This is used internally by the netCDF library. It + * should not be used by netcdf users. */ +#ifdef USE_PARALLEL +typedef struct NC_MPI_INFO { + MPI_Comm comm; + MPI_Info info; +} NC_MPI_INFO; +#endif + +/* Define known dispatch tables and initializers */ + +/*Forward*/ +typedef struct NC_Dispatch NC_Dispatch; + +extern NC_Dispatch* NCSUBSTRATE_dispatch_table; +extern int NCDISPATCH_initialize(void); + +extern NC_Dispatch* NC3_dispatch_table; +extern int NC3_initialize(void); + +#ifdef USE_DAP +extern NC_Dispatch* NCD3_dispatch_table; +extern int NCD3_initialize(void); +#endif + +#ifdef USE_NETCDF4 + +extern NC_Dispatch* NC4_dispatch_table; +extern int NC4_initialize(void); + +#ifdef USE_DAP +extern NC_Dispatch* NCD4_dispatch_table; +extern int NCD4_initialize(void); +#endif + +#ifdef USE_CDMREMOTE +extern NC_Dispatch* NCCR_dispatch_table; +extern int NCCR_initialize(void); +#endif + +#ifdef BUILD_RPC +extern NC_Dispatch* NCRPC_dispatch_table; +extern int NCRPC_initialize(void); +#endif + +#endif /*USE_NETCDF4*/ + +/* Vectors of ones and zeros */ +extern size_t nc_sizevector0[NC_MAX_DIMS]; +extern size_t nc_sizevector1[NC_MAX_DIMS]; +extern ptrdiff_t nc_ptrdiffvector1[NC_MAX_DIMS]; + +/**************************************************/ +/* Forward */ +#ifndef USE_NETCDF4 +/* Taken from libsrc4/netcdf.h */ +struct nc_vlen_t; +#define NC_NETCDF4 0x1000 +#define NC_CLASSIC_MODEL 0x0100 +#define NC_ENOPAR (-114) +#endif /*USE_NETCDF4*/ + +struct NC; + +/* WARNING: this must match libsrc4/netcdf.h */ +#ifndef USE_PARALLEL +#ifndef MPI_Comm +#define MPI_Comm int +#define MPI_Info int +#define MPI_COMM_WORLD 0 +#ifndef MPI_INFO_NULL +#define MPI_INFO_NULL 0 +#endif +#endif +#endif + +int NC_create(const char *path, int cmode, + size_t initialsz, int basepe, size_t *chunksizehintp, + int useparallel,void* mpi_info, + int *ncidp); +int NC_open(const char *path, int cmode, + int basepe, size_t *chunksizehintp, + int useparallel, void* mpi_info, + int *ncidp); + +/* Expose the default vars and varm dispatch entries */ +extern int NCDEFAULT_get_vars(int, int, const size_t*, + const size_t*, const ptrdiff_t*, void*, nc_type); +extern int NCDEFAULT_put_vars(int, int, const size_t*, + const size_t*, const ptrdiff_t*, const void*, nc_type); +extern int NCDEFAULT_get_varm(int, int, const size_t*, + const size_t*, const ptrdiff_t*, const ptrdiff_t*, + void*, nc_type); +extern int NCDEFAULT_put_varm(int, int, const size_t*, + const size_t*, const ptrdiff_t*, const ptrdiff_t*, + const void*, nc_type); + +/**************************************************/ +/* Forward */ +struct NCHDR; + +struct NC_Dispatch { + +int model; /* one of the NC_DISPATCH #'s above */ + +int (*new_nc)(struct NC**); /* Create an nc instance;free is not needed, + because it can be done by close and abort*/ + +/* Warning: these two will create appropriate NC instances + using new_nc dispatch function +*/ +int (*create)(const char *path, int cmode, + size_t initialsz, int basepe, size_t *chunksizehintp, + int use_parallel, void* parameters, + struct NC_Dispatch* table, NC** ncp); +int (*open)(const char *path, int mode, + int basepe, size_t *chunksizehintp, + int use_parallel, void* parameters, + struct NC_Dispatch* table, NC** ncp); + +int (*redef)(int); +int (*_enddef)(int,size_t,size_t,size_t,size_t); +int (*sync)(int); +int (*abort)(int); +int (*close)(int); +int (*set_fill)(int,int,int*); +int (*inq_base_pe)(int,int*); +int (*set_base_pe)(int,int); +int (*inq_format)(int,int*); + +int (*inq)(int,int*,int*,int*,int*); +int (*inq_type)(int, nc_type, char*, size_t*); + +int (*def_dim)(int, const char*, size_t, int*); +int (*inq_dimid)(int, const char*, int*); +int (*inq_dim)(int, int, char*, size_t*); +int (*inq_unlimdim)(int ncid, int *unlimdimidp); +int (*rename_dim)(int, int, const char*); + +int (*inq_att)(int, int, const char*, nc_type*, size_t*); +int (*inq_attid)(int, int, const char*, int*); +int (*inq_attname)(int, int, int, char*); +int (*rename_att)(int, int, const char*, const char*); +int (*del_att)(int, int, const char*); +int (*get_att)(int, int, const char*, void*, nc_type); +int (*put_att)(int, int, const char*, nc_type, size_t, const void*, nc_type); + +int (*def_var)(int, const char*, nc_type, int, const int*, int*); +int (*inq_varid)(int, const char*, int*); +int (*rename_var)(int, int, const char*); + +int (*get_vara)(int, int, const size_t*, const size_t*, void*, nc_type); +int (*put_vara)(int, int, const size_t*, const size_t*, const void*, nc_type); + +/* Added to solve Ferret performance problem with Opendap */ +int (*get_vars)(int, int, const size_t*, const size_t*, const ptrdiff_t*, void*, nc_type); +int (*put_vars)(int, int, const size_t*, const size_t*, const ptrdiff_t*, const void*, nc_type); + +int (*get_varm)(int, int, const size_t*, const size_t*, const ptrdiff_t*, const ptrdiff_t*, void*, nc_type); +int (*put_varm)(int, int, const size_t*, const size_t*, const ptrdiff_t*, const ptrdiff_t*, const void*, nc_type); + + +int (*inq_var_all)(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp, + int *shufflep, int *deflatep, int *deflate_levelp, + int *fletcher32p, int *contiguousp, size_t *chunksizesp, + int *no_fill, void *fill_valuep, int *endiannessp, + int *options_maskp, int *pixels_per_blockp); + +/* Note the following may still be invoked by netcdf client code + even when the file is a classic file +*/ +#ifdef USE_NETCDF4 +int (*show_metadata)(int); +int (*inq_unlimdims)(int, int*, int*); +int (*var_par_access)(int, int, int); +int (*inq_ncid)(int, const char*, int*); +int (*inq_grps)(int, int*, int*); +int (*inq_grpname)(int, char*); +int (*inq_grpname_full)(int, size_t*, char*); +int (*inq_grp_parent)(int, int*); +int (*inq_grp_full_ncid)(int, const char*, int*); +int (*inq_varids)(int, int* nvars, int*); +int (*inq_dimids)(int, int* ndims, int*, int); +int (*inq_typeids)(int, int* ntypes, int*); +int (*inq_type_equal)(int, nc_type, int, nc_type, int*); +int (*def_grp)(int, const char*, int*); +int (*inq_user_type)(int, nc_type, char*, size_t*, nc_type*, size_t*, int*); +int (*inq_typeid)(int, const char*, nc_type*); + +int (*def_compound)(int, size_t, const char*, nc_type*); +int (*insert_compound)(int, nc_type, const char*, size_t, nc_type); +int (*insert_array_compound)(int, nc_type, const char*, size_t, nc_type, int, const int*); +int (*inq_compound_field)(int, nc_type, int, char*, size_t*, nc_type*, int*, int*); +int (*inq_compound_fieldindex)(int, nc_type, const char*, int*); +int (*def_vlen)(int, const char*, nc_type base_typeid, nc_type*); +int (*put_vlen_element)(int, int, void*, size_t, const void*); +int (*get_vlen_element)(int, int, const void*, size_t*, void*); +int (*def_enum)(int, nc_type, const char*, nc_type*); +int (*insert_enum)(int, nc_type, const char*, const void*); +int (*inq_enum_member)(int, nc_type, int, char*, void*); +int (*inq_enum_ident)(int, nc_type, long long, char*); +int (*def_opaque)(int, size_t, const char*, nc_type*); +int (*def_var_deflate)(int, int, int, int, int); +int (*def_var_fletcher32)(int, int, int); +int (*def_var_chunking)(int, int, int, const size_t*); +int (*def_var_fill)(int, int, int, const void*); +int (*def_var_endian)(int, int, int); +int (*set_var_chunk_cache)(int, int, size_t, size_t, float); +int (*get_var_chunk_cache)(int ncid, int varid, size_t *sizep, size_t *nelemsp, float *preemptionp); +#endif /*USE_NETCDF4*/ + +}; + +/* Following functions must be handled as non-dispatch */ +#ifdef NONDISPATCH +void(*nc_advise)(const char*cdf_routine_name,interr,const char*fmt,...); +void(*nc_set_log_level)(int); +const char* (*nc_inq_libvers)(void); +const char* (*nc_strerror)(int); +int(*nc_delete)(const char*path); +int(*nc_delete_mp)(const char*path,intbasepe); +#endif /*NONDISPATCH*/ + +/* Define the common fields for NC and NC_FILE_INFO_T etc */ +typedef struct NCcommon { + int ext_ncid; /* uid << 16 */ + int int_ncid; /* unspecified other id */ + struct NC_Dispatch* dispatch; + void* dispatchdata; /* per-protocol instance data */ + char* path; /* as specified at open or create */ + int substrate; /* ncid for another protocol on which to build */ +} NCcommon; + +extern int NC_atomictypelen(nc_type xtype); +extern char* NC_atomictypename(nc_type xtype); + +/* Provide an initializer */ +extern int NC_initialize(void); + +/* Provide a dispatch table overlay facility */ +extern int NC_dispatch_overlay(const NC_Dispatch* overlay, + const NC_Dispatch* base, + NC_Dispatch* merge); + +/* Get/set the override dispatch table */ +extern NC_Dispatch* NC_get_dispatch_override(void); +extern void NC_set_dispatch_override(NC_Dispatch*); + +/* Does the path look like a url? */ +extern int NC_testurl(const char* path); +/* Return model (0 or 3 or 4) as specified by the url */ +extern int NC_urlmodel(const char* path); + +/* allow access url parse and params without exposing nc_url.h */ +extern int NCDAP_urlparse(const char* s, void** dapurl); +extern void NCDAP_urlfree(void* dapurl); +extern const char* NCDAP_urllookup(void* dapurl, const char* param); + +/* Test for specific set of servers */ +extern const char* NC_findtestserver(const char*); +/* Ping a specific server */ +extern int NCDAP_ping(const char*); + +/* Misc */ + +extern int NC_getshape(int ncid, int varid, int ndims, size_t* shape); +extern int NC_is_recvar(int ncid, int varid, size_t* nrecs); + +#define nullstring(s) (s==NULL?"(null)":s) + +extern size_t* NC_coord_zero; +extern size_t* NC_coord_one; + +#endif /* _DISPATCH_H */ + diff --git a/extern/src_netcdf4/ncfunc.c b/extern/src_netcdf4/ncfunc.c new file mode 100644 index 0000000000000000000000000000000000000000..85ce74b8a0c6bd2a5292094ae434a2bcabad87a5 --- /dev/null +++ b/extern/src_netcdf4/ncfunc.c @@ -0,0 +1,100 @@ +/* + +This file is part of netcdf-4, a netCDF-like interface for HDF5, or a +HDF5 backend for netCDF, depending on your point of view. + +This file handles the nc_ calls, calling the appropriate nc3 or nc4 +function, depending on ncid. + +Copyright 2003, University Corporation for Atmospheric Research. See +netcdf-4/docs/COPYRIGHT file for copying and redistribution +conditions. +*/ + +#include "nc4internal.h" +#include "nc3dispatch.h" + +#ifdef IGNORE +/* Keep a linked list of file info objects. */ +extern NC_FILE_INFO_T *nc_file; +#endif + +#ifdef IGNORE +/* This function deletes a member of parliment. Be careful! Last time + * this function was used, Labor got in! This function only does + * anything for netcdf-3 files. */ + +int +nc_delete(const char *path) +{ + return NC3_delete_mp(path, 0); +} + +int +nc_delete_mp(const char *path, int basepe) +{ + return NC3_delete_mp(path, basepe); +} +#endif + +/* This will return the length of a netcdf data type in bytes. Since + we haven't added any new types, I just call the v3 function. + Ed Hartnett 10/43/03 +*/ + +/* This function only does anything for netcdf-3 files. */ +int +NC4_set_base_pe(int ncid, int pe) +{ + NC_FILE_INFO_T *nc; + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + if (nc->nc4_info) + return NC_ENOTNC3; + return NC3_set_base_pe(nc->int_ncid, pe); +} + +/* This function only does anything for netcdf-3 files. */ +int +NC4_inq_base_pe(int ncid, int *pe) +{ + NC_FILE_INFO_T *nc; + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + if (nc->nc4_info) + return NC_ENOTNC3; + return NC3_inq_base_pe(nc->int_ncid, pe); +} + +/* Get the format (i.e. classic, 64-bit-offset, or netcdf-4) of an + * open file. */ +int +NC4_inq_format(int ncid, int *formatp) +{ + NC_FILE_INFO_T *nc; + + LOG((2, "nc_inq_format: ncid 0x%x", ncid)); + + if (!formatp) + return NC_NOERR; + + /* Find the file metadata. */ + if (!(nc = nc4_find_nc_file(ncid))) + return NC_EBADID; + + /* If this isn't a netcdf-4 file, pass this call on to the netcdf-3 + * library. */ + if (!nc->nc4_info) + return NC3_inq_format(nc->int_ncid, formatp); + + /* Otherwise, this is a netcdf-4 file. Check if classic NC3 rules + * are in effect for this file. */ + if (nc->nc4_info->cmode & NC_CLASSIC_MODEL) + *formatp = NC_FORMAT_NETCDF4_CLASSIC; + else + *formatp = NC_FORMAT_NETCDF4; + + return NC_NOERR; +} + + diff --git a/extern/src_netcdf4/nchashmap.c b/extern/src_netcdf4/nchashmap.c new file mode 100644 index 0000000000000000000000000000000000000000..3f1eb2baabcc29ff7c31f71dff690cc6ab76375b --- /dev/null +++ b/extern/src_netcdf4/nchashmap.c @@ -0,0 +1,194 @@ +/********************************************************************* + * Copyright 1993, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header: /upc/share/CVS/netcdf-3/libncdap3/nchashmap.c,v 1.4 2009/09/23 22:26:08 dmh Exp $ + *********************************************************************/ +#include +#include +#include + +#include "nchashmap.h" + +static ncelem ncDATANULL = (ncelem)0; + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define DEFAULTALLOC 31 + +NChashmap* nchashnew(void) {return nchashnew0(DEFAULTALLOC);} + +NChashmap* nchashnew0(int alloc) +{ + NChashmap* hm; + hm = (NChashmap*)malloc(sizeof(NChashmap)); + if(!hm) return NULL; + hm->alloc = alloc; + hm->table = (NClist**)malloc(hm->alloc*sizeof(NClist*)); + if(!hm->table) {free(hm); return NULL;} + memset((void*)hm->table,0,hm->alloc*sizeof(NClist*)); + return hm; +} + +int +nchashfree(NChashmap* hm) +{ + if(hm) { + int i; + for(i=0;ialloc;i++) { + if(hm->table[i] != NULL) nclistfree(hm->table[i]); + } + free(hm->table); + free(hm); + } + return TRUE; +} + +/* Insert a pair into the table*/ +/* Fail if already there*/ +int +nchashinsert(NChashmap* hm, nchashid hash, ncelem value) +{ + int i,offset,len; + NClist* seq; + ncelem* list; + + offset = (hash % hm->alloc); + seq = hm->table[offset]; + if(seq == NULL) {seq = nclistnew(); hm->table[offset] = seq;} + len = nclistlength(seq); + list = nclistcontents(seq); + for(i=0;isize++; + return TRUE; +} + +/* Insert a pair into the table*/ +/* Overwrite if already there*/ +int +nchashreplace(NChashmap* hm, nchashid hash, ncelem value) +{ + int i,offset,len; + NClist* seq; + ncelem* list; + + offset = (hash % hm->alloc); + seq = hm->table[offset]; + if(seq == NULL) {seq = nclistnew(); hm->table[offset] = seq;} + len = nclistlength(seq); + list = nclistcontents(seq); + for(i=0;isize++; + return TRUE; +} + +/* remove a nchashid*/ +/* return TRUE if found, false otherwise*/ +int +nchashremove(NChashmap* hm, nchashid hash) +{ + int i,offset,len; + NClist* seq; + ncelem* list; + + offset = (hash % hm->alloc); + seq = hm->table[offset]; + if(seq == NULL) return TRUE; + len = nclistlength(seq); + list = nclistcontents(seq); + for(i=0;isize--; + if(nclistlength(seq) == 0) {nclistfree(seq); hm->table[offset] = NULL;} + return TRUE; + } + } + return FALSE; +} + +/* lookup a nchashid; return DATANULL if not found*/ +/* (use hashlookup if the possible values include 0)*/ +ncelem +nchashget(NChashmap* hm, nchashid hash) +{ + ncelem value; + if(!nchashlookup(hm,hash,&value)) return ncDATANULL; + return value; +} + +int +nchashlookup(NChashmap* hm, nchashid hash, ncelem* valuep) +{ + int i,offset,len; + NClist* seq; + ncelem* list; + + offset = (hash % hm->alloc); + seq = hm->table[offset]; + if(seq == NULL) return TRUE; + len = nclistlength(seq); + list = nclistcontents(seq); + for(i=0;ialloc;i++) { + NClist* seq = hm->table[i]; + int len = nclistlength(seq) / 2; + if(len == 0) continue; + if((index - len) < 0) { + if(hashp) *hashp = (nchashid)nclistget(seq,index*2); + if(elemp) *elemp = nclistget(seq,(index*2)+1); + return TRUE; + } + index -= len; + } + return FALSE; +} + +/* Return all the keys; order is completely arbitrary*/ +/* Can be expensive*/ +int +nchashkeys(NChashmap* hm, nchashid** keylist) +{ + int i,j,index; + nchashid* keys; + if(hm == NULL) return FALSE; + if(hm->size == 0) { + keys = NULL; + } else { + keys = (nchashid*)malloc(sizeof(nchashid)*hm->size); + for(index=0,i=0;ialloc;i++) { + NClist* seq = hm->table[i]; + for(j=0;jsize:0) + +#endif /*NCHASHMAP_H*/ + diff --git a/extern/src_netcdf4/ncio.c b/extern/src_netcdf4/ncio.c new file mode 100644 index 0000000000000000000000000000000000000000..018b5a8f469996d1b046cd9b1294a18d88caccbd --- /dev/null +++ b/extern/src_netcdf4/ncio.c @@ -0,0 +1,132 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ + +#include +#include + +#include "netcdf.h" +#include "ncio.h" +#include "fbits.h" + +/* With the advent of diskless io, we need to provide + for multiple ncio packages at the same time, + so we have multiple versions of ncio_create. +*/ + +/* Define known ncio packages */ +extern int posixio_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const); +extern int posixio_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const); + +#ifdef USE_FFIO +extern int ffio_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const); +extern int ffio_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const); +#endif + +#ifdef USE_DISKLESS +# ifdef USE_MMAP + extern int mmapio_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const); + extern int mmapio_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const); +# endif + extern int memio_create(const char*,int,size_t,off_t,size_t,size_t*,ncio**,void** const); + extern int memio_open(const char*,int,off_t,size_t,size_t*,ncio**,void** const); +#endif + +int +ncio_create(const char *path, int ioflags, size_t initialsz, + off_t igeto, size_t igetsz, size_t *sizehintp, + ncio** iopp, void** const mempp) +{ +#ifdef USE_DISKLESS + if(fIsSet(ioflags,NC_DISKLESS)) { +# ifdef USE_MMAP + if(fIsSet(ioflags,NC_MMAP)) + return mmapio_create(path,ioflags,initialsz,igeto,igetsz,sizehintp,iopp,mempp); + else +# endif /*USE_MMAP*/ + return memio_create(path,ioflags,initialsz,igeto,igetsz,sizehintp,iopp,mempp); + } +#endif + +#ifdef USE_FFIO + return ffio_create(path,ioflags,initialsz,igeto,igetsz,sizehintp,iopp,mempp); +#else + return posixio_create(path,ioflags,initialsz,igeto,igetsz,sizehintp,iopp,mempp); +#endif +} + +int +ncio_open(const char *path, int ioflags, + off_t igeto, size_t igetsz, size_t *sizehintp, + ncio** iopp, void** const mempp) +{ + /* Diskless open has the following constraints: + 1. file must be classic version 1 or 2 + */ +#ifdef USE_DISKLESS + if(fIsSet(ioflags,NC_DISKLESS)) { +# ifdef USE_MMAP + if(fIsSet(ioflags,NC_MMAP)) + return mmapio_open(path,ioflags,igeto,igetsz,sizehintp,iopp,mempp); + else +# endif /*USE_MMAP*/ + return memio_open(path,ioflags,igeto,igetsz,sizehintp,iopp,mempp); + } +#endif +#ifdef USE_FFIO + return ffio_open(path,ioflags,igeto,igetsz,sizehintp,iopp,mempp); +#else + return posixio_open(path,ioflags,igeto,igetsz,sizehintp,iopp,mempp); +#endif +} + +/**************************************************/ +/* wrapper functions for the ncio dispatch table */ + +int +ncio_rel(ncio *const nciop, off_t offset, int rflags) +{ + return nciop->rel(nciop,offset,rflags); +} + +int +ncio_get(ncio *const nciop, off_t offset, size_t extent, + int rflags, void **const vpp) +{ + return nciop->get(nciop,offset,extent,rflags,vpp); +} + +int +ncio_move(ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags) +{ + return nciop->move(nciop,to,from,nbytes,rflags); +} + +int +ncio_sync(ncio *const nciop) +{ + return nciop->sync(nciop); +} + +int +ncio_filesize(ncio *nciop, off_t *filesizep) +{ + return nciop->filesize(nciop,filesizep); +} + +int +ncio_pad_length(ncio* nciop, off_t length) +{ + return nciop->pad_length(nciop,length); +} + +int +ncio_close(ncio *nciop, int doUnlink) +{ + /* close and release all resources associated + with nciop, including nciop + */ + int status = nciop->close(nciop,doUnlink); + return status; +} diff --git a/extern/src_netcdf4/ncio.h b/extern/src_netcdf4/ncio.h new file mode 100644 index 0000000000000000000000000000000000000000..617b851da057799c42932b993acec900a13b94d3 --- /dev/null +++ b/extern/src_netcdf4/ncio.h @@ -0,0 +1,175 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: ncio.h,v 1.27 2006/01/03 04:56:28 russ Exp $ */ + +#ifndef _NCIO_H_ +#define _NCIO_H_ + +#include /* size_t */ +#include /* off_t */ +#include "netcdf.h" + +typedef struct ncio ncio; /* forward reference */ + +/* + * A value which is an invalid off_t + */ +#define OFF_NONE ((off_t)(-1)) + +/* + * Flags used by the region layer, + * 'rflags' argument to ncio.rel() and ncio.get(). + */ +#define RGN_NOLOCK 0x1 /* Don't lock region. + * Used when contention control handled + * elsewhere. + */ +#define RGN_NOWAIT 0x2 /* return immediate if can't lock, else wait */ + +#define RGN_WRITE 0x4 /* we intend to modify, else read only */ + +#define RGN_MODIFIED 0x8 /* we did modify, else, discard */ + + +/* + * The next four typedefs define the signatures + * of function pointers in struct ncio below. + * They are not used outside of this file and ncio.h, + * They just make some casts in the ncio.c more readable. + */ + /* + * Indicate that you are done with the region which begins + * at offset. Only reasonable flag value is RGN_MODIFIED. + */ +typedef int ncio_relfunc(ncio *const nciop, + off_t offset, int rflags); + + /* + * Request that the region (offset, extent) + * be made available through *vpp. + */ +typedef int ncio_getfunc(ncio *const nciop, + off_t offset, size_t extent, + int rflags, + void **const vpp); + + /* + * Like memmove(), safely move possibly overlapping data. + * Only reasonable flag value is RGN_NOLOCK. + */ +typedef int ncio_movefunc(ncio *const nciop, off_t to, off_t from, + size_t nbytes, int rflags); + + /* + * Write out any dirty buffers to disk and + * ensure that next read will get data from disk. + */ +typedef int ncio_syncfunc(ncio *const nciop); + +/* + * Sync any changes to disk, then truncate or extend file so its size + * is length. This is only intended to be called before close, if the + * file is open for writing and the actual size does not match the + * calculated size, perhaps as the result of having been previously + * written in NOFILL mode. + */ +typedef int ncio_pad_lengthfunc(ncio* nciop, off_t length); + +/* + * Get file size in bytes. + */ +typedef int ncio_filesizefunc(ncio *nciop, off_t *filesizep); + +/* Write out any dirty buffers and + ensure that next read will not get cached data. + Sync any changes, then close the open file associated with the ncio + struct, and free its memory. + nciop - pointer to ncio to close. + doUnlink - if true, unlink file +*/ +typedef int ncio_closefunc(ncio *nciop, int doUnlink); + +/* Get around cplusplus "const xxx in class ncio without constructor" error */ +#if defined(__cplusplus) +#define NCIO_CONST +#else +#define NCIO_CONST const +#endif + +/* + * netcdf i/o abstraction + */ +struct ncio { + /* + * A copy of the ioflags argument passed in to ncio_open() + * or ncio_create(). + */ + int ioflags; + + /* + * The file descriptor of the netcdf file. + * This gets handed to the user as the netcdf id. + */ + NCIO_CONST int fd; + + /* member functions do the work */ + + ncio_relfunc *NCIO_CONST rel; + + ncio_getfunc *NCIO_CONST get; + + ncio_movefunc *NCIO_CONST move; + + ncio_syncfunc *NCIO_CONST sync; + + ncio_pad_lengthfunc *NCIO_CONST pad_length; + + ncio_filesizefunc *NCIO_CONST filesize; + + ncio_closefunc *NCIO_CONST close; + + /* + * A copy of the 'path' argument passed in to ncio_open() + * or ncio_create(). Used by ncabort() to remove (unlink) + * the file and by error messages. + */ + const char *path; + + /* implementation private stuff */ + void *pvt; +}; + +#undef NCIO_CONST + +/* Define wrappers around the ncio dispatch table */ + +extern int ncio_rel(ncio* const, off_t, int); +extern int ncio_get(ncio* const, off_t, size_t, int, void** const); +extern int ncio_move(ncio* const, off_t, off_t, size_t, int); +extern int ncio_sync(ncio* const); +extern int ncio_filesize(ncio* const, off_t*); +extern int ncio_pad_length(ncio* const, off_t); +extern int ncio_close(ncio* const, int); + +extern int ncio_create(const char *path, int ioflags, size_t initialsz, + off_t igeto, size_t igetsz, size_t *sizehintp, + ncio** nciopp, void** const mempp); + +extern int ncio_open(const char *path, int ioflags, + off_t igeto, size_t igetsz, size_t *sizehintp, + ncio** nciopp, void** const mempp); + +/* With the advent of diskless io, we need to provide + for multiple ncio packages at the same time, + so we have multiple versions of ncio_create. + If you create a new package, the you must do the following. + 1. add an extern definition for it in ncio.c + 2. modify ncio_create and ncio_open in ncio.c to invoke + the new package when appropriate. +*/ + + + +#endif /* _NCIO_H_ */ diff --git a/extern/src_netcdf4/nclist.c b/extern/src_netcdf4/nclist.c new file mode 100644 index 0000000000000000000000000000000000000000..ffce2950c3f80e32def2ffbc5f1f88ca14663983 --- /dev/null +++ b/extern/src_netcdf4/nclist.c @@ -0,0 +1,224 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ +#include +#include +#include + +#include "nclist.h" + +static ncelem ncDATANULL = (ncelem)0; +/*static int ncinitialized=0;*/ + +int nclistnull(ncelem e) {return e == ncDATANULL;} + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define DEFAULTALLOC 16 +#define ALLOCINCR 16 + +NClist* nclistnew(void) +{ + NClist* l; +/* + if(!ncinitialized) { + memset((void*)&ncDATANULL,0,sizeof(ncelem)); + ncinitialized = 1; + } +*/ + l = (NClist*)malloc(sizeof(NClist)); + if(l) { + l->alloc=0; + l->length=0; + l->content=NULL; + } + return l; +} + +int +nclistfree(NClist* l) +{ + if(l) { + l->alloc = 0; + if(l->content != NULL) {free(l->content); l->content = NULL;} + free(l); + } + return TRUE; +} + +int +nclistsetalloc(NClist* l, unsigned int sz) +{ + ncelem* newcontent; + if(l == NULL) return FALSE; + if(sz <= 0) {sz = (l->length?2*l->length:DEFAULTALLOC);} + if(l->alloc >= sz) {return TRUE;} + newcontent=(ncelem*)calloc(sz,sizeof(ncelem)); + if(l->alloc > 0 && l->length > 0 && l->content != NULL) { + memcpy((void*)newcontent,(void*)l->content,sizeof(ncelem)*l->length); + } + if(l->content != NULL) free(l->content); + l->content=newcontent; + l->alloc=sz; + return TRUE; +} + +int +nclistsetlength(NClist* l, unsigned int sz) +{ + if(l == NULL) return FALSE; + if(sz > l->alloc && !nclistsetalloc(l,sz)) return FALSE; + l->length = sz; + return TRUE; +} + +ncelem +nclistget(NClist* l, unsigned int index) +{ + if(l == NULL || l->length == 0) return ncDATANULL; + if(index >= l->length) return ncDATANULL; + return l->content[index]; +} + +int +nclistset(NClist* l, unsigned int index, ncelem elem) +{ + if(l == NULL) return FALSE; + if(index >= l->length) return FALSE; + l->content[index] = elem; + return TRUE; +} + +/* Insert at position i of l; will push up elements i..|seq|. */ +int +nclistinsert(NClist* l, unsigned int index, ncelem elem) +{ + int i; /* do not make unsigned */ + if(l == NULL) return FALSE; + if(index > l->length) return FALSE; + nclistsetalloc(l,0); + for(i=(int)l->length;i>index;i--) l->content[i] = l->content[i-1]; + l->content[index] = elem; + l->length++; + return TRUE; +} + +int +nclistpush(NClist* l, ncelem elem) +{ + if(l == NULL) return FALSE; + if(l->length >= l->alloc) nclistsetalloc(l,0); + l->content[l->length] = elem; + l->length++; + return TRUE; +} + +ncelem +nclistpop(NClist* l) +{ + if(l == NULL || l->length == 0) return ncDATANULL; + l->length--; + return l->content[l->length]; +} + +ncelem +nclisttop(NClist* l) +{ + if(l == NULL || l->length == 0) return ncDATANULL; + return l->content[l->length - 1]; +} + +ncelem +nclistremove(NClist* l, unsigned int i) +{ + unsigned int len; + ncelem elem; + if(l == NULL || (len=l->length) == 0) return ncDATANULL; + if(i >= len) return ncDATANULL; + elem = l->content[i]; + for(i+=1;icontent[i-1] = l->content[i]; + l->length--; + return elem; +} + +/* Duplicate and return the content (null terminate) */ +ncelem* +nclistdup(NClist* l) +{ + ncelem* result = (ncelem*)malloc(sizeof(ncelem)*(l->length+1)); + memcpy((void*)result,(void*)l->content,sizeof(ncelem)*l->length); + result[l->length] = (ncelem)0; + return result; +} + +int +nclistcontains(NClist* list, ncelem elem) +{ + unsigned int i; + for(i=0;ilength) == 0) return ncDATANULL; + for(i=0;icontent[i]; + if(elem == candidate) { + for(i+=1;icontent[i-1] = l->content[i]; + l->length--; + found = 1; + break; + } + } + return found; +} + + + + +/* Extends nclist to include a unique operator + which remove duplicate values; NULL values removed + return value is always 1. +*/ + +int +nclistunique(NClist* list) +{ + unsigned int i,j,k,len; + ncelem* content; + if(list == NULL || list->length == 0) return 1; + len = list->length; + content = list->content; + for(i=0;ilength = len; + return 1; +} + +NClist* +nclistclone(NClist* list) +{ + NClist* clone = nclistnew(); + *clone = *list; + clone->content = nclistdup(list); + return clone; +} diff --git a/extern/src_netcdf4/nclist.h b/extern/src_netcdf4/nclist.h new file mode 100644 index 0000000000000000000000000000000000000000..260ddd01e6fadac439ebee4de392936243990ee5 --- /dev/null +++ b/extern/src_netcdf4/nclist.h @@ -0,0 +1,67 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ +#ifndef NCLIST_H +#define NCLIST_H 1 + +/* Define the type of the elements in the list*/ + +#if defined(_CPLUSPLUS_) || defined(__CPLUSPLUS__) +#define EXTERNC extern "C" +#else +#define EXTERNC extern +#endif + +typedef unsigned long ncelem; + +EXTERNC int nclistnull(ncelem); + +typedef struct NClist { + unsigned int alloc; + unsigned int length; + ncelem* content; +} NClist; + +EXTERNC NClist* nclistnew(void); +EXTERNC int nclistfree(NClist*); +EXTERNC int nclistsetalloc(NClist*,unsigned int); +EXTERNC int nclistsetlength(NClist*,unsigned int); + +/* Set the ith element */ +EXTERNC int nclistset(NClist*,unsigned int,ncelem); +/* Get value at position i */ +EXTERNC ncelem nclistget(NClist*,unsigned int);/* Return the ith element of l */ +/* Insert at position i; will push up elements i..|seq|. */ +EXTERNC int nclistinsert(NClist*,unsigned int,ncelem); +/* Remove element at position i; will move higher elements down */ +EXTERNC ncelem nclistremove(NClist* l, unsigned int i); + +/* Tail operations */ +EXTERNC int nclistpush(NClist*,ncelem); /* Add at Tail */ +EXTERNC ncelem nclistpop(NClist*); +EXTERNC ncelem nclisttop(NClist*); + +/* Duplicate and return the content (null terminate) */ +EXTERNC ncelem* nclistdup(NClist*); + +/* Look for value match */ +EXTERNC int nclistcontains(NClist*, ncelem); + +/* Remove element by value; only removes first encountered */ +EXTERNC int nclistelemremove(NClist* l, ncelem elem); + + +/* remove duplicates */ +EXTERNC int nclistunique(NClist*); + +/* Create a clone of a list */ +EXTERNC NClist* nclistclone(NClist*); + +/* Following are always "in-lined"*/ +#define nclistclear(l) nclistsetlength((l),0U) +#define nclistextend(l,len) nclistsetalloc((l),(len)+(l->alloc)) +#define nclistcontents(l) ((l)->content) +#define nclistlength(l) ((l)?(l)->length:0U) + +#endif /*NCLIST_H*/ + + diff --git a/extern/src_netcdf4/nclistmgr.c b/extern/src_netcdf4/nclistmgr.c new file mode 100644 index 0000000000000000000000000000000000000000..f4241f199009141266af52c9b764ddde1136e74d --- /dev/null +++ b/extern/src_netcdf4/nclistmgr.c @@ -0,0 +1,80 @@ +/********************************************************************* + Copyright 2010, UCAR/Unidata See netcdf/COPYRIGHT file for + copying and redistribution conditions. + *********************************************************************/ + +#include +#include +#include +#include +#include "nc.h" + +#define ID_SHIFT (16) +#define NCFILELISTLENGTH 0x10000 +/* Version one just allocates the max space (sizeof(NC*)*2^16)*/ +static NC** nc_filelist = NULL; + +static int numfiles = 0; + +/* Common */ +int +count_NCList(void) +{ + return numfiles; +} + + +void +free_NCList(void) +{ + if(numfiles > 0) return; /* not empty */ + if(nc_filelist != NULL) free(nc_filelist); + nc_filelist = NULL; +} + +int +add_to_NCList(NC* ncp) +{ + int i; + int new_id; + if(nc_filelist == NULL) { + if (!(nc_filelist = calloc(1, sizeof(NC*)*NCFILELISTLENGTH))) + return NC_ENOMEM; + numfiles = 0; + } + new_id = 0; /* id's begin at 1 */ + for(i=1;i<0x10000;i++) { + if(nc_filelist[i] == NULL) {new_id = i; break;} + } + if(new_id == 0) return NC_ENOMEM; /* no more slots */ + nc_filelist[new_id] = ncp; + numfiles++; + new_id = (new_id << ID_SHIFT); + ncp->ext_ncid = new_id; + return NC_NOERR; +} + +void +del_from_NCList(NC* ncp) +{ + unsigned int ncid = ((unsigned int)ncp->ext_ncid) >> ID_SHIFT; + if(numfiles == 0 || ncid == 0 || nc_filelist == NULL) return; + if(nc_filelist[ncid] != ncp) return; + nc_filelist[ncid] = NULL; + numfiles--; + + /* If all files have been closed, release the filelist memory. */ + if (numfiles == 0) + free_NCList(); +} + +NC * +find_in_NCList(int ext_ncid) +{ + NC* f = NULL; + unsigned int ncid = ((unsigned int)ext_ncid) >> ID_SHIFT; + if(numfiles > 0 && nc_filelist != NULL && ncid < NCFILELISTLENGTH) + f = nc_filelist[ncid]; + return f; +} + diff --git a/extern/src_netcdf4/nclog.h b/extern/src_netcdf4/nclog.h new file mode 100644 index 0000000000000000000000000000000000000000..1284b6bae1693cc6a6f9cc7cae30e394839eac3d --- /dev/null +++ b/extern/src_netcdf4/nclog.h @@ -0,0 +1,31 @@ +/********************************************************************* + * Copyright 2010, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header$ + *********************************************************************/ + +#ifndef NCLOG_H +#define NCLOG_H + +#define ENVFLAG "NCLOGFILE" + +/* Suggested tag values */ +#define NCLOGNOTE 0 +#define NCLOGWARN 1 +#define NCLOGERR 2 +#define NCLOGDBG 3 + +extern void ncloginit(void); +extern void ncsetlogging(int tf); +extern void nclogopen(const char* file); +extern void nclogclose(void); + +/* The tag value is an arbitrary integer */ +extern void nclog(int tag, const char* fmt, ...); +extern void nclogtext(int tag, const char* text); +extern void nclogtextn(int tag, const char* text, size_t count); + +/* Provide printable names for tags */ +extern void nclogsettags(char** tagset, char* dfalt); + +#endif /*NCLOG_H*/ diff --git a/extern/src_netcdf4/nctime.c b/extern/src_netcdf4/nctime.c new file mode 100644 index 0000000000000000000000000000000000000000..e21d920c2769f79e29e611ad78b115fe5fe8e3c4 --- /dev/null +++ b/extern/src_netcdf4/nctime.c @@ -0,0 +1,1169 @@ +/********************************************************************* + * Copyright 2008, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Id: nctime.c,v 1.9 2010/05/05 22:15:39 dmh Exp $ + *********************************************************************/ + +/* + * This code was extracted with permission from the CDMS time + * conversion and arithmetic routines developed by Bob Drach, Lawrence + * Livermore National Laboratory as part of the cdtime library. Russ + * Rew of the UCAR Unidata Program made changes and additions to + * support the "-t" option of the netCDF ncdump utility, including a + * 366-day climate calendar. + * + * For the complete time conversion and climate calendar facilities of + * the CDMS library, get the original sources from LLNL. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "nctime.h" + +static int cuErrOpts; /* Error options */ +static int cuErrorOccurred = 0; /* True iff cdError was called */ + +#define CU_FATAL 1 /* Exit immediately on fatal error */ +#define CU_VERBOSE 2 /* Report errors */ + +#define CD_DEFAULT_BASEYEAR "1979" /* Default base year for relative time (no 'since' clause) */ +#define VALCMP(a,b) ((a)<(b)?-1:(b)<(a)?1:0) + +/* forward declarations */ +static void cdComp2Rel(cdCalenType timetype, cdCompTime comptime, char* relunits, double* reltime); +static void cdRel2CompMixed(double reltime, cdUnitTime unit, cdCompTime basetime, cdCompTime *comptime); +static void cdRel2Comp(cdCalenType timetype, char* relunits, double reltime, cdCompTime* comptime); + +/* Trim trailing whitespace, up to n characters. */ +/* If no whitespace up to the last character, set */ +/* the last character to null, else set the first */ +/* whitespace character to null. */ +static void +cdTrim(char* s, int n) +{ + char* c; + + if(s==NULL) + return; + for(c=s; *c && cyear (long) (year since 0 BC) + * date->timeType (CdTimetype) (time type) + * date->baseYear base year for relative times + * Output: + * date->month (short) (month in year) + * date->day (short) (day in month) + * + * + * Derived from NRL NEONS V3.6. + */ + +static void +CdMonthDay(int *doy, CdTime *date) +{ + int i; /* month counter */ + int idoy; /* day of year counter */ + long year; + + if ((idoy = *doy) < 1) { + date->month = 0; + date->day = 0; + return; + } + + if(!(date->timeType & CdChronCal)) /* Ignore year for Clim calendar */ + year = 0; + else if(!(date->timeType & CdBase1970)) /* year is offset from base for relative time */ + year = date->baseYear + date->year; + else + year = date->year; + + if (ISLEAP(year,date->timeType)) { + mon_day_cnt[1] = 29; + } else { + mon_day_cnt[1] = 28; + } + date->month = 0; + for (i = 0; i < 12; i++) { + (date->month)++; + date->day = idoy; + if ((idoy -= ((date->timeType & Cd365) ? (mon_day_cnt[date->month-1]) : 30)) <= 0) { + return; + } + } + return; +} + +/* Compute day-of-year from year, month and day + * + * Input: + * date->year (long) (year since 0 BC) + * date->month (short) (month in year) + * date->day (short) (day in month) + * date->baseYear base year for relative times + * Output: doy (int) (day-of-year) + * + * Derived from NRL NEONS V3.6 + */ + +static void +CdDayOfYear(CdTime *date, int *doy) +{ + int leap_add = 0; /* add 1 day if leap year */ + int month; /* month */ + long year; + + month = date->month; + if (month < 1 || month > 12) { + cdError( "Day-of-year error; month: %d\n", month); + month = 1; + } + + if(!(date->timeType & CdChronCal)) /* Ignore year for Clim calendar */ + year = 0; + else if(!(date->timeType & CdBase1970)) /* year is offset from base for relative time */ + year = date->baseYear + date->year; + else + year = date->year; + + if (ISLEAP(year,date->timeType) && month > 2) leap_add = 1; + if( ((date->timeType) & Cd365) || ((date->timeType) & Cd366) ) { + *doy = days_sum[month-1] + date->day + leap_add ; + } else { /* date->timeType & Cd360 */ + *doy = 30*(month-1) + date->day + leap_add ; + } + return; +} + +/* Convert epochal time (hours since 00 jan 1, 1970) + * to human time (structured) + * + * Input: + * etime = epochal time representation + * timeType = time type (e.g., CdChron, CdClim, etc.) as defined in cdms.h + * baseYear = base real, used for relative time types only + * + * Output: htime = human (structured) time representation + * + * Derived from NRL Neons V3.6 + */ +void +Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime) +{ + long ytemp; /* temporary year holder */ + int yr_day_cnt; /* count of days in year */ + int doy; /* day of year */ + int daysInLeapYear; /* number of days in a leap year */ + int daysInYear; /* days in non-leap year */ + extern void CdMonthDay(int *doy, CdTime *date); + + doy = (long) floor(etime / 24.) + 1; + htime->hour = etime - (double) (doy - 1) * 24.; + + /* Correct for goofy floor func on J90 */ + if(htime->hour >= 24.){ + doy += 1; + htime->hour -= 24.; + } + + htime->baseYear = (timeType & CdBase1970) ? 1970 : baseYear; + if(!(timeType & CdChronCal)) htime->baseYear = 0; /* Set base year to 0 for Clim */ + if(timeType & Cd366) { + daysInLeapYear = 366; + daysInYear = 366; + } else { + daysInLeapYear = (timeType & Cd365) ? 366 : 360; + daysInYear = (timeType & Cd365) ? 365 : 360; + } + + if (doy > 0) { + for (ytemp = htime->baseYear; ; ytemp++) { + yr_day_cnt = ISLEAP(ytemp,timeType) ? daysInLeapYear : daysInYear; + if (doy <= yr_day_cnt) break; + doy -= yr_day_cnt; + } + } else { + for (ytemp = htime->baseYear-1; ; ytemp--) { + yr_day_cnt = ISLEAP(ytemp,timeType) ? daysInLeapYear : daysInYear; + doy += yr_day_cnt; + if (doy > 0) break; + } + } + htime->year = (timeType & CdBase1970) ? ytemp : (ytemp - htime->baseYear); + if(!(timeType & CdChronCal)) htime->year = 0; /* Set year to 0 for Clim */ + htime->timeType = timeType; + CdMonthDay(&doy,htime); + + return; +} + +/* Add 'nDel' times 'delTime' to epochal time 'begEtm', + * return the result in epochal time 'endEtm'. + */ +static void +CdAddDelTime(double begEtm, long nDel, CdDeltaTime delTime, CdTimeType timeType, + long baseYear, double *endEtm) +{ + double delHours; + long delMonths, delYears; + CdTime bhtime, ehtime; + + extern void Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime); + extern void Cdh2e(CdTime *htime, double *etime); + + switch(delTime.units){ + case CdYear: + delMonths = 12; + break; + case CdSeason: + delMonths = 3; + break; + case CdMonth: + delMonths = 1; + break; + case CdWeek: + delHours = 168.0; + break; + case CdDay: + delHours = 24.0; + break; + case CdHour: + delHours = 1.0; + break; + case CdMinute: + delHours = 1./60.; + break; + case CdSecond: + delHours = 1./3600.; + break; + default: + cdError("Invalid delta time units: %d\n",delTime.units); + return; + } + + switch(delTime.units){ + case CdYear: case CdSeason: case CdMonth: + Cde2h(begEtm,timeType,baseYear,&bhtime); + delMonths = delMonths * nDel * delTime.count + bhtime.month - 1; + delYears = (delMonths >= 0 ? (delMonths/12) : (delMonths+1)/12 - 1); + ehtime.year = bhtime.year + delYears; + ehtime.month = delMonths - (12 * delYears) + 1; + ehtime.day = 1; + ehtime.hour = 0.0; + ehtime.timeType = timeType; + ehtime.baseYear = !(timeType & CdChronCal) ? 0 : + (timeType & CdBase1970) ? 1970 : baseYear; /* base year is 0 for Clim, */ + /* 1970 for Chron, */ + /* or input base year for Rel */ + Cdh2e(&ehtime,endEtm); + break; + case CdWeek: case CdDay: case CdHour: case CdMinute: case CdSecond: + delHours *= (nDel * delTime.count); + *endEtm = begEtm + delHours; + break; + default: break; + } + return; +} + +/* Parse relative units, returning the unit and base component time. */ +/* Function returns 1 if error, 0 on success */ +int +cdParseRelunits(cdCalenType timetype, char* relunits, cdUnitTime* unit, cdCompTime* base_comptime) +{ + char charunits[CD_MAX_RELUNITS]; + char basetime_1[CD_MAX_CHARTIME]; + char basetime_2[CD_MAX_CHARTIME]; + char basetime[CD_MAX_CHARTIME]; + int nconv1, nconv2, nconv; + + /* Parse the relunits */ + /* Allow ISO-8601 "T" date-time separator as well as blank separator */ + nconv1 = sscanf(relunits,"%s since %[^T]T%s",charunits,basetime_1,basetime_2); + if(nconv1==EOF || nconv1==0){ + cdError("Error on relative units conversion, string = %s\n",relunits); + return 1; + } + nconv2 = sscanf(relunits,"%s since %s %s",charunits,basetime_1,basetime_2); + if(nconv2==EOF || nconv2==0){ + cdError("Error on relative units conversion, string = %s\n",relunits); + return 1; + } + if(nconv1 < nconv2) { + nconv = nconv2; + } else { + nconv = sscanf(relunits,"%s since %[^T]T%s",charunits,basetime_1,basetime_2); + } + /* Get the units */ + cdTrim(charunits,CD_MAX_RELUNITS); + if(!strncmp(charunits,"sec",3) || !strcmp(charunits,"s")){ + *unit = cdSecond; + } + else if(!strncmp(charunits,"min",3) || !strcmp(charunits,"mn")){ + *unit = cdMinute; + } + else if(!strncmp(charunits,"hour",4) || !strcmp(charunits,"hr")){ + *unit = cdHour; + } + else if(!strncmp(charunits,"day",3) || !strcmp(charunits,"dy")){ + *unit = cdDay; + } + else if(!strncmp(charunits,"week",4) || !strcmp(charunits,"wk")){ + *unit = cdWeek; + } + else if(!strncmp(charunits,"month",5) || !strcmp(charunits,"mo")){ + *unit = cdMonth; + } + else if(!strncmp(charunits,"season",6)){ + *unit = cdSeason; + } + else if(!strncmp(charunits,"year",4) || !strcmp(charunits,"yr")){ + if(!(timetype & cdStandardCal)){ + cdError("Error on relative units conversion: climatological units cannot be 'years'.\n"); + return 1; + } + *unit = cdYear; + } + else { + cdError("Error on relative units conversion: invalid units = %s\n",charunits); + return 1; + } + + /* Build the basetime, if any (default is 1979), */ + /* or month 1 for climatological time. */ + if(nconv == 1){ + if(timetype & cdStandardCal) + strcpy(basetime,CD_DEFAULT_BASEYEAR); + else + strcpy(basetime,"1"); + } + /* Convert the basetime to component, then epochal (hours since 1970) */ + else{ + if(nconv == 2){ + cdTrim(basetime_1,CD_MAX_CHARTIME); + strcpy(basetime,basetime_1); + } + else{ + cdTrim(basetime_1,CD_MAX_CHARTIME); + cdTrim(basetime_2,CD_MAX_CHARTIME); + sprintf(basetime,"%s %s",basetime_1,basetime_2); + } + } + + cdChar2Comp(timetype, basetime, base_comptime); + + return 0; +} + +/* ca - cb in Gregorian calendar */ +/* Result is in hours. */ +static double +cdDiffGregorian(cdCompTime ca, cdCompTime cb){ + + double rela, relb; + + cdComp2Rel(cdStandard, ca, "hours", &rela); + cdComp2Rel(cdStandard, cb, "hours", &relb); + return (rela - relb); +} + +/* Return -1, 0, 1 as ca is less than, equal to, */ +/* or greater than cb, respectively. */ +static int +cdCompCompare(cdCompTime ca, cdCompTime cb){ + + int test; + + if ((test = VALCMP(ca.year, cb.year))) + return test; + else if ((test = VALCMP(ca.month, cb.month))) + return test; + else if ((test = VALCMP(ca.day, cb.day))) + return test; + else + return (VALCMP(ca.hour, cb.hour)); +} + +/* ca - cb in Julian calendar. Result is in hours. */ +static double +cdDiffJulian(cdCompTime ca, cdCompTime cb){ + + double rela, relb; + + cdComp2Rel(cdJulian, ca, "hours", &rela); + cdComp2Rel(cdJulian, cb, "hours", &relb); + return (rela - relb); +} + +/* ca - cb in mixed Julian/Gregorian calendar. */ +/* Result is in hours. */ +static double +cdDiffMixed(cdCompTime ca, cdCompTime cb){ + + static cdCompTime ZA = {1582, 10, 5, 0.0}; + static cdCompTime ZB = {1582, 10, 15, 0.0}; + double result; + + if (cdCompCompare(cb, ZB) == -1){ + if (cdCompCompare(ca, ZB) == -1) { + result = cdDiffJulian(ca, cb); + } + else { + result = cdDiffGregorian(ca, ZB) + cdDiffJulian(ZA, cb); + } + } + else { + if (cdCompCompare(ca, ZB) == -1){ + result = cdDiffJulian(ca, ZA) + cdDiffGregorian(ZB, cb); + } + else { + result = cdDiffGregorian(ca, cb); + } + } + return result; +} + +/* Divide ('endEtm' - 'begEtm') by 'delTime', + * return the integer portion of the result in 'nDel'. + */ +static void +CdDivDelTime(double begEtm, double endEtm, CdDeltaTime delTime, CdTimeType timeType, + long baseYear, long *nDel) +{ + double delHours, frange; + long delMonths, range; + CdTime bhtime, ehtime; + int hoursInYear; + + extern void Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime); + + switch(delTime.units){ + case CdYear: + delMonths = 12; + break; + case CdSeason: + delMonths = 3; + break; + case CdMonth: + delMonths = 1; + break; + case CdWeek: + delHours = 168.0; + break; + case CdDay: + delHours = 24.0; + break; + case CdHour: + delHours = 1.0; + break; + case CdMinute: + delHours = 1./60.; + break; + case CdSecond: + delHours = 1./3600.; + break; + default: + cdError("Invalid delta time units: %d\n",delTime.units); + return; + } + + switch(delTime.units){ + case CdYear: case CdSeason: case CdMonth: + delMonths *= delTime.count; + Cde2h(begEtm,timeType,baseYear,&bhtime); + Cde2h(endEtm,timeType,baseYear,&ehtime); + if(timeType & CdChronCal){ /* Chron and Rel time */ + range = 12*(ehtime.year - bhtime.year) + + (ehtime.month - bhtime.month); + } + else{ /* Clim time, ignore year */ + range = (ehtime.month - bhtime.month); + if(range < 0) range += 12; + } + *nDel = abs(range)/delMonths; + break; + case CdWeek: case CdDay: case CdHour: case CdMinute: case CdSecond: + delHours *= (double)delTime.count; + if(timeType & CdChronCal){ /* Chron and Rel time */ + frange = fabs(endEtm - begEtm); + } + else{ /* Clim time, ignore year, but */ + /* wraparound relative to hours-in-year*/ + frange = endEtm - begEtm; + if(timeType & Cd366) { + hoursInYear = 8784; + } else { + hoursInYear = (timeType & Cd365) ? 8760. : 8640.; + } + /* Normalize frange to interval [0,hoursInYear) */ + if(frange < 0.0 || frange >= hoursInYear) + frange -= hoursInYear * floor(frange/hoursInYear); + } + *nDel = (frange + 1.e-10*delHours)/delHours; + break; + default: break; + } + return; +} + +/* Value is in hours. Translate to units. */ +static double +cdFromHours(double value, cdUnitTime unit){ + double result; + + switch(unit){ + case cdSecond: + result = value * 3600.0; + break; + case cdMinute: + result = value * 60.0; + break; + case cdHour: + result = value; + break; + case cdDay: + result = value/24.0; + break; + case cdWeek: + result = value/168.0; + break; + case cdMonth: + case cdSeason: + case cdYear: + case cdFraction: + default: + cdError("Error on conversion from hours to vague unit"); + result = 0; + break; + } + return result; +} + /* Map to old timetypes */ +static int +cdToOldTimetype(cdCalenType newtype, CdTimeType* oldtype) +{ + switch(newtype){ + case cdStandard: + *oldtype = CdChron; + break; + case cdJulian: + *oldtype = CdJulianCal; + break; + case cdNoLeap: + *oldtype = CdChronNoLeap; + break; + case cd360: + *oldtype = CdChron360; + break; + case cd366: + *oldtype = CdChron366; + break; + case cdClim: + *oldtype = CdClim; + break; + case cdClimLeap: + *oldtype = CdClimLeap; + break; + case cdClim360: + *oldtype = CdClim360; + break; + default: + cdError("Error on relative units conversion, invalid timetype = %d",newtype); + return 1; + } + return 0; +} + +/* Convert human time to epochal time (hours since 00 jan 1, 1970) + * + * Input: htime = human time representation + * + * Output: etime = epochal time representation + * + * Derived from NRL Neons V3.6 + */ +void +Cdh2e(CdTime *htime, double *etime) +{ + long ytemp, year; /* temporary year holder */ + int day_cnt; /* count of days */ + int doy; /* day of year */ + long baseYear; /* base year for epochal time */ + int daysInLeapYear; /* number of days in a leap year */ + int daysInYear; /* days in non-leap year */ + extern void CdDayOfYear(CdTime *date, int *doy); + + CdDayOfYear(htime,&doy); + + day_cnt = 0; + + baseYear = ((htime->timeType) & CdBase1970) ? 1970 : htime->baseYear; + year = ((htime->timeType) & CdBase1970) ? htime->year : (htime->year + htime->baseYear); + if(!((htime->timeType) & CdChronCal)) baseYear = year = 0; /* set year and baseYear to 0 for Clim */ + if((htime->timeType) & Cd366) { + daysInLeapYear = 366; + daysInYear = 366; + } else { + daysInLeapYear = ((htime->timeType) & Cd365) ? 366 : 360; + daysInYear = ((htime->timeType) & Cd365) ? 365 : 360; + } + + if (year > baseYear) { + for (ytemp = year - 1; ytemp >= baseYear; ytemp--) { + day_cnt += ISLEAP(ytemp,htime->timeType) ? daysInLeapYear : daysInYear; + } + } else if (year < baseYear) { + for (ytemp = year; ytemp < baseYear; ytemp++) { + day_cnt -= ISLEAP(ytemp,htime->timeType) ? daysInLeapYear : daysInYear; + } + } + *etime = (double) (day_cnt + doy - 1) * 24. + htime->hour; + return; +} + +/* Validate the component time, return 0 if valid, 1 if not */ +static int +cdValidateTime(cdCalenType timetype, cdCompTime comptime) +{ + if(comptime.month<1 || comptime.month>12){ + cdError("Error on time conversion: invalid month = %hd\n",comptime.month); + return 1; + } + if(comptime.day<1 || comptime.day>31){ + cdError("Error on time conversion: invalid day = %hd\n",comptime.day); + return 1; + } + if(comptime.hour<0.0 || comptime.hour>24.0){ + cdError("Error on time conversion: invalid hour = %lf\n",comptime.hour); + return 1; + } + return 0; +} + +void +cdChar2Comp(cdCalenType timetype, char* chartime, cdCompTime* comptime) +{ + double sec; + int ihr, imin, nconv; + long year; + short day; + short month; + + comptime->year = CD_NULL_YEAR; + comptime->month = CD_NULL_MONTH; + comptime->day = CD_NULL_DAY; + comptime->hour = CD_NULL_HOUR; + + if(timetype & cdStandardCal){ + nconv = sscanf(chartime,"%ld-%hd-%hd %d:%d:%lf",&year,&month,&day,&ihr,&imin,&sec); + if(nconv==EOF || nconv==0){ + cdError("Error on character time conversion, string = %s\n",chartime); + return; + } + if(nconv >= 1){ + comptime->year = year; + } + if(nconv >= 2){ + comptime->month = month; + } + if(nconv >= 3){ + comptime->day = day; + } + if(nconv >= 4){ + if(ihr<0 || ihr>23){ + cdError("Error on character time conversion: invalid hour = %d\n",ihr); + return; + } + comptime->hour = (double)ihr; + } + if(nconv >= 5){ + if(imin<0 || imin>59){ + cdError("Error on character time conversion: invalid minute = %d\n",imin); + return; + } + comptime->hour += (double)imin/60.; + } + if(nconv >= 6){ + if(sec<0.0 || sec>60.0){ + cdError("Error on character time conversion: invalid second = %lf\n",sec); + return; + } + comptime->hour += sec/3600.; + } + } + else{ /* Climatological */ + nconv = sscanf(chartime,"%hd-%hd %d:%d:%lf",&month,&day,&ihr,&imin,&sec); + if(nconv==EOF || nconv==0){ + cdError("Error on character time conversion, string = %s",chartime); + return; + } + if(nconv >= 1){ + comptime->month = month; + } + if(nconv >= 2){ + comptime->day = day; + } + if(nconv >= 3){ + if(ihr<0 || ihr>23){ + cdError("Error on character time conversion: invalid hour = %d\n",ihr); + return; + } + comptime->hour = (double)ihr; + } + if(nconv >= 4){ + if(imin<0 || imin>59){ + cdError("Error on character time conversion: invalid minute = %d\n",imin); + return; + } + comptime->hour += (double)imin/60.; + } + if(nconv >= 5){ + if(sec<0.0 || sec>60.0){ + cdError("Error on character time conversion: invalid second = %lf\n",sec); + return; + } + comptime->hour += sec/3600.; + } + } + (void)cdValidateTime(timetype,*comptime); + return; +} + +/* Convert ct to relunits (unit, basetime) */ +/* in the mixed Julian/Gregorian calendar. */ +/* unit is anything but year, season, month. unit and basetime are */ +/* from the parsed relunits. Return result in reltime. */ +static void +cdComp2RelMixed(cdCompTime ct, cdUnitTime unit, cdCompTime basetime, double *reltime){ + + double hourdiff; + + hourdiff = cdDiffMixed(ct, basetime); + *reltime = cdFromHours(hourdiff, unit); + return; +} + +static void +cdComp2Rel(cdCalenType timetype, cdCompTime comptime, char* relunits, double* reltime) +{ + cdCompTime base_comptime; + CdDeltaTime deltime; + CdTime humantime; + CdTimeType old_timetype; + cdUnitTime unit; + double base_etm, etm, delta; + long ndel, hoursInYear; + + /* Parse the relunits */ + if(cdParseRelunits(timetype, relunits, &unit, &base_comptime)) + return; + + /* Handle mixed Julian/Gregorian calendar */ + if (timetype == cdMixed){ + switch(unit){ + case cdWeek: case cdDay: case cdHour: case cdMinute: case cdSecond: + cdComp2RelMixed(comptime, unit, base_comptime, reltime); + return; + case cdYear: case cdSeason: case cdMonth: + timetype = cdStandard; + break; + case cdFraction: + cdError("invalid unit in conversion"); + break; + default: break; + } + } + + /* Convert basetime to epochal */ + humantime.year = base_comptime.year; + humantime.month = base_comptime.month; + humantime.day = base_comptime.day; + humantime.hour = base_comptime.hour; + humantime.baseYear = 1970; + /* Map to old-style timetype */ + if(cdToOldTimetype(timetype,&old_timetype)) + return; + humantime.timeType = old_timetype; + Cdh2e(&humantime,&base_etm); + + /* Map end time to epochal */ + humantime.year = comptime.year; + humantime.month = comptime.month; + humantime.day = comptime.day; + humantime.hour = comptime.hour; + Cdh2e(&humantime,&etm); + /* Calculate relative time value for months or hours */ + deltime.count = 1; + deltime.units = (CdTimeUnit)unit; + switch(unit){ + case cdWeek: case cdDay: case cdHour: case cdMinute: case cdSecond: + delta = etm - base_etm; + if(!(timetype & cdStandardCal)){ /* Climatological time */ + hoursInYear = (timetype & cd365Days) ? 8760. : (timetype & cdHasLeap) ? 8784. : 8640.; + /* Normalize delta to interval [0,hoursInYear) */ + if(delta < 0.0 || delta >= hoursInYear) + delta -= hoursInYear * floor(delta/hoursInYear); + } + break; + case cdYear: case cdSeason: case cdMonth: + CdDivDelTime(base_etm, etm, deltime, old_timetype, 1970, &ndel); + break; + case cdFraction: + cdError("invalid unit in conversion"); + break; + default: break; + } + + /* Convert to output units */ + switch(unit){ + case cdSecond: + *reltime = 3600.0 * delta; + break; + case cdMinute: + *reltime = 60.0 * delta; + break; + case cdHour: + *reltime = delta; + break; + case cdDay: + *reltime = delta/24.0; + break; + case cdWeek: + *reltime = delta/168.0; + break; + case cdMonth: case cdSeason: case cdYear: /* Already in correct units */ + if(timetype & cdStandardCal) + *reltime = (base_etm <= etm) ? (double)ndel : (double)(-ndel); + else /* Climatological time is already normalized*/ + *reltime = (double)ndel; + break; + default: + cdError("invalid unit in conversion"); + break; + } + + return; +} + +/* Add (value,unit) to comptime. */ +/* value is in hours. */ +/* calendar is anything but cdMixed. */ +static void +cdCompAdd(cdCompTime comptime, double value, cdCalenType calendar, cdCompTime *result){ + + double reltime; + + cdComp2Rel(calendar, comptime, "hours", &reltime); + reltime += value; + cdRel2Comp(calendar, "hours", reltime, result); + return; +} + +/* Add value in hours to ct, in the mixed Julian/Gregorian + * calendar. */ +static void +cdCompAddMixed(cdCompTime ct, double value, cdCompTime *result){ + + static cdCompTime ZA = {1582, 10, 5, 0.0}; + static cdCompTime ZB = {1582, 10, 15, 0.0}; + double xj, xg; + + if (cdCompCompare(ct, ZB) == -1){ + xj = cdDiffJulian(ZA, ct); + if (value <= xj){ + cdCompAdd(ct, value, cdJulian, result); + } + else { + cdCompAdd(ZB, value-xj, cdStandard, result); + } + } + else { + xg = cdDiffGregorian(ZB, ct); + if (value > xg){ + cdCompAdd(ct, value, cdStandard, result); + } + else { + cdCompAdd(ZA, value-xg, cdJulian, result); + } + } + return; +} + +/* Return value expressed in hours. */ +static double +cdToHours(double value, cdUnitTime unit){ + + double result = 0; + + switch(unit){ + case cdSecond: + result = value/3600.0; + break; + case cdMinute: + result = value/60.0; + break; + case cdHour: + result = value; + break; + case cdDay: + result = 24.0 * value; + break; + case cdWeek: + result = 168.0 * value; + break; + default: + cdError("invalid unit in conversion"); + break; + + } + return result; +} + +/* Convert relative time (reltime, unit, basetime) to comptime in the + * mixed Julian/Gregorian calendar. unit is anything but year, season, + * month. unit and basetime are from the parsed relunits. Return + * result in comptime. */ +static void +cdRel2CompMixed(double reltime, cdUnitTime unit, cdCompTime basetime, cdCompTime *comptime){ + + reltime = cdToHours(reltime, unit); + cdCompAddMixed(basetime, reltime, comptime); + return; +} + + +static void +cdRel2Comp(cdCalenType timetype, char* relunits, double reltime, cdCompTime* comptime) +{ + CdDeltaTime deltime; + CdTime humantime; + CdTimeType old_timetype; + cdCompTime base_comptime; + cdUnitTime unit, baseunits; + double base_etm, result_etm; + double delta; + long idelta; + + /* Parse the relunits */ + if(cdParseRelunits(timetype, relunits, &unit, &base_comptime)) + return; + + if (timetype == cdMixed){ + switch(unit){ + case cdWeek: case cdDay: case cdHour: case cdMinute: case cdSecond: + cdRel2CompMixed(reltime, unit, base_comptime, comptime); + return; + case cdYear: case cdSeason: case cdMonth: + timetype = cdStandard; + break; + case cdFraction: + cdError("invalid unit in conversion"); + break; + default: break; + } + } + + baseunits =cdBadUnit; + switch(unit){ + case cdSecond: + delta = reltime/3600.0; + baseunits = cdHour; + break; + case cdMinute: + delta = reltime/60.0; + baseunits = cdHour; + break; + case cdHour: + delta = reltime; + baseunits = cdHour; + break; + case cdDay: + delta = 24.0 * reltime; + baseunits = cdHour; + break; + case cdWeek: + delta = 168.0 * reltime; + baseunits = cdHour; + break; + case cdMonth: + idelta = (long)(reltime + (reltime<0 ? -1.e-10 : 1.e-10)); + baseunits = cdMonth; + break; + case cdSeason: + idelta = (long)(3.0 * reltime + (reltime<0 ? -1.e-10 : 1.e-10)); + baseunits = cdMonth; + break; + case cdYear: + idelta = (long)(12 * reltime + (reltime<0 ? -1.e-10 : 1.e-10)); + baseunits = cdMonth; + break; + default: + cdError("invalid unit in conversion"); + break; + } + + deltime.count = 1; + deltime.units = (CdTimeUnit)baseunits; + + humantime.year = base_comptime.year; + humantime.month = base_comptime.month; + humantime.day = base_comptime.day; + humantime.hour = base_comptime.hour; + humantime.baseYear = 1970; + /* Map to old-style timetype */ + if(cdToOldTimetype(timetype,&old_timetype)) + return; + humantime.timeType = old_timetype; + + Cdh2e(&humantime,&base_etm); + /* If months, seasons, or years, */ + if(baseunits == cdMonth){ + + /* Calculate new epochal time from integer months. */ + /* Convert back to human, then comptime. */ + /* For zero reltime, just return the basetime*/ + if(reltime != 0.0){ + CdAddDelTime(base_etm,idelta,deltime,old_timetype,1970,&result_etm); + Cde2h(result_etm, old_timetype, 1970, &humantime); + } + } + /* Calculate new epochal time. */ + /* Convert back to human, then comptime. */ + else if(baseunits == cdHour){ + Cde2h(base_etm+delta, old_timetype, 1970, &humantime); + + } + comptime->year = humantime.year; + comptime->month = humantime.month; + comptime->day = humantime.day; + comptime->hour = humantime.hour; + + return; +} + +/* rkr: output as ISO 8601 strings */ +static void +cdComp2Iso(cdCalenType timetype, int separator, cdCompTime comptime, char* time) +{ + double dtmp, sec; + int ihr, imin, isec; + int nskip; + + if(cdValidateTime(timetype,comptime)) + return; + + ihr = (int)comptime.hour; + dtmp = 60.0 * (comptime.hour - (double)ihr); + imin = (int)dtmp; + sec = 60.0 * (dtmp - (double)imin); + isec = sec; + + if(sec == isec) + if(isec == 0) + if(imin == 0) + if(ihr == 0) + nskip = 4; + else + nskip = 3; + else + nskip = 2; + else + nskip = 1; + else + nskip = 0; + + if(timetype & cdStandardCal){ + switch (nskip) { + case 0: /* sec != 0 && (int)sec != sec */ + sprintf(time,"%4.4ld-%2.2hd-%2.2hd%c%2.2d:%2.2d:%lf", + comptime.year,comptime.month,comptime.day,separator,ihr,imin,sec); + break; + case 1: + sprintf(time,"%4.4ld-%2.2hd-%2.2hd%c%2.2d:%2.2d:%2.2d", + comptime.year,comptime.month,comptime.day,separator,ihr,imin,isec); + break; + case 2: + sprintf(time,"%4.4ld-%2.2hd-%2.2hd%c%2.2d:%2.2d", + comptime.year,comptime.month,comptime.day,separator,ihr,imin); + break; + case 3: + sprintf(time,"%4.4ld-%2.2hd-%2.2hd%c%2.2d", + comptime.year,comptime.month,comptime.day,separator,ihr); + break; + case 4: + sprintf(time,"%4.4ld-%2.2hd-%2.2hd", + comptime.year,comptime.month,comptime.day); + break; + } + } + else { /* Climatological */ + switch (nskip) { + case 0: /* sec != 0 && (int)sec != sec */ + sprintf(time,"%2.2hd-%2.2hd%c%2.2d:%2.2d:%lf", + comptime.month,comptime.day,separator,ihr,imin,sec); + break; + case 1: + sprintf(time,"%2.2hd-%2.2hd%c%2.2d:%2.2d:%2.2d", + comptime.month,comptime.day,separator,ihr,imin,isec); + break; + case 2: + sprintf(time,"%2.2hd-%2.2hd%c%2.2d:%2.2d", + comptime.month,comptime.day,separator,ihr,imin); + break; + case 3: + sprintf(time,"%2.2hd-%2.2hd%c%2.2d", + comptime.month,comptime.day,separator,ihr); + break; + case 4: + sprintf(time,"%2.2hd-%2.2hd", + comptime.month,comptime.day); + break; + } + } + return; +} + +/* rkr: added for output closer to ISO 8601 */ +void +cdRel2Iso(cdCalenType timetype, char* relunits, int separator, double reltime, char* chartime) +{ + cdCompTime comptime; + + cdRel2Comp(timetype, relunits, reltime, &comptime); + cdComp2Iso(timetype, separator, comptime, chartime); + + return; +} diff --git a/extern/src_netcdf4/nctime.h b/extern/src_netcdf4/nctime.h new file mode 100644 index 0000000000000000000000000000000000000000..ee5c275c208337a4e7a98edc9d4d7ce0c364f0b6 --- /dev/null +++ b/extern/src_netcdf4/nctime.h @@ -0,0 +1,159 @@ +/********************************************************************* + * Copyright 2008, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Id: nctime.h,v 1.6 2010/03/18 19:24:26 russ Exp $ + *********************************************************************/ + +struct bounds_node{ + int ncid; /* group (or file) in which variable with associated + * bounds variable resides */ + int varid; /* has "bounds" attribute naming its bounds variable */ + char *bounds_name; /* the named variable, which stores bounds for varid */ + struct bounds_node *next; /* next node on list or NULL ifn last list node */ +}; + +typedef struct bounds_node bounds_node_t; + +/* + * This code was extracted with permission from the CDMS time + * conversion and arithmetic routines developed by Bob Drach, Lawrence + * Livermore National Laboratory as part of the cdtime library. + * Changes and additions were made to support the "-t" option of the + * netCDF ncdump utility. + * + * For the complete time conversion and climate calendar facilities of + * the CDMS library, get the original sources from LLNL. + */ + +#define CD_MAX_RELUNITS 64 /* Max characters in relative units */ +#define CD_MAX_CHARTIME 48 /* Max characters in character time */ +#define CD_NULL_DAY 1 /* Null day value */ +#define CD_NULL_HOUR 0.0 /* Null hour value */ +#define CD_NULL_ID 0 /* Reserved ID */ +#define CD_NULL_MONTH 1 /* Null month value */ +#define CD_NULL_YEAR 0 /* Null year value, component time */ + +typedef enum CdTimeUnit { + CdBadTimeUnit = 0, + CdMinute = 1, + CdHour = 2, + CdDay = 3, + CdWeek = 4, /* Always = 7 days */ + CdMonth = 5, + CdSeason = 6, /* Always = 3 months */ + CdYear = 7, + CdSecond = 8 +} CdTimeUnit; + +typedef enum cdUnit { + cdBadUnit = CdBadTimeUnit, + cdMinute = CdMinute, + cdHour = CdHour, + cdDay = CdDay, + cdWeek = CdWeek, /* Always = 7 days */ + cdMonth = CdMonth, + cdSeason = CdSeason, /* Always = 3 months */ + cdYear = CdYear, + cdSecond = CdSecond, + cdFraction /* Fractional part of absolute time */ +} cdUnitTime; + +#define CdChronCal 0x1 +#define CdClimCal 0x0 +#define CdBaseRel 0x00 +#define CdBase1970 0x10 +#define CdHasLeap 0x100 +#define CdNoLeap 0x000 +#define Cd366 0x2000 +#define Cd365 0x1000 +#define Cd360 0x0000 +#define CdJulianType 0x10000 + +typedef enum CdTimeType { + CdChron = ( CdChronCal | CdBase1970 | CdHasLeap | Cd365), /* 4369 */ + CdJulianCal = ( CdChronCal | CdBase1970 | CdHasLeap | Cd365 | CdJulianType), + CdChronNoLeap = ( CdChronCal | CdBase1970 | CdNoLeap | Cd365), /* 4113 */ + CdChron360 = ( CdChronCal | CdBase1970 | CdNoLeap | Cd360), /* 17 */ + CdRel = ( CdChronCal | CdBaseRel | CdHasLeap | Cd365), /* 4353 */ + CdRelNoLeap = ( CdChronCal | CdBaseRel | CdNoLeap | Cd365), /* 4097 */ + CdClim = ( CdClimCal | CdBaseRel | CdNoLeap | Cd365), /* 4096 */ + CdClimLeap = ( CdClimCal | CdBaseRel | CdHasLeap | Cd365), + CdClim360 = ( CdClimCal | CdBaseRel | CdNoLeap | Cd365), + CdChron366 = ( CdChronCal | CdBase1970 | CdNoLeap | Cd366) +} CdTimeType; + +typedef struct { + long year; /* e.g., 1979 */ + short month; /* e.g., CdDec */ + short day; /* e.g., 30 */ + double hour; /* hour and fractional hour */ + long baseYear; /* base year for relative, 1970 for CdChron */ + CdTimeType timeType; /* e.g., CdChron */ +} CdTime; + +#define cdStandardCal 0x11 +#define cdClimCal 0x0 +#define cdHasLeap 0x100 +#define cdHasNoLeap 0x000 +#define cd366Days 0x2000 +#define cd365Days 0x1000 +#define cd360Days 0x0000 +#define cdJulianCal 0x10000 +#define cdMixedCal 0x20000 + +typedef enum cdCalenType { + cdStandard = ( cdStandardCal | cdHasLeap | cd365Days), + cdJulian = ( cdStandardCal | cdHasLeap | cd365Days | cdJulianCal), + cdNoLeap = ( cdStandardCal | cdHasNoLeap | cd365Days), + cd360 = ( cdStandardCal | cdHasNoLeap | cd360Days), + cd366 = ( cdStandardCal | cdHasNoLeap | cd366Days), + cdClim = ( cdClimCal | cdHasNoLeap | cd365Days), + cdClimLeap = ( cdClimCal | cdHasLeap | cd365Days), + cdClim360 = ( cdClimCal | cdHasNoLeap | cd360Days), + cdMixed = ( cdStandardCal | cdHasLeap | cd365Days | cdMixedCal) +} cdCalenType; + +/* Component time */ +typedef struct { + long year; /* Year */ + short month; /* Numerical month (1..12) */ + short day; /* Day of month (1..31) */ + double hour; /* Hour and fractional hours */ +} cdCompTime; + +typedef struct { + long count; /* units count */ + CdTimeUnit units; /* time interval units */ +} CdDeltaTime; + +typedef struct timeinfo_t { + cdCalenType calendar; + cdUnitTime unit; + char *units; + cdCompTime origin; +} timeinfo_t; + + + +#if defined(DLL_NETCDF) /* Defined when library is a DLL */ +# if defined(DLL_EXPORT) /* define when building the library. */ +# define MSC_NCTIME_EXTRA __declspec(dllexport) +# else +# define MSC_NCTIME_EXTRA __declspec(dllimport) +# endif + +MSC_NCTIME_EXTRA extern void cdRel2Iso(cdCalenType timetype, char* relunits, int separator, double reltime, char* chartime); +MSC_NCTIME_EXTRA extern void cdChar2Comp(cdCalenType timetype, char* chartime, cdCompTime* comptime); +MSC_NCTIME_EXTRA extern void Cdh2e(CdTime *htime, double *etime); +MSC_NCTIME_EXTRA extern void Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime); +MSC_NCTIME_EXTRA extern int cdParseRelunits(cdCalenType timetype, char* relunits, cdUnitTime* unit, cdCompTime* base_comptime); +#else +extern void cdRel2Iso(cdCalenType timetype, char* relunits, int separator, double reltime, char* chartime); +extern void cdChar2Comp(cdCalenType timetype, char* chartime, cdCompTime* comptime); +extern void Cdh2e(CdTime *htime, double *etime); +extern void Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime); +extern int cdParseRelunits(cdCalenType timetype, char* relunits, cdUnitTime* unit, cdCompTime* base_comptime); +#endif /* DLL Considerations. */ + + + diff --git a/extern/src_netcdf4/ncx.c b/extern/src_netcdf4/ncx.c new file mode 100644 index 0000000000000000000000000000000000000000..896ec4028fd38b457c40adb3dbaebeb4266f3668 --- /dev/null +++ b/extern/src_netcdf4/ncx.c @@ -0,0 +1,8385 @@ +/* Do not edit this file. It is produced from the corresponding .m4 source */ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * + * This file contains some routines derived from code + * which is copyrighted by Sun Microsystems, Inc. + * The "#ifdef vax" versions of + * ncx_put_float_float() + * ncx_get_float_float() + * ncx_put_double_double() + * ncx_get_double_double() + * ncx_putn_float_float() + * ncx_getn_float_float() + * ncx_putn_double_double() + * ncx_getn_double_double() + * are derived from xdr_float() and xdr_double() routines + * in the freely available, copyrighted Sun RPCSRC 3.9 + * distribution, xdr_float.c. + * Our "value added" is that these are always memory to memory, + * they handle IEEE subnormals properly, and their "n" versions + * operate speedily on arrays. + */ +/* $Id: ncx.m4,v 2.58 2010/05/26 18:11:08 dmh Exp $ */ + +/* + * An external data representation interface. + */ + +#include "ncx.h" +#include "nc3dispatch.h" +#include +#include + +/* alias poorly named limits.h macros */ +#define SHORT_MAX SHRT_MAX +#define SHORT_MIN SHRT_MIN +#define USHORT_MAX USHRT_MAX +#ifndef LLONG_MAX +# define LLONG_MAX 9223372036854775807LL +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX 18446744073709551615ULL +#endif +#define LONG_LONG_MAX LLONG_MAX +#define LONG_LONG_MIN LLONG_MIN +#define ULONG_LONG_MAX ULLONG_MAX +#include +#ifndef FLT_MAX /* This POSIX macro missing on some systems */ +# ifndef NO_IEEE_FLOAT +# define FLT_MAX 3.40282347e+38f +# else +# error "You will need to define FLT_MAX" +# endif +#endif +/* alias poorly named float.h macros */ +#define FLOAT_MAX FLT_MAX +#define FLOAT_MIN (-FLT_MAX) +#define DOUBLE_MAX DBL_MAX +#define DOUBLE_MIN (-DBL_MAX) +#define FLOAT_MAX_EXP FLT_MAX_EXP +#define DOUBLE_MAX_EXP DBL_MAX_EXP +#include +#define UCHAR_MIN 0 +#define Min(a,b) ((a) < (b) ? (a) : (b)) +#define Max(a,b) ((a) > (b) ? (a) : (b)) + +/* + * If the machine's float domain is "smaller" than the external one + * use the machine domain + */ +#if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128 /* 128 is X_FLT_MAX_EXP */ +#undef X_FLOAT_MAX +# define X_FLOAT_MAX FLT_MAX +#undef X_FLOAT_MIN +# define X_FLOAT_MIN (-X_FLOAT_MAX) +#endif + +#if _SX /* NEC SUPER UX */ +#define LOOPCNT 256 /* must be no longer than hardware vector length */ +#if _INT64 +#undef INT_MAX /* workaround cpp bug */ +#define INT_MAX X_INT_MAX +#undef INT_MIN /* workaround cpp bug */ +#define INT_MIN X_INT_MIN +#undef LONG_MAX /* workaround cpp bug */ +#define LONG_MAX X_INT_MAX +#undef LONG_MIN /* workaround cpp bug */ +#define LONG_MIN X_INT_MIN +#elif _LONG64 +#undef LONG_MAX /* workaround cpp bug */ +#define LONG_MAX 4294967295L +#undef LONG_MIN /* workaround cpp bug */ +#define LONG_MIN -4294967295L +#endif +#if !_FLOAT0 +#error "FLOAT1 and FLOAT2 not supported" +#endif +#endif /* _SX */ + +static const char nada[X_ALIGN] = {0, 0, 0, 0}; + +#ifndef WORDS_BIGENDIAN +/* LITTLE_ENDIAN: DEC and intel */ +/* + * Routines to convert to BIGENDIAN. + * Optimize the swapn?b() and swap?b() routines aggressivly. + */ + +#define SWAP2(a) ( (((a) & 0xff) << 8) | \ + (((a) >> 8) & 0xff) ) + +#define SWAP4(a) ( ((a) << 24) | \ + (((a) << 8) & 0x00ff0000) | \ + (((a) >> 8) & 0x0000ff00) | \ + (((a) >> 24) & 0x000000ff) ) + + +static void +swapn2b(void *dst, const void *src, size_t nn) +{ + char *op = dst; + const char *ip = src; + +/* unroll the following to reduce loop overhead + * + * while(nn-- != 0) + * { + * *op++ = *(++ip); + * *op++ = *(ip++ -1); + * } + */ + while(nn > 3) + { + *op++ = *(++ip); + *op++ = *(ip++ -1); + *op++ = *(++ip); + *op++ = *(ip++ -1); + *op++ = *(++ip); + *op++ = *(ip++ -1); + *op++ = *(++ip); + *op++ = *(ip++ -1); + nn -= 4; + } + while(nn-- != 0) + { + *op++ = *(++ip); + *op++ = *(ip++ -1); + } +} + +# ifndef vax +static void +swap4b(void *dst, const void *src) +{ + char *op = dst; + const char *ip = src; + op[0] = ip[3]; + op[1] = ip[2]; + op[2] = ip[1]; + op[3] = ip[0]; +} +# endif /* !vax */ + +static void +swapn4b(void *dst, const void *src, size_t nn) +{ + char *op = dst; + const char *ip = src; + +/* unroll the following to reduce loop overhead + * while(nn-- != 0) + * { + * op[0] = ip[3]; + * op[1] = ip[2]; + * op[2] = ip[1]; + * op[3] = ip[0]; + * op += 4; + * ip += 4; + * } + */ + while(nn > 3) + { + op[0] = ip[3]; + op[1] = ip[2]; + op[2] = ip[1]; + op[3] = ip[0]; + op[4] = ip[7]; + op[5] = ip[6]; + op[6] = ip[5]; + op[7] = ip[4]; + op[8] = ip[11]; + op[9] = ip[10]; + op[10] = ip[9]; + op[11] = ip[8]; + op[12] = ip[15]; + op[13] = ip[14]; + op[14] = ip[13]; + op[15] = ip[12]; + op += 16; + ip += 16; + nn -= 4; + } + while(nn-- != 0) + { + op[0] = ip[3]; + op[1] = ip[2]; + op[2] = ip[1]; + op[3] = ip[0]; + op += 4; + ip += 4; + } +} + +# ifndef vax +static void +swap8b(void *dst, const void *src) +{ + char *op = dst; + const char *ip = src; +# ifndef FLOAT_WORDS_BIGENDIAN + op[0] = ip[7]; + op[1] = ip[6]; + op[2] = ip[5]; + op[3] = ip[4]; + op[4] = ip[3]; + op[5] = ip[2]; + op[6] = ip[1]; + op[7] = ip[0]; +# else + op[0] = ip[3]; + op[1] = ip[2]; + op[2] = ip[1]; + op[3] = ip[0]; + op[4] = ip[7]; + op[5] = ip[6]; + op[6] = ip[5]; + op[7] = ip[4]; +# endif +} +# endif /* !vax */ + +# ifndef vax +static void +swapn8b(void *dst, const void *src, size_t nn) +{ + char *op = dst; + const char *ip = src; + +/* unroll the following to reduce loop overhead + * while(nn-- != 0) + * { + * op[0] = ip[7]; + * op[1] = ip[6]; + * op[2] = ip[5]; + * op[3] = ip[4]; + * op[4] = ip[3]; + * op[5] = ip[2]; + * op[6] = ip[1]; + * op[7] = ip[0]; + * op += 8; + * ip += 8; + * } + */ +# ifndef FLOAT_WORDS_BIGENDIAN + while(nn > 1) + { + op[0] = ip[7]; + op[1] = ip[6]; + op[2] = ip[5]; + op[3] = ip[4]; + op[4] = ip[3]; + op[5] = ip[2]; + op[6] = ip[1]; + op[7] = ip[0]; + op[8] = ip[15]; + op[9] = ip[14]; + op[10] = ip[13]; + op[11] = ip[12]; + op[12] = ip[11]; + op[13] = ip[10]; + op[14] = ip[9]; + op[15] = ip[8]; + op += 16; + ip += 16; + nn -= 2; + } + while(nn-- != 0) + { + op[0] = ip[7]; + op[1] = ip[6]; + op[2] = ip[5]; + op[3] = ip[4]; + op[4] = ip[3]; + op[5] = ip[2]; + op[6] = ip[1]; + op[7] = ip[0]; + op += 8; + ip += 8; + } +# else + while(nn-- != 0) + { + op[0] = ip[3]; + op[1] = ip[2]; + op[2] = ip[1]; + op[3] = ip[0]; + op[4] = ip[7]; + op[5] = ip[6]; + op[6] = ip[5]; + op[7] = ip[4]; + op += 8; + ip += 8; + } +# endif +} +# endif /* !vax */ + +#endif /* LITTLE_ENDIAN */ + + +/* + * Primitive numeric conversion functions. + */ + +/* x_schar */ + +/* We don't implement any x_schar primitives. */ + + +/* x_short */ + +#if SHORT_MAX == X_SHORT_MAX +typedef short ix_short; +#define SIZEOF_IX_SHORT SIZEOF_SHORT +#define IX_SHORT_MAX SHORT_MAX +#elif INT_MAX >= X_SHORT_MAX +typedef int ix_short; +#define SIZEOF_IX_SHORT SIZEOF_INT +#define IX_SHORT_MAX INT_MAX +#elif LONG_MAX >= X_SHORT_MAX +typedef long ix_short; +#define SIZEOF_IX_SHORT SIZEOF_LONG +#define IX_SHORT_MAX LONG_MAX +#elif LLONG_MAX >= X_SHORT_MAX +typedef long long ix_short; +#define SIZEOF_IX_SHORT SIZEOF_LONG_LONG +#define IX_SHORT_MAX LLONG_MAX +#else +#error "ix_short implementation" +#endif + +static void +get_ix_short(const void *xp, ix_short *ip) +{ + const uchar *cp = (const uchar *) xp; + *ip = *cp++ << 8; +#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT + if(*ip & 0x8000) + { + /* extern is negative */ + *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */ + } +#endif + *ip |= *cp; +} + +static void +put_ix_short(void *xp, const ix_short *ip) +{ + uchar *cp = (uchar *) xp; + *cp++ = (*ip) >> 8; + *cp = (*ip) & 0xff; +} + + +int +ncx_get_short_schar(const void *xp, schar *ip) +{ + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; + if(xx > SCHAR_MAX || xx < SCHAR_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_short_uchar(const void *xp, uchar *ip) +{ + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; + if(xx > UCHAR_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_short_short(const void *xp, short *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX + get_ix_short(xp, (ix_short *)ip); + return ENOERR; +#else + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; +# if IX_SHORT_MAX > SHORT_MAX + if(xx > SHORT_MAX || xx < SHORT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_get_short_int(const void *xp, int *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX + get_ix_short(xp, (ix_short *)ip); + return ENOERR; +#else + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; +# if IX_SHORT_MAX > INT_MAX + if(xx > INT_MAX || xx < INT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_get_short_uint(const void *xp, unsigned int *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX + get_ix_short(xp, (ix_short *)ip); + return ENOERR; +#else + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; +# if IX_SHORT_MAX > INT_MAX + if(xx > UINT_MAX || xx < 0) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_get_short_longlong(const void *xp, long long *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_LONG_LONG && IX_SHORT_MAX == LONG_LONG_MAX + get_ix_short(xp, (ix_short *)ip); + return ENOERR; +#else + /* assert(LONG_LONG_MAX >= X_SHORT_MAX); */ + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; + return ENOERR; +#endif +} + +int +ncx_get_short_ulonglong(const void *xp, unsigned long long *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX + get_ix_short(xp, (ix_short *)ip); + return ENOERR; +#else + /* assert(LONG_LONG_MAX >= X_SHORT_MAX); */ + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; + if(xx < 0) + return NC_ERANGE; + return ENOERR; +#endif +} + +int +ncx_get_short_float(const void *xp, float *ip) +{ + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; +#if 0 /* TODO: determine when necessary */ + if(xx > FLT_MAX || xx < (-FLT_MAX)) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_get_short_double(const void *xp, double *ip) +{ + /* assert(DBL_MAX >= X_SHORT_MAX); */ + ix_short xx; + get_ix_short(xp, &xx); + *ip = xx; + return ENOERR; +} + +int +ncx_put_short_schar(void *xp, const schar *ip) +{ + uchar *cp = (uchar *) xp; + if(*ip & 0x80) + *cp++ = 0xff; + else + *cp++ = 0; + *cp = (uchar)*ip; + return ENOERR; +} + +int +ncx_put_short_uchar(void *xp, const uchar *ip) +{ + uchar *cp = (uchar *) xp; + *cp++ = 0; + *cp = *ip; + return ENOERR; +} + +int +ncx_put_short_short(void *xp, const short *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_SHORT && X_SHORT_MAX == SHORT_MAX + put_ix_short(xp, (const ix_short *)ip); + return ENOERR; +#else + ix_short xx = (ix_short)*ip; + put_ix_short(xp, &xx); +# if X_SHORT_MAX < SHORT_MAX + if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_short_int(void *xp, const int *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_INT && X_SHORT_MAX == INT_MAX + put_ix_short(xp, (const ix_short *)ip); + return ENOERR; +#else + ix_short xx = (ix_short)*ip; + put_ix_short(xp, &xx); +# if X_SHORT_MAX < INT_MAX + if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_short_uint(void *xp, const unsigned int *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_INT && X_SHORT_MAX == INT_MAX + put_ix_short(xp, (const ix_short *)ip); + return ENOERR; +#else + ix_short xx = (ix_short)*ip; + put_ix_short(xp, &xx); +# if X_SHORT_MAX < INT_MAX + if(*ip > X_SHORT_MAX) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_short_longlong(void *xp, const long long *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_LONG_LONG && X_SHORT_MAX == LONG_LONG_MAX + put_ix_short(xp, (const ix_short *)ip); + return ENOERR; +#else + ix_short xx = (ix_short)*ip; + put_ix_short(xp, &xx); +# if X_SHORT_MAX < LONG_LONG_MAX + if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_short_ulonglong(void *xp, const unsigned long long *ip) +{ +#if SIZEOF_IX_SHORT == SIZEOF_LONG_LONG && X_SHORT_MAX == LONG_LONG_MAX + put_ix_short(xp, (const ix_short *)ip); + return ENOERR; +#else + ix_short xx = (ix_short)*ip; + put_ix_short(xp, &xx); +# if X_SHORT_MAX < LONG_LONG_MAX + if(*ip > X_SHORT_MAX) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_short_float(void *xp, const float *ip) +{ + ix_short xx = *ip; + put_ix_short(xp, &xx); + if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_put_short_double(void *xp, const double *ip) +{ + ix_short xx = *ip; + put_ix_short(xp, &xx); + if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) + return NC_ERANGE; + return ENOERR; +} + +/* x_int */ + +#if SHORT_MAX == X_INT_MAX +typedef short ix_int; +#define SIZEOF_IX_INT SIZEOF_SHORT +#define IX_INT_MAX SHORT_MAX +#elif INT_MAX >= X_INT_MAX +typedef int ix_int; +#define SIZEOF_IX_INT SIZEOF_INT +#define IX_INT_MAX INT_MAX +#elif LONG_MAX >= X_INT_MAX +typedef long ix_int; +#define SIZEOF_IX_INT SIZEOF_LONG +#define IX_INT_MAX LONG_MAX +#else +#error "ix_int implementation" +#endif + + +static void +get_ix_int(const void *xp, ix_int *ip) +{ + const uchar *cp = (const uchar *) xp; + + *ip = *cp++ << 24; +#if SIZEOF_IX_INT > X_SIZEOF_INT + if(*ip & 0x80000000) + { + /* extern is negative */ + *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */ + } +#endif + *ip |= (*cp++ << 16); + *ip |= (*cp++ << 8); + *ip |= *cp; +} + +static void +put_ix_int(void *xp, const ix_int *ip) +{ + uchar *cp = (uchar *) xp; + + *cp++ = (*ip) >> 24; + *cp++ = ((*ip) & 0x00ff0000) >> 16; + *cp++ = ((*ip) & 0x0000ff00) >> 8; + *cp = ((*ip) & 0x000000ff); +} + + +int +ncx_get_int_schar(const void *xp, schar *ip) +{ + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; + if(xx > SCHAR_MAX || xx < SCHAR_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_int_uchar(const void *xp, uchar *ip) +{ + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; + if(xx > UCHAR_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_int_short(const void *xp, short *ip) +{ +#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX + get_ix_int(xp, (ix_int *)ip); + return ENOERR; +#else + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; +# if IX_INT_MAX > SHORT_MAX + if(xx > SHORT_MAX || xx < SHORT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_get_int_int(const void *xp, int *ip) +{ +#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX + get_ix_int(xp, (ix_int *)ip); + return ENOERR; +#else + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; +# if IX_INT_MAX > INT_MAX + if(xx > INT_MAX || xx < INT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_get_int_uint(const void *xp, unsigned int *ip) +{ + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; + if(xx > UINT_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_int_longlong(const void *xp, long long *ip) +{ + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; + return ENOERR; +} + +int +ncx_get_int_ulonglong(const void *xp, unsigned long long *ip) +{ + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; + if(xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_int_float(const void *xp, float *ip) +{ + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; +#if 0 /* TODO: determine when necessary */ + if(xx > FLT_MAX || xx < (-FLT_MAX)) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_get_int_double(const void *xp, double *ip) +{ + /* assert((DBL_MAX >= X_INT_MAX); */ + ix_int xx; + get_ix_int(xp, &xx); + *ip = xx; + return ENOERR; +} + +int +ncx_put_int_schar(void *xp, const schar *ip) +{ + uchar *cp = (uchar *) xp; + if(*ip & 0x80) + { + *cp++ = 0xff; + *cp++ = 0xff; + *cp++ = 0xff; + } + else + { + *cp++ = 0x00; + *cp++ = 0x00; + *cp++ = 0x00; + } + *cp = (uchar)*ip; + return ENOERR; +} + +int +ncx_put_int_uchar(void *xp, const uchar *ip) +{ + uchar *cp = (uchar *) xp; + *cp++ = 0x00; + *cp++ = 0x00; + *cp++ = 0x00; + *cp = *ip; + return ENOERR; +} + +int +ncx_put_int_short(void *xp, const short *ip) +{ +#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX + put_ix_int(xp, (ix_int *)ip); + return ENOERR; +#else + ix_int xx = (ix_int)(*ip); + put_ix_int(xp, &xx); +# if IX_INT_MAX < SHORT_MAX + if(*ip > X_INT_MAX || *ip < X_INT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_int_int(void *xp, const int *ip) +{ +#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX + put_ix_int(xp, (ix_int *)ip); + return ENOERR; +#else + ix_int xx = (ix_int)(*ip); + put_ix_int(xp, &xx); +# if IX_INT_MAX < INT_MAX + if(*ip > X_INT_MAX || *ip < X_INT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_int_uint(void *xp, const unsigned int *ip) +{ +#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX + put_ix_int(xp, (ix_int *)ip); + return ENOERR; +#else + ix_int xx = (ix_int)(*ip); + put_ix_int(xp, &xx); + if(*ip > X_UINT_MAX) + return NC_ERANGE; + return ENOERR; +#endif +} + +int +ncx_put_int_longlong(void *xp, const longlong *ip) +{ +#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX + put_ix_int(xp, (ix_int *)ip); + return ENOERR; +#else + ix_int xx = (ix_int)(*ip); + put_ix_int(xp, &xx); +# if IX_INT_MAX < LONG_LONG_MAX + if(*ip > X_INT_MAX || *ip < X_INT_MIN) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_int_ulonglong(void *xp, const unsigned long long *ip) +{ +#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX + put_ix_int(xp, (ix_int *)ip); + return ENOERR; +#else + ix_int xx = (ix_int)(*ip); + put_ix_int(xp, &xx); +# if IX_INT_MAX < LONG_MAX + if(*ip > X_INT_MAX) + return NC_ERANGE; +# endif + return ENOERR; +#endif +} + +int +ncx_put_int_float(void *xp, const float *ip) +{ + ix_int xx = (ix_int)(*ip); + put_ix_int(xp, &xx); + if(*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_put_int_double(void *xp, const double *ip) +{ + ix_int xx = (ix_int)(*ip); + put_ix_int(xp, &xx); + if(*ip > X_INT_MAX || *ip < X_INT_MIN) + return NC_ERANGE; + return ENOERR; +} + + +/* x_float */ + +#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) + +static void +get_ix_float(const void *xp, float *ip) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(ip, xp, sizeof(float)); +#else + swap4b(ip, xp); +#endif +} + +static void +put_ix_float(void *xp, const float *ip) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(xp, ip, X_SIZEOF_FLOAT); +#else + swap4b(xp, ip); +#endif +} + +#elif vax + +/* What IEEE single precision floating point looks like on a Vax */ +struct ieee_single { + unsigned int exp_hi : 7; + unsigned int sign : 1; + unsigned int mant_hi : 7; + unsigned int exp_lo : 1; + unsigned int mant_lo_hi : 8; + unsigned int mant_lo_lo : 8; +}; + +/* Vax single precision floating point */ +struct vax_single { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; +}; + +#define VAX_SNG_BIAS 0x81 +#define IEEE_SNG_BIAS 0x7f + +static struct sgl_limits { + struct vax_single s; + struct ieee_single ieee; +} max = { + { 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ + { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 } /* Max IEEE */ +}; +static struct sgl_limits min = { + { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } /* Min IEEE */ +}; + +static void +get_ix_float(const void *xp, float *ip) +{ + struct vax_single *const vsp = (struct vax_single *) ip; + const struct ieee_single *const isp = + (const struct ieee_single *) xp; + unsigned exp = isp->exp_hi << 1 | isp->exp_lo; + + switch(exp) { + case 0 : + /* ieee subnormal */ + if(isp->mant_hi == min.ieee.mant_hi + && isp->mant_lo_hi == min.ieee.mant_lo_hi + && isp->mant_lo_lo == min.ieee.mant_lo_lo) + { + *vsp = min.s; + } + else + { + unsigned mantissa = (isp->mant_hi << 16) + | isp->mant_lo_hi << 8 + | isp->mant_lo_lo; + unsigned tmp = mantissa >> 20; + if(tmp >= 4) { + vsp->exp = 2; + } else if (tmp >= 2) { + vsp->exp = 1; + } else { + *vsp = min.s; + break; + } /* else */ + tmp = mantissa - (1 << (20 + vsp->exp )); + tmp <<= 3 - vsp->exp; + vsp->mantissa2 = tmp; + vsp->mantissa1 = (tmp >> 16); + } + break; + case 0xfe : + case 0xff : + *vsp = max.s; + break; + default : + vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; + vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo; + vsp->mantissa1 = isp->mant_hi; + } + + vsp->sign = isp->sign; + +} + + +static void +put_ix_float(void *xp, const float *ip) +{ + const struct vax_single *const vsp = + (const struct vax_single *)ip; + struct ieee_single *const isp = (struct ieee_single *) xp; + + switch(vsp->exp){ + case 0 : + /* all vax float with zero exponent map to zero */ + *isp = min.ieee; + break; + case 2 : + case 1 : + { + /* These will map to subnormals */ + unsigned mantissa = (vsp->mantissa1 << 16) + | vsp->mantissa2; + mantissa >>= 3 - vsp->exp; + mantissa += (1 << (20 + vsp->exp)); + isp->mant_lo_lo = mantissa; + isp->mant_lo_hi = mantissa >> 8; + isp->mant_hi = mantissa >> 16; + isp->exp_lo = 0; + isp->exp_hi = 0; + } + break; + case 0xff : /* max.s.exp */ + if( vsp->mantissa2 == max.s.mantissa2 + && vsp->mantissa1 == max.s.mantissa1) + { + /* map largest vax float to ieee infinity */ + *isp = max.ieee; + break; + } /* else, fall thru */ + default : + { + unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; + isp->exp_hi = exp >> 1; + isp->exp_lo = exp; + isp->mant_lo_lo = vsp->mantissa2; + isp->mant_lo_hi = vsp->mantissa2 >> 8; + isp->mant_hi = vsp->mantissa1; + } + } + + isp->sign = vsp->sign; + +} + + /* vax */ +#elif defined(_CRAY) && !defined(__crayx1) + +/* + * Return the number of bytes until the next "word" boundary + * N.B. This is based on the very wierd YMP address structure, + * which puts the address within a word in the leftmost 3 bits + * of the address. + */ +static size_t +word_align(const void *vp) +{ + const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7; + return (rem != 0); +} + +struct ieee_single_hi { + unsigned int sign : 1; + unsigned int exp : 8; + unsigned int mant :23; + unsigned int pad :32; +}; +typedef struct ieee_single_hi ieee_single_hi; + +struct ieee_single_lo { + unsigned int pad :32; + unsigned int sign : 1; + unsigned int exp : 8; + unsigned int mant :23; +}; +typedef struct ieee_single_lo ieee_single_lo; + +static const int ieee_single_bias = 0x7f; + +struct ieee_double { + unsigned int sign : 1; + unsigned int exp :11; + unsigned int mant :52; +}; +typedef struct ieee_double ieee_double; + +static const int ieee_double_bias = 0x3ff; + +#if defined(NO_IEEE_FLOAT) + +struct cray_single { + unsigned int sign : 1; + unsigned int exp :15; + unsigned int mant :48; +}; +typedef struct cray_single cray_single; + +static const int cs_ieis_bias = 0x4000 - 0x7f; + +static const int cs_id_bias = 0x4000 - 0x3ff; + + +static void +get_ix_float(const void *xp, float *ip) +{ + + if(word_align(xp) == 0) + { + const ieee_single_hi *isp = (const ieee_single_hi *) xp; + cray_single *csp = (cray_single *) ip; + + if(isp->exp == 0) + { + /* ieee subnormal */ + *ip = (double)isp->mant; + if(isp->mant != 0) + { + csp->exp -= (ieee_single_bias + 22); + } + } + else + { + csp->exp = isp->exp + cs_ieis_bias + 1; + csp->mant = isp->mant << (48 - 1 - 23); + csp->mant |= (1 << (48 - 1)); + } + csp->sign = isp->sign; + + + } + else + { + const ieee_single_lo *isp = (const ieee_single_lo *) xp; + cray_single *csp = (cray_single *) ip; + + if(isp->exp == 0) + { + /* ieee subnormal */ + *ip = (double)isp->mant; + if(isp->mant != 0) + { + csp->exp -= (ieee_single_bias + 22); + } + } + else + { + csp->exp = isp->exp + cs_ieis_bias + 1; + csp->mant = isp->mant << (48 - 1 - 23); + csp->mant |= (1 << (48 - 1)); + } + csp->sign = isp->sign; + + + } +} + +static void +put_ix_float(void *xp, const float *ip) +{ + if(word_align(xp) == 0) + { + ieee_single_hi *isp = (ieee_single_hi*)xp; + const cray_single *csp = (const cray_single *) ip; + int ieee_exp = csp->exp - cs_ieis_bias -1; + + isp->sign = csp->sign; + + if(ieee_exp >= 0xff) + { + /* NC_ERANGE => ieee Inf */ + isp->exp = 0xff; + isp->mant = 0x0; + } + else if(ieee_exp > 0) + { + /* normal ieee representation */ + isp->exp = ieee_exp; + /* assumes cray rep is in normal form */ + assert(csp->mant & 0x800000000000); + isp->mant = (((csp->mant << 1) & + 0xffffffffffff) >> (48 - 23)); + } + else if(ieee_exp > -23) + { + /* ieee subnormal, right shift */ + const int rshift = (48 - 23 - ieee_exp); + + isp->mant = csp->mant >> rshift; + +#if 0 + if(csp->mant & (1 << (rshift -1))) + { + /* round up */ + isp->mant++; + } +#endif + + isp->exp = 0; + } + else + { + /* smaller than ieee can represent */ + isp->exp = 0; + isp->mant = 0; + } + + } + else + { + ieee_single_lo *isp = (ieee_single_lo*)xp; + const cray_single *csp = (const cray_single *) ip; + int ieee_exp = csp->exp - cs_ieis_bias -1; + + isp->sign = csp->sign; + + if(ieee_exp >= 0xff) + { + /* NC_ERANGE => ieee Inf */ + isp->exp = 0xff; + isp->mant = 0x0; + } + else if(ieee_exp > 0) + { + /* normal ieee representation */ + isp->exp = ieee_exp; + /* assumes cray rep is in normal form */ + assert(csp->mant & 0x800000000000); + isp->mant = (((csp->mant << 1) & + 0xffffffffffff) >> (48 - 23)); + } + else if(ieee_exp > -23) + { + /* ieee subnormal, right shift */ + const int rshift = (48 - 23 - ieee_exp); + + isp->mant = csp->mant >> rshift; + +#if 0 + if(csp->mant & (1 << (rshift -1))) + { + /* round up */ + isp->mant++; + } +#endif + + isp->exp = 0; + } + else + { + /* smaller than ieee can represent */ + isp->exp = 0; + isp->mant = 0; + } + + } +} + +#else + /* IEEE Cray with only doubles */ +static void +get_ix_float(const void *xp, float *ip) +{ + + ieee_double *idp = (ieee_double *) ip; + + if(word_align(xp) == 0) + { + const ieee_single_hi *isp = (const ieee_single_hi *) xp; + if(isp->exp == 0 && isp->mant == 0) + { + idp->exp = 0; + idp->mant = 0; + } + else + { + idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias); + idp->mant = isp->mant << (52 - 23); + } + idp->sign = isp->sign; + } + else + { + const ieee_single_lo *isp = (const ieee_single_lo *) xp; + if(isp->exp == 0 && isp->mant == 0) + { + idp->exp = 0; + idp->mant = 0; + } + else + { + idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias); + idp->mant = isp->mant << (52 - 23); + } + idp->sign = isp->sign; + } +} + +static void +put_ix_float(void *xp, const float *ip) +{ + const ieee_double *idp = (const ieee_double *) ip; + if(word_align(xp) == 0) + { + ieee_single_hi *isp = (ieee_single_hi*)xp; + if(idp->exp > (ieee_double_bias - ieee_single_bias)) + isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias); + else + isp->exp = 0; + isp->mant = idp->mant >> (52 - 23); + isp->sign = idp->sign; + } + else + { + ieee_single_lo *isp = (ieee_single_lo*)xp; + if(idp->exp > (ieee_double_bias - ieee_single_bias)) + isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias); + else + isp->exp = 0; + isp->mant = idp->mant >> (52 - 23); + isp->sign = idp->sign; + } +} +#endif + +#else +#error "ix_float implementation" +#endif + + +int +ncx_get_float_schar(const void *xp, schar *ip) +{ + float xx; + get_ix_float(xp, &xx); + *ip = (schar) xx; + if(xx > SCHAR_MAX || xx < SCHAR_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_float_uchar(const void *xp, uchar *ip) +{ + float xx; + get_ix_float(xp, &xx); + *ip = (uchar) xx; + if(xx > UCHAR_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_float_short(const void *xp, short *ip) +{ + float xx; + get_ix_float(xp, &xx); + *ip = (short) xx; + if(xx > SHORT_MAX || xx < SHORT_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_float_int(const void *xp, int *ip) +{ + float xx; + get_ix_float(xp, &xx); + *ip = (int) xx; + if(xx > (double)INT_MAX || xx < (double)INT_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_float_uint(const void *xp, unsigned int *ip) +{ + float xx; + get_ix_float(xp, &xx); + *ip = (unsigned int) xx; + if(xx > (double)UINT_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_float_longlong(const void *xp, longlong *ip) +{ + float xx; + get_ix_float(xp, &xx); + *ip = (longlong) xx; + if(xx > (double)LONG_LONG_MAX || xx < (double)LONG_LONG_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_float_ulonglong(const void *xp, unsigned long long *ip) +{ + float xx; + get_ix_float(xp, &xx); + *ip = (longlong) xx; + if(xx > (double)ULONG_LONG_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_float_float(const void *xp, float *ip) +{ + /* TODO */ + get_ix_float(xp, ip); + return ENOERR; +} + +int +ncx_get_float_double(const void *xp, double *ip) +{ + /* TODO */ + float xx; + get_ix_float(xp, &xx); + *ip = xx; + return ENOERR; +} + + +int +ncx_put_float_schar(void *xp, const schar *ip) +{ + float xx = (float) *ip; + put_ix_float(xp, &xx); + return ENOERR; +} + +int +ncx_put_float_uchar(void *xp, const uchar *ip) +{ + float xx = (float) *ip; + put_ix_float(xp, &xx); + return ENOERR; +} + +int +ncx_put_float_short(void *xp, const short *ip) +{ + float xx = (float) *ip; + put_ix_float(xp, &xx); +#if 0 /* TODO: figure this out */ + if((float)(*ip) > X_FLOAT_MAX || (float)(*ip) < X_FLOAT_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_float_int(void *xp, const int *ip) +{ + float xx = (float) *ip; + put_ix_float(xp, &xx); +#if 1 /* TODO: figure this out */ + if((float)(*ip) > X_FLOAT_MAX || (float)(*ip) < X_FLOAT_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_float_uint(void *xp, const unsigned int *ip) +{ + float xx = (float) *ip; + put_ix_float(xp, &xx); +#if 1 /* TODO: figure this out */ + if((float)(*ip) > X_FLOAT_MAX) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_float_longlong(void *xp, const longlong *ip) +{ + float xx = (float) *ip; + put_ix_float(xp, &xx); +#if 1 /* TODO: figure this out */ + if((float)(*ip) > X_FLOAT_MAX || (float)(*ip) < X_FLOAT_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_float_ulonglong(void *xp, const unsigned long long *ip) +{ + float xx = (float) *ip; + put_ix_float(xp, &xx); +#if 1 /* TODO: figure this out */ + if((float)(*ip) > X_FLOAT_MAX) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_float_float(void *xp, const float *ip) +{ + put_ix_float(xp, ip); +#ifdef NO_IEEE_FLOAT + if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_float_double(void *xp, const double *ip) +{ + float xx = (float) *ip; + put_ix_float(xp, &xx); + if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) + return NC_ERANGE; + return ENOERR; +} + +/* x_double */ + +#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) + +static void +get_ix_double(const void *xp, double *ip) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(ip, xp, sizeof(double)); +#else + swap8b(ip, xp); +#endif +} + +static void +put_ix_double(void *xp, const double *ip) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(xp, ip, X_SIZEOF_DOUBLE); +#else + swap8b(xp, ip); +#endif +} + +#elif vax + +/* What IEEE double precision floating point looks like on a Vax */ +struct ieee_double { + unsigned int exp_hi : 7; + unsigned int sign : 1; + unsigned int mant_6 : 4; + unsigned int exp_lo : 4; + unsigned int mant_5 : 8; + unsigned int mant_4 : 8; + + unsigned int mant_lo : 32; +}; + +/* Vax double precision floating point */ +struct vax_double { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; + unsigned int mantissa3 : 16; + unsigned int mantissa4 : 16; +}; + +#define VAX_DBL_BIAS 0x81 +#define IEEE_DBL_BIAS 0x3ff +#define MASK(nbits) ((1 << nbits) - 1) + +static const struct dbl_limits { + struct vax_double d; + struct ieee_double ieee; +} dbl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ + { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */ +}; + + +static void +get_ix_double(const void *xp, double *ip) +{ + struct vax_double *const vdp = + (struct vax_double *)ip; + const struct ieee_double *const idp = + (const struct ieee_double *) xp; + { + const struct dbl_limits *lim; + int ii; + for (ii = 0, lim = dbl_limits; + ii < sizeof(dbl_limits)/sizeof(struct dbl_limits); + ii++, lim++) + { + if ((idp->mant_lo == lim->ieee.mant_lo) + && (idp->mant_4 == lim->ieee.mant_4) + && (idp->mant_5 == lim->ieee.mant_5) + && (idp->mant_6 == lim->ieee.mant_6) + && (idp->exp_lo == lim->ieee.exp_lo) + && (idp->exp_hi == lim->ieee.exp_hi) + ) + { + *vdp = lim->d; + goto doneit; + } + } + } + { + unsigned exp = idp->exp_hi << 4 | idp->exp_lo; + vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; + } + { + unsigned mant_hi = ((idp->mant_6 << 16) + | (idp->mant_5 << 8) + | idp->mant_4); + unsigned mant_lo = SWAP4(idp->mant_lo); + vdp->mantissa1 = (mant_hi >> 13); + vdp->mantissa2 = ((mant_hi & MASK(13)) << 3) + | (mant_lo >> 29); + vdp->mantissa3 = (mant_lo >> 13); + vdp->mantissa4 = (mant_lo << 3); + } + doneit: + vdp->sign = idp->sign; + +} + + +static void +put_ix_double(void *xp, const double *ip) +{ + const struct vax_double *const vdp = + (const struct vax_double *)ip; + struct ieee_double *const idp = + (struct ieee_double *) xp; + + if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) && + (vdp->mantissa3 == dbl_limits[0].d.mantissa3) && + (vdp->mantissa2 == dbl_limits[0].d.mantissa2) && + (vdp->mantissa1 == dbl_limits[0].d.mantissa1) && + (vdp->exp == dbl_limits[0].d.exp)) + { + *idp = dbl_limits[0].ieee; + goto shipit; + } + if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) && + (vdp->mantissa3 == dbl_limits[1].d.mantissa3) && + (vdp->mantissa2 == dbl_limits[1].d.mantissa2) && + (vdp->mantissa1 == dbl_limits[1].d.mantissa1) && + (vdp->exp == dbl_limits[1].d.exp)) + { + *idp = dbl_limits[1].ieee; + goto shipit; + } + + { + unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; + + unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) | + (vdp->mantissa3 << 13) | + ((vdp->mantissa4 >> 3) & MASK(13)); + + unsigned mant_hi = (vdp->mantissa1 << 13) + | (vdp->mantissa2 >> 3); + + if((vdp->mantissa4 & 7) > 4) + { + /* round up */ + mant_lo++; + if(mant_lo == 0) + { + mant_hi++; + if(mant_hi > 0xffffff) + { + mant_hi = 0; + exp++; + } + } + } + + idp->mant_lo = SWAP4(mant_lo); + idp->mant_6 = mant_hi >> 16; + idp->mant_5 = (mant_hi & 0xff00) >> 8; + idp->mant_4 = mant_hi; + idp->exp_hi = exp >> 4; + idp->exp_lo = exp; + } + + shipit: + idp->sign = vdp->sign; + +} + + /* vax */ +#elif defined(_CRAY) && !defined(__crayx1) + +static void +get_ix_double(const void *xp, double *ip) +{ + const ieee_double *idp = (const ieee_double *) xp; + cray_single *csp = (cray_single *) ip; + + if(idp->exp == 0) + { + /* ieee subnormal */ + *ip = (double)idp->mant; + if(idp->mant != 0) + { + csp->exp -= (ieee_double_bias + 51); + } + } + else + { + csp->exp = idp->exp + cs_id_bias + 1; + csp->mant = idp->mant >> (52 - 48 + 1); + csp->mant |= (1 << (48 - 1)); + } + csp->sign = idp->sign; +} + +static void +put_ix_double(void *xp, const double *ip) +{ + ieee_double *idp = (ieee_double *) xp; + const cray_single *csp = (const cray_single *) ip; + + int ieee_exp = csp->exp - cs_id_bias -1; + + idp->sign = csp->sign; + + if(ieee_exp >= 0x7ff) + { + /* NC_ERANGE => ieee Inf */ + idp->exp = 0x7ff; + idp->mant = 0x0; + } + else if(ieee_exp > 0) + { + /* normal ieee representation */ + idp->exp = ieee_exp; + /* assumes cray rep is in normal form */ + assert(csp->mant & 0x800000000000); + idp->mant = (((csp->mant << 1) & + 0xffffffffffff) << (52 - 48)); + } + else if(ieee_exp >= (-(52 -48))) + { + /* ieee subnormal, left shift */ + const int lshift = (52 - 48) + ieee_exp; + idp->mant = csp->mant << lshift; + idp->exp = 0; + } + else if(ieee_exp >= -52) + { + /* ieee subnormal, right shift */ + const int rshift = (- (52 - 48) - ieee_exp); + + idp->mant = csp->mant >> rshift; + +#if 0 + if(csp->mant & (1 << (rshift -1))) + { + /* round up */ + idp->mant++; + } +#endif + + idp->exp = 0; + } + else + { + /* smaller than ieee can represent */ + idp->exp = 0; + idp->mant = 0; + } +} +#else +#error "ix_double implementation" +#endif + +int +ncx_get_double_schar(const void *xp, schar *ip) +{ + double xx; + get_ix_double(xp, &xx); + *ip = (schar) xx; + if(xx > SCHAR_MAX || xx < SCHAR_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_double_uchar(const void *xp, uchar *ip) +{ + double xx; + get_ix_double(xp, &xx); + *ip = (uchar) xx; + if(xx > UCHAR_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_double_short(const void *xp, short *ip) +{ + double xx; + get_ix_double(xp, &xx); + *ip = (short) xx; + if(xx > SHORT_MAX || xx < SHORT_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_double_int(const void *xp, int *ip) +{ + double xx; + get_ix_double(xp, &xx); + *ip = (int) xx; + if(xx > INT_MAX || xx < INT_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_double_uint(const void *xp, unsigned int *ip) +{ + double xx; + get_ix_double(xp, &xx); + *ip = (unsigned int) xx; + if(xx > UINT_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_double_longlong(const void *xp, longlong *ip) +{ + double xx; + get_ix_double(xp, &xx); + *ip = (longlong) xx; + if(xx > LONG_LONG_MAX || xx < LONG_LONG_MIN) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_double_ulonglong(const void *xp, unsigned long long *ip) +{ + double xx; + get_ix_double(xp, &xx); + *ip = (unsigned longlong) xx; + if(xx > ULONG_LONG_MAX || xx < 0) + return NC_ERANGE; + return ENOERR; +} + +int +ncx_get_double_float(const void *xp, float *ip) +{ + double xx; + get_ix_double(xp, &xx); + if(xx > FLT_MAX) + { + *ip = FLT_MAX; + return NC_ERANGE; + } + if(xx < (-FLT_MAX)) + { + *ip = (-FLT_MAX); + return NC_ERANGE; + } + *ip = (float) xx; + return ENOERR; +} + +int +ncx_get_double_double(const void *xp, double *ip) +{ + /* TODO */ + get_ix_double(xp, ip); + return ENOERR; +} + + +int +ncx_put_double_schar(void *xp, const schar *ip) +{ + double xx = (double) *ip; + put_ix_double(xp, &xx); + return ENOERR; +} + +int +ncx_put_double_uchar(void *xp, const uchar *ip) +{ + double xx = (double) *ip; + put_ix_double(xp, &xx); + return ENOERR; +} + +int +ncx_put_double_short(void *xp, const short *ip) +{ + double xx = (double) *ip; + put_ix_double(xp, &xx); +#if 0 /* TODO: figure this out */ + if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_double_int(void *xp, const int *ip) +{ + double xx = (double) *ip; + put_ix_double(xp, &xx); +#if 0 /* TODO: figure this out */ + if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_double_uint(void *xp, const unsigned int *ip) +{ + double xx = (double) *ip; + put_ix_double(xp, &xx); +#if 0 /* TODO: figure this out */ + if((double)(*ip) > X_DOUBLE_MAX) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_double_longlong(void *xp, const longlong *ip) +{ + double xx = (double) *ip; + put_ix_double(xp, &xx); +#if 1 /* TODO: figure this out */ + if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_double_ulonglong(void *xp, const unsigned long long *ip) +{ + double xx = (double) *ip; + put_ix_double(xp, &xx); +#if 1 /* TODO: figure this out */ + if((double)(*ip) > X_DOUBLE_MAX) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_double_float(void *xp, const float *ip) +{ + double xx = (double) *ip; + put_ix_double(xp, &xx); +#if 1 /* TODO: figure this out */ + if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + +int +ncx_put_double_double(void *xp, const double *ip) +{ + put_ix_double(xp, ip); +#ifdef NO_IEEE_FLOAT + if(*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) + return NC_ERANGE; +#endif + return ENOERR; +} + + +/* x_size_t */ + +#if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T +#error "x_size_t implementation" +/* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */ +#endif + +int +ncx_put_size_t(void **xpp, const size_t *ulp) +{ + /* similar to put_ix_int() */ + uchar *cp = (uchar *) *xpp; + assert(*ulp <= X_SIZE_MAX); + + *cp++ = (uchar)((*ulp) >> 24); + *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16); + *cp++ = (uchar)(((*ulp) & 0x0000ff00) >> 8); + *cp = (uchar)((*ulp) & 0x000000ff); + + *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T); + return ENOERR; +} + +int +ncx_get_size_t(const void **xpp, size_t *ulp) +{ + /* similar to get_ix_int */ + const uchar *cp = (const uchar *) *xpp; + + *ulp = (unsigned)(*cp++ << 24); + *ulp |= (*cp++ << 16); + *ulp |= (*cp++ << 8); + *ulp |= *cp; + + *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T); + return ENOERR; +} + +/* x_off_t */ + +int +ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t) +{ + /* similar to put_ix_int() */ + uchar *cp = (uchar *) *xpp; + /* No negative offsets stored in netcdf */ + if (*lp < 0) { + /* Assume this is an overflow of a 32-bit int... */ + return ERANGE; + } + + assert(sizeof_off_t == 4 || sizeof_off_t == 8); + + if (sizeof_off_t == 4) { + *cp++ = (uchar) ((*lp) >> 24); + *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16); + *cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8); + *cp = (uchar)( (*lp) & 0x000000ff); + } else { +#if SIZEOF_OFF_T == 4 +/* Write a 64-bit offset on a system with only a 32-bit offset */ + *cp++ = (uchar)0; + *cp++ = (uchar)0; + *cp++ = (uchar)0; + *cp++ = (uchar)0; + + *cp++ = (uchar)(((*lp) & 0xff000000) >> 24); + *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16); + *cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8); + *cp = (uchar)( (*lp) & 0x000000ff); +#else + *cp++ = (uchar) ((*lp) >> 56); + *cp++ = (uchar)(((*lp) & 0x00ff000000000000ULL) >> 48); + *cp++ = (uchar)(((*lp) & 0x0000ff0000000000ULL) >> 40); + *cp++ = (uchar)(((*lp) & 0x000000ff00000000ULL) >> 32); + *cp++ = (uchar)(((*lp) & 0x00000000ff000000ULL) >> 24); + *cp++ = (uchar)(((*lp) & 0x0000000000ff0000ULL) >> 16); + *cp++ = (uchar)(((*lp) & 0x000000000000ff00ULL) >> 8); + *cp = (uchar)( (*lp) & 0x00000000000000ffULL); +#endif + } + *xpp = (void *)((char *)(*xpp) + sizeof_off_t); + return ENOERR; +} + +int +ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t) +{ + /* similar to get_ix_int() */ + const uchar *cp = (const uchar *) *xpp; + assert(sizeof_off_t == 4 || sizeof_off_t == 8); + + if (sizeof_off_t == 4) { + *lp = *cp++ << 24; + *lp |= (*cp++ << 16); + *lp |= (*cp++ << 8); + *lp |= *cp; + } else { +#if SIZEOF_OFF_T == 4 +/* Read a 64-bit offset on a system with only a 32-bit offset */ +/* If the offset overflows, set an error code and return */ + *lp = ((off_t)(*cp++) << 24); + *lp |= ((off_t)(*cp++) << 16); + *lp |= ((off_t)(*cp++) << 8); + *lp |= ((off_t)(*cp++)); +/* + * lp now contains the upper 32-bits of the 64-bit offset. if lp is + * not zero, then the dataset is larger than can be represented + * on this system. Set an error code and return. + */ + if (*lp != 0) { + return ERANGE; + } + + *lp = ((off_t)(*cp++) << 24); + *lp |= ((off_t)(*cp++) << 16); + *lp |= ((off_t)(*cp++) << 8); + *lp |= (off_t)*cp; + + if (*lp < 0) { + /* + * If this fails, then the offset is >2^31, but less + * than 2^32 which is not allowed, but is not caught + * by the previous check + */ + return ERANGE; + } +#else + *lp = ((off_t)(*cp++) << 56); + *lp |= ((off_t)(*cp++) << 48); + *lp |= ((off_t)(*cp++) << 40); + *lp |= ((off_t)(*cp++) << 32); + *lp |= ((off_t)(*cp++) << 24); + *lp |= ((off_t)(*cp++) << 16); + *lp |= ((off_t)(*cp++) << 8); + *lp |= (off_t)*cp; +#endif + } + *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t); + return ENOERR; +} + + +/* + * Aggregate numeric conversion functions. + */ + + + +/* schar */ + +int +ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp) +{ + (void) memcpy(tp, *xpp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + return ENOERR; + +} +int +ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp) +{ + (void) memcpy(tp, *xpp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + return ENOERR; + +} +int +ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp) +{ + schar *xp = (schar *)(*xpp); + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (const void *)xp; + return ENOERR; +} + +int +ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp) +{ + schar *xp = (schar *)(*xpp); + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (const void *)xp; + return ENOERR; +} + +int +ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp) +{ + schar *xp = (schar *)(*xpp); + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (const void *)xp; + return ENOERR; +} + +int +ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp) +{ + schar *xp = (schar *)(*xpp); + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (const void *)xp; + return ENOERR; +} + +int +ncx_getn_schar_uint(const void **xpp, size_t nelems, uint *tp) +{ + schar *xp = (schar *)(*xpp); + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (const void *)xp; + return ENOERR; +} + +int +ncx_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp) +{ + schar *xp = (schar *)(*xpp); + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (const void *)xp; + return ENOERR; +} + +int +ncx_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp) +{ + schar *xp = (schar *)(*xpp); + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (const void *)xp; + return ENOERR; +} + + +int +ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp) +{ + size_t rndup = nelems % X_ALIGN; + + if(rndup) + rndup = X_ALIGN - rndup; + + (void) memcpy(tp, *xpp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems + rndup); + + return ENOERR; + +} +int +ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp) +{ + size_t rndup = nelems % X_ALIGN; + + if(rndup) + rndup = X_ALIGN - rndup; + + (void) memcpy(tp, *xpp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems + rndup); + + return ENOERR; + +} +int +ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp) +{ + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (void *)(xp + rndup); + return ENOERR; +} + +int +ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp) +{ + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (void *)(xp + rndup); + return ENOERR; +} + +int +ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp) +{ + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (void *)(xp + rndup); + return ENOERR; +} + +int +ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp) +{ + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (void *)(xp + rndup); + return ENOERR; +} + +int +ncx_pad_getn_schar_uint(const void **xpp, size_t nelems, uint *tp) +{ + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (void *)(xp + rndup); + return ENOERR; +} + +int +ncx_pad_getn_schar_longlong(const void **xpp, size_t nelems, longlong *tp) +{ + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (void *)(xp + rndup); + return ENOERR; +} + +int +ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *tp) +{ + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + *tp++ = *xp++; + } + + *xpp = (void *)(xp + rndup); + return ENOERR; +} + + +int +ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp) +{ + (void) memcpy(*xpp, tp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + + return ENOERR; + +} +int +ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp) +{ + (void) memcpy(*xpp, tp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + + return ENOERR; + +} +int +ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp) +{ + int status = ENOERR; + schar *xp = (schar *) *xpp; + + while(nelems-- != 0) + { + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp) +{ + int status = ENOERR; + schar *xp = (schar *) *xpp; + + while(nelems-- != 0) + { + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp) +{ + int status = ENOERR; + schar *xp = (schar *) *xpp; + + while(nelems-- != 0) + { + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp) +{ + int status = ENOERR; + schar *xp = (schar *) *xpp; + + while(nelems-- != 0) + { + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_putn_schar_uint(void **xpp, size_t nelems, const uint *tp) +{ + int status = ENOERR; + schar *xp = (schar *) *xpp; + + while(nelems-- != 0) + { + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp) +{ + int status = ENOERR; + schar *xp = (schar *) *xpp; + + while(nelems-- != 0) + { + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp) +{ + int status = ENOERR; + schar *xp = (schar *) *xpp; + + while(nelems-- != 0) + { + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + *xpp = (void *)xp; + return status; +} + + +int +ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp) +{ + size_t rndup = nelems % X_ALIGN; + + if(rndup) + rndup = X_ALIGN - rndup; + + (void) memcpy(*xpp, tp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + + if(rndup) + { + (void) memcpy(*xpp, nada, rndup); + *xpp = (void *)((char *)(*xpp) + rndup); + } + + return ENOERR; + +} +int +ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp) +{ + size_t rndup = nelems % X_ALIGN; + + if(rndup) + rndup = X_ALIGN - rndup; + + (void) memcpy(*xpp, tp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + + if(rndup) + { + (void) memcpy(*xpp, nada, rndup); + *xpp = (void *)((char *)(*xpp) + rndup); + } + + return ENOERR; + +} +int +ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp) +{ + int status = ENOERR; + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + /* N.B. schar as signed */ + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + + if(rndup) + { + (void) memcpy(xp, nada, rndup); + xp += rndup; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp) +{ + int status = ENOERR; + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + /* N.B. schar as signed */ + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + + if(rndup) + { + (void) memcpy(xp, nada, rndup); + xp += rndup; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp) +{ + int status = ENOERR; + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + /* N.B. schar as signed */ + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + + if(rndup) + { + (void) memcpy(xp, nada, rndup); + xp += rndup; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp) +{ + int status = ENOERR; + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + /* N.B. schar as signed */ + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + + if(rndup) + { + (void) memcpy(xp, nada, rndup); + xp += rndup; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const uint *tp) +{ + int status = ENOERR; + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + /* N.B. schar as signed */ + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + + if(rndup) + { + (void) memcpy(xp, nada, rndup); + xp += rndup; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *tp) +{ + int status = ENOERR; + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + /* N.B. schar as signed */ + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + + if(rndup) + { + (void) memcpy(xp, nada, rndup); + xp += rndup; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *tp) +{ + int status = ENOERR; + size_t rndup = nelems % X_ALIGN; + schar *xp = (schar *) *xpp; + + if(rndup) + rndup = X_ALIGN - rndup; + + while(nelems-- != 0) + { + /* N.B. schar as signed */ + if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) + status = NC_ERANGE; + *xp++ = (schar) *tp++; + } + + + if(rndup) + { + (void) memcpy(xp, nada, rndup); + xp += rndup; + } + + *xpp = (void *)xp; + return status; +} + + + +/* short */ + +int +ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j SCHAR_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j UCHAR_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +#if X_SIZEOF_SHORT == SIZEOF_SHORT +/* optimized version */ +int +ncx_getn_short_short(const void **xpp, size_t nelems, short *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(tp, *xpp, nelems * sizeof(short)); +# else + swapn2b(tp, *xpp, nelems); +# endif + *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT); + return ENOERR; +} +#else +int +ncx_getn_short_short(const void **xpp, size_t nelems, short *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j SHORT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +#endif +int +ncx_getn_short_int(const void **xpp, size_t nelems, int *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j INT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_short_float(const void **xpp, size_t nelems, float *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j FLOAT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_short_double(const void **xpp, size_t nelems, double *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j DOUBLE_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_short_uint(const void **xpp, size_t nelems, uint *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j UINT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j LONGLONG_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j ULONGLONG_MAX; + } + /* update xpp and tp */ + if (realign) xp = (short *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + + +int +ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_getn_short_uint(const void **xpp, size_t nelems, uint *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_getn_short_longlong(const void **xpp, size_t nelems, longlong *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *tp) +{ + const size_t rndup = nelems % 2; + + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + const int lstatus = ncx_get_short_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + xp += X_SIZEOF_SHORT; + + *xpp = (void *)xp; + return status; +} + + +int +ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +#if X_SIZEOF_SHORT == SIZEOF_SHORT +/* optimized version */ +int +ncx_putn_short_short(void **xpp, size_t nelems, const short *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(*xpp, tp, nelems * X_SIZEOF_SHORT); +# else + swapn2b(*xpp, tp, nelems); +# endif + *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT); + return ENOERR; +} +#else +int +ncx_putn_short_short(void **xpp, size_t nelems, const short *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +#endif +int +ncx_putn_short_int(void **xpp, size_t nelems, const int *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_short_float(void **xpp, size_t nelems, const float *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_short_double(void **xpp, size_t nelems, const double *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_short_uint(void **xpp, size_t nelems, const uint *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp) +{ +#if _SX && \ + X_SIZEOF_SHORT == SIZEOF_SHORT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + short tmp[LOOPCNT]; /* in case input is misaligned */ + short *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_SHORT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_SHORT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_SHORT); + xp = (short *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + + +int +ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_short_uint(void **xpp, size_t nelems, const uint *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_short_longlong(void **xpp, size_t nelems, const longlong *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + +int +ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *tp) +{ + const size_t rndup = nelems % 2; + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) + { + int lstatus = ncx_put_short_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + if(rndup != 0) + { + (void) memcpy(xp, nada, X_SIZEOF_SHORT); + xp += X_SIZEOF_SHORT; + } + + *xpp = (void *)xp; + return status; +} + + + +/* int */ + +int +ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j SCHAR_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j UCHAR_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_int_short(const void **xpp, size_t nelems, short *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j SHORT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +#if X_SIZEOF_INT == SIZEOF_INT +/* optimized version */ +int +ncx_getn_int_int(const void **xpp, size_t nelems, int *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(tp, *xpp, nelems * sizeof(int)); +# else + swapn4b(tp, *xpp, nelems); +# endif + *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT); + return ENOERR; +} +int +ncx_getn_int_uint(const void **xpp, size_t nelems, unsigned int *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(tp, *xpp, nelems * sizeof(int)); +# else + swapn4b(tp, *xpp, nelems); +# endif + *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT); + return ENOERR; +} +#else +int +ncx_getn_int_int(const void **xpp, size_t nelems, int *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j INT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_int_uint(const void **xpp, size_t nelems, uint *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j UINT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +#endif + +int +ncx_getn_int_longlong(const void **xpp, size_t nelems, longlong *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j LONGLONG_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j ULONGLONG_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + + +int +ncx_getn_int_float(const void **xpp, size_t nelems, float *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j FLOAT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_int_double(const void **xpp, size_t nelems, double *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j DOUBLE_MAX; + } + /* update xpp and tp */ + if (realign) xp = (int *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + const int lstatus = ncx_get_int_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + + +int +ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_int_short(void **xpp, size_t nelems, const short *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +#if X_SIZEOF_INT == SIZEOF_INT +/* optimized version */ +int +ncx_putn_int_int(void **xpp, size_t nelems, const int *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(*xpp, tp, nelems * X_SIZEOF_INT); +# else + swapn4b(*xpp, tp, nelems); +# endif + *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT); + return ENOERR; +} +int +ncx_putn_int_uint(void **xpp, size_t nelems, const unsigned int *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(*xpp, tp, nelems * X_SIZEOF_INT); +# else + swapn4b(*xpp, tp, nelems); +# endif + *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT); + return ENOERR; +} +#else +int +ncx_putn_int_int(void **xpp, size_t nelems, const int *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_int_uint(void **xpp, size_t nelems, const uint *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +#endif + +int +ncx_putn_int_longlong(void **xpp, size_t nelems, const longlong *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_int_float(void **xpp, size_t nelems, const float *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + double d; /* special case for ncx_putn_int_float */ + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_int_double(void **xpp, size_t nelems, const double *tp) +{ +#if _SX && \ + X_SIZEOF_INT == SIZEOF_INT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + int tmp[LOOPCNT]; /* in case input is misaligned */ + int *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_INT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_INT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_INT); + xp = (int *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) + { + int lstatus = ncx_put_int_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + + + +/* float */ + +int +ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j SCHAR_MAX; + } + /* update xpp and tp */ + if (realign) xp = (float *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j UCHAR_MAX; + } + /* update xpp and tp */ + if (realign) xp = (float *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_float_short(const void **xpp, size_t nelems, short *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j SHORT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (float *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_float_int(const void **xpp, size_t nelems, int *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j INT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (float *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) +/* optimized version */ +int +ncx_getn_float_float(const void **xpp, size_t nelems, float *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(tp, *xpp, nelems * sizeof(float)); +# else + swapn4b(tp, *xpp, nelems); +# endif + *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT); + return ENOERR; +} +#elif vax +int +ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip) +{ + float *const end = ip + nfloats; + + while(ip < end) + { + struct vax_single *const vsp = (struct vax_single *) ip; + const struct ieee_single *const isp = + (const struct ieee_single *) (*xpp); + unsigned exp = isp->exp_hi << 1 | isp->exp_lo; + + switch(exp) { + case 0 : + /* ieee subnormal */ + if(isp->mant_hi == min.ieee.mant_hi + && isp->mant_lo_hi == min.ieee.mant_lo_hi + && isp->mant_lo_lo == min.ieee.mant_lo_lo) + { + *vsp = min.s; + } + else + { + unsigned mantissa = (isp->mant_hi << 16) + | isp->mant_lo_hi << 8 + | isp->mant_lo_lo; + unsigned tmp = mantissa >> 20; + if(tmp >= 4) { + vsp->exp = 2; + } else if (tmp >= 2) { + vsp->exp = 1; + } else { + *vsp = min.s; + break; + } /* else */ + tmp = mantissa - (1 << (20 + vsp->exp )); + tmp <<= 3 - vsp->exp; + vsp->mantissa2 = tmp; + vsp->mantissa1 = (tmp >> 16); + } + break; + case 0xfe : + case 0xff : + *vsp = max.s; + break; + default : + vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; + vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo; + vsp->mantissa1 = isp->mant_hi; + } + + vsp->sign = isp->sign; + + + ip++; + *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT; + } + return ENOERR; +} +#else +int +ncx_getn_float_float(const void **xpp, size_t nelems, float *tp) +{ + const char *xp = *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +} + +#endif +int +ncx_getn_float_double(const void **xpp, size_t nelems, double *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j DOUBLE_MAX; + } + /* update xpp and tp */ + if (realign) xp = (float *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_float_uint(const void **xpp, size_t nelems, uint *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j UINT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (float *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_float_longlong(const void **xpp, size_t nelems, longlong *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j LONGLONG_MAX; + } + /* update xpp and tp */ + if (realign) xp = (float *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j ULONGLONG_MAX; + } + /* update xpp and tp */ + if (realign) xp = (float *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + const int lstatus = ncx_get_float_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + + +int +ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_FLOAT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_FLOAT); + xp = (float *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_FLOAT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_FLOAT); + xp = (float *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_float_short(void **xpp, size_t nelems, const short *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_FLOAT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_FLOAT); + xp = (float *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_float_int(void **xpp, size_t nelems, const int *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_FLOAT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_FLOAT); + xp = (float *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT) +/* optimized version */ +int +ncx_putn_float_float(void **xpp, size_t nelems, const float *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(*xpp, tp, nelems * X_SIZEOF_FLOAT); +# else + swapn4b(*xpp, tp, nelems); +# endif + *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT); + return ENOERR; +} +#elif vax +int +ncx_putn_float_float(void **xpp, size_t nfloats, const float *ip) +{ + const float *const end = ip + nfloats; + + while(ip < end) + { + const struct vax_single *const vsp = + (const struct vax_single *)ip; + struct ieee_single *const isp = (struct ieee_single *) (*xpp); + + switch(vsp->exp){ + case 0 : + /* all vax float with zero exponent map to zero */ + *isp = min.ieee; + break; + case 2 : + case 1 : + { + /* These will map to subnormals */ + unsigned mantissa = (vsp->mantissa1 << 16) + | vsp->mantissa2; + mantissa >>= 3 - vsp->exp; + mantissa += (1 << (20 + vsp->exp)); + isp->mant_lo_lo = mantissa; + isp->mant_lo_hi = mantissa >> 8; + isp->mant_hi = mantissa >> 16; + isp->exp_lo = 0; + isp->exp_hi = 0; + } + break; + case 0xff : /* max.s.exp */ + if( vsp->mantissa2 == max.s.mantissa2 + && vsp->mantissa1 == max.s.mantissa1) + { + /* map largest vax float to ieee infinity */ + *isp = max.ieee; + break; + } /* else, fall thru */ + default : + { + unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; + isp->exp_hi = exp >> 1; + isp->exp_lo = exp; + isp->mant_lo_lo = vsp->mantissa2; + isp->mant_lo_hi = vsp->mantissa2 >> 8; + isp->mant_hi = vsp->mantissa1; + } + } + + isp->sign = vsp->sign; + + + ip++; + *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT; + } + return ENOERR; +} +#else +int +ncx_putn_float_float(void **xpp, size_t nelems, const float *tp) +{ + char *xp = *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +} + +#endif +int +ncx_putn_float_double(void **xpp, size_t nelems, const double *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_FLOAT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_FLOAT); + xp = (float *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_float_uint(void **xpp, size_t nelems, const uint *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_FLOAT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_FLOAT); + xp = (float *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_float_longlong(void **xpp, size_t nelems, const longlong *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_FLOAT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_FLOAT); + xp = (float *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *tp) +{ +#if _SX && \ + X_SIZEOF_FLOAT == SIZEOF_FLOAT + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + float tmp[LOOPCNT]; /* in case input is misaligned */ + float *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_FLOAT; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_FLOAT_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_FLOAT); + xp = (float *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) + { + int lstatus = ncx_put_float_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + + +/* double */ + +int +ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j SCHAR_MAX; + } + /* update xpp and tp */ + if (realign) xp = (double *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j UCHAR_MAX; + } + /* update xpp and tp */ + if (realign) xp = (double *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_double_short(const void **xpp, size_t nelems, short *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j SHORT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (double *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_double_int(const void **xpp, size_t nelems, int *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j INT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (double *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_double_float(const void **xpp, size_t nelems, float *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j FLOAT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (double *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_double_uint(const void **xpp, size_t nelems, uint *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j UINT_MAX; + } + /* update xpp and tp */ + if (realign) xp = (double *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_double_longlong(const void **xpp, size_t nelems, longlong *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j LONGLONG_MAX; + } + /* update xpp and tp */ + if (realign) xp = (double *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +int +ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of input data + * - copy (conversion happens automatically) input data + * to output + * - update xpp to point at next unconverted input, and tp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j ULONGLONG_MAX; + } + /* update xpp and tp */ + if (realign) xp = (double *) *xpp; + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + const char *xp = (const char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +# endif +} + +#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) +/* optimized version */ +int +ncx_getn_double_double(const void **xpp, size_t nelems, double *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(tp, *xpp, nelems * sizeof(double)); +# else + swapn8b(tp, *xpp, nelems); +# endif + *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); + return ENOERR; +} +#elif vax +int +ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip) +{ + double *const end = ip + ndoubles; + + while(ip < end) + { + struct vax_double *const vdp = + (struct vax_double *)ip; + const struct ieee_double *const idp = + (const struct ieee_double *) (*xpp); + { + const struct dbl_limits *lim; + int ii; + for (ii = 0, lim = dbl_limits; + ii < sizeof(dbl_limits)/sizeof(struct dbl_limits); + ii++, lim++) + { + if ((idp->mant_lo == lim->ieee.mant_lo) + && (idp->mant_4 == lim->ieee.mant_4) + && (idp->mant_5 == lim->ieee.mant_5) + && (idp->mant_6 == lim->ieee.mant_6) + && (idp->exp_lo == lim->ieee.exp_lo) + && (idp->exp_hi == lim->ieee.exp_hi) + ) + { + *vdp = lim->d; + goto doneit; + } + } + } + { + unsigned exp = idp->exp_hi << 4 | idp->exp_lo; + vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; + } + { + unsigned mant_hi = ((idp->mant_6 << 16) + | (idp->mant_5 << 8) + | idp->mant_4); + unsigned mant_lo = SWAP4(idp->mant_lo); + vdp->mantissa1 = (mant_hi >> 13); + vdp->mantissa2 = ((mant_hi & MASK(13)) << 3) + | (mant_lo >> 29); + vdp->mantissa3 = (mant_lo >> 13); + vdp->mantissa4 = (mant_lo << 3); + } + doneit: + vdp->sign = idp->sign; + + ip++; + *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE; + } + return ENOERR; +} + /* vax */ +#else +int +ncx_getn_double_double(const void **xpp, size_t nelems, double *tp) +{ + const char *xp = *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + const int lstatus = ncx_get_double_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (const void *)xp; + return status; +} + +#endif + +int +ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_DOUBLE_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_DOUBLE); + xp = (double *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_schar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_DOUBLE_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_DOUBLE); + xp = (double *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_uchar(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_double_short(void **xpp, size_t nelems, const short *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_DOUBLE_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_DOUBLE); + xp = (double *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_short(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_double_int(void **xpp, size_t nelems, const int *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_DOUBLE_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_DOUBLE); + xp = (double *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_int(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_double_float(void **xpp, size_t nelems, const float *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_DOUBLE_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_DOUBLE); + xp = (double *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_float(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_double_uint(void **xpp, size_t nelems, const uint *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_DOUBLE_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_DOUBLE); + xp = (double *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_uint(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_double_longlong(void **xpp, size_t nelems, const longlong *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_DOUBLE_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_DOUBLE); + xp = (double *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_longlong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +int +ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *tp) +{ +#if _SX && \ + X_SIZEOF_DOUBLE == SIZEOF_DOUBLE + + /* basic algorithm is: + * - ensure sane alignment of output data + * - copy (conversion happens automatically) input data + * to output + * - update tp to point at next unconverted input, and xpp to point + * at next location for converted output + */ + long i, j, ni; + double tmp[LOOPCNT]; /* in case input is misaligned */ + double *xp; + int nrange = 0; /* number of range errors */ + int realign = 0; /* "do we need to fix input data alignment?" */ + long cxp = (long) *((char**)xpp); + + realign = (cxp & 7) % SIZEOF_DOUBLE; + /* sjl: manually stripmine so we can limit amount of + * vector work space reserved to LOOPCNT elements. Also + * makes vectorisation easy */ + for (j=0; j X_DOUBLE_MAX; + } + /* copy workspace back if necessary */ + if (realign) { + memcpy(*xpp, tmp, ni*X_SIZEOF_DOUBLE); + xp = (double *) *xpp; + } + /* update xpp and tp */ + xp += ni; + tp += ni; + *xpp = (void*)xp; + } + return nrange == 0 ? ENOERR : NC_ERANGE; + +#else /* not SX */ + + char *xp = (char *) *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_ulonglong(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +#endif +} + +#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) +/* optimized version */ +int +ncx_putn_double_double(void **xpp, size_t nelems, const double *tp) +{ +#ifdef WORDS_BIGENDIAN + (void) memcpy(*xpp, tp, nelems * X_SIZEOF_DOUBLE); +# else + swapn8b(*xpp, tp, nelems); +# endif + *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); + return ENOERR; +} +#elif vax +int +ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip) +{ + const double *const end = ip + ndoubles; + + while(ip < end) + { + const struct vax_double *const vdp = + (const struct vax_double *)ip; + struct ieee_double *const idp = + (struct ieee_double *) (*xpp); + + if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) && + (vdp->mantissa3 == dbl_limits[0].d.mantissa3) && + (vdp->mantissa2 == dbl_limits[0].d.mantissa2) && + (vdp->mantissa1 == dbl_limits[0].d.mantissa1) && + (vdp->exp == dbl_limits[0].d.exp)) + { + *idp = dbl_limits[0].ieee; + goto shipit; + } + if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) && + (vdp->mantissa3 == dbl_limits[1].d.mantissa3) && + (vdp->mantissa2 == dbl_limits[1].d.mantissa2) && + (vdp->mantissa1 == dbl_limits[1].d.mantissa1) && + (vdp->exp == dbl_limits[1].d.exp)) + { + *idp = dbl_limits[1].ieee; + goto shipit; + } + + { + unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; + + unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) | + (vdp->mantissa3 << 13) | + ((vdp->mantissa4 >> 3) & MASK(13)); + + unsigned mant_hi = (vdp->mantissa1 << 13) + | (vdp->mantissa2 >> 3); + + if((vdp->mantissa4 & 7) > 4) + { + /* round up */ + mant_lo++; + if(mant_lo == 0) + { + mant_hi++; + if(mant_hi > 0xffffff) + { + mant_hi = 0; + exp++; + } + } + } + + idp->mant_lo = SWAP4(mant_lo); + idp->mant_6 = mant_hi >> 16; + idp->mant_5 = (mant_hi & 0xff00) >> 8; + idp->mant_4 = mant_hi; + idp->exp_hi = exp >> 4; + idp->exp_lo = exp; + } + + shipit: + idp->sign = vdp->sign; + + ip++; + *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE; + } + return ENOERR; +} + /* vax */ +#else +int +ncx_putn_double_double(void **xpp, size_t nelems, const double *tp) +{ + char *xp = *xpp; + int status = ENOERR; + + for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) + { + int lstatus = ncx_put_double_double(xp, tp); + if(lstatus != ENOERR) + status = lstatus; + } + + *xpp = (void *)xp; + return status; +} + +#endif + + +/* + * Other aggregate conversion functions. + */ + +/* text */ + +int +ncx_getn_text(const void **xpp, size_t nelems, char *tp) +{ + (void) memcpy(tp, *xpp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + return ENOERR; + +} + +int +ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp) +{ + size_t rndup = nelems % X_ALIGN; + + if(rndup) + rndup = X_ALIGN - rndup; + + (void) memcpy(tp, *xpp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems + rndup); + + return ENOERR; + +} + +int +ncx_putn_text(void **xpp, size_t nelems, const char *tp) +{ + (void) memcpy(*xpp, tp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + + return ENOERR; + +} + +int +ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp) +{ + size_t rndup = nelems % X_ALIGN; + + if(rndup) + rndup = X_ALIGN - rndup; + + (void) memcpy(*xpp, tp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + + if(rndup) + { + (void) memcpy(*xpp, nada, rndup); + *xpp = (void *)((char *)(*xpp) + rndup); + } + + return ENOERR; + +} + + +/* opaque */ + +int +ncx_getn_void(const void **xpp, size_t nelems, void *tp) +{ + (void) memcpy(tp, *xpp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + return ENOERR; + +} + +int +ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp) +{ + size_t rndup = nelems % X_ALIGN; + + if(rndup) + rndup = X_ALIGN - rndup; + + (void) memcpy(tp, *xpp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems + rndup); + + return ENOERR; + +} + +int +ncx_putn_void(void **xpp, size_t nelems, const void *tp) +{ + (void) memcpy(*xpp, tp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + + return ENOERR; + +} + +int +ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp) +{ + size_t rndup = nelems % X_ALIGN; + + if(rndup) + rndup = X_ALIGN - rndup; + + (void) memcpy(*xpp, tp, nelems); + *xpp = (void *)((char *)(*xpp) + nelems); + + if(rndup) + { + (void) memcpy(*xpp, nada, rndup); + *xpp = (void *)((char *)(*xpp) + rndup); + } + + return ENOERR; + +} diff --git a/extern/src_netcdf4/ncx.h b/extern/src_netcdf4/ncx.h new file mode 100644 index 0000000000000000000000000000000000000000..746df5f2b049545503196b2711954181567d12b7 --- /dev/null +++ b/extern/src_netcdf4/ncx.h @@ -0,0 +1,753 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* "$Id: ncx.h,v 1.65 2010/05/26 18:11:08 dmh Exp $" */ + +#ifndef _NCX_H_ +#define _NCX_H_ + +#include "ncdispatch.h" +#include "ncio.h" +#include "fbits.h" + +/* + * An external data representation interface. + + * + * This started out as a general replacement for ONC XDR, + * specifically, the xdrmem family of functions. + * + * We eventually realized that we could write more portable + * code if we decoupled any association between the 'C' types + * and the external types. (XDR has this association between the 'C' + * types and the external representations, like xdr_int() takes + * an int argument and goes to an external int representation.) + * So, now there is a matrix of functions. + * + */ + +#include /* output of 'configure' */ +#include "rnd.h" +#include /* size_t */ +#include +#include /* off_t */ +#include +#define longlong long long + +#if defined(_CRAY) && !defined(_CRAYIEEE) && !defined(__crayx1) +#define CRAYFLOAT 1 /* CRAY Floating point */ +#elif defined(_SX) && defined(_FLOAT2) /* NEC SUPER-UX in CRAY mode */ +#define CRAYFLOAT 1 /* CRAY Floating point */ +#endif + +/* + * The integer return code for the conversion routines + * is 0 (ENOERR) when no error occured, or NC_ERANGE as appropriate + * for an overflow conversion. + */ +#ifndef ENOERR +#define ENOERR 0 +#endif +#ifndef NC_ERANGE +#define NC_ERANGE (-60) /* N.B. must match value in netcdf.h */ +#endif +#ifndef NC_ENOMEM +#define NC_ENOMEM (-61) /* N.B. must match value in netcdf.h */ +#endif + + +/* + * External sizes of the primitive elements. + */ +#define X_SIZEOF_CHAR 1 +#define X_SIZEOF_SHORT 2 +#define X_SIZEOF_INT 4 /* xdr_int */ +#if 0 +#define X_SIZEOF_LONG 8 */ /* xdr_long_long */ +#endif +#define X_SIZEOF_FLOAT 4 +#define X_SIZEOF_DOUBLE 8 + +/* + * For now, netcdf is limited to 32 bit sizes, + * If compiled with support for "large files", then + * netcdf will use a 64 bit off_t and it can then write a file + * using 64 bit offsets. + * see also X_SIZE_MAX, X_OFF_MAX below + */ +#define X_SIZEOF_OFF_T (sizeof(off_t)) +#define X_SIZEOF_SIZE_T X_SIZEOF_INT + +/* + * limits of the external representation + */ +#define X_SCHAR_MIN (-128) +#define X_SCHAR_MAX 127 +#define X_UCHAR_MAX 255U +#define X_SHORT_MIN (-32768) +#define X_SHRT_MIN X_SHORT_MIN /* alias compatible with limits.h */ +#define X_SHORT_MAX 32767 +#define X_SHRT_MAX X_SHORT_MAX /* alias compatible with limits.h */ +#define X_USHORT_MAX 65535U +#define X_USHRT_MAX X_USHORT_MAX /* alias compatible with limits.h */ +#define X_INT_MIN (-2147483647-1) +#define X_INT_MAX 2147483647 +#define X_UINT_MAX 4294967295U +#define X_LONGLONG_MIN (-9223372036854775807LL-1LL) +#define X_LONGLONG_MAX 9223372036854775807LL +#define X_ULONGLONG_MAX 18446744073709551615ULL +#define X_FLOAT_MAX 3.402823466e+38f +#define X_FLOAT_MIN (-X_FLOAT_MAX) +#define X_FLT_MAX X_FLOAT_MAX /* alias compatible with limits.h */ +#if CRAYFLOAT +/* ldexp(1. - ldexp(.5 , -46), 1024) */ +#define X_DOUBLE_MAX 1.79769313486230e+308 +#else +/* scalb(1. - scalb(.5 , -52), 1024) */ +#define X_DOUBLE_MAX 1.7976931348623157e+308 +#endif +#define X_DOUBLE_MIN (-X_DOUBLE_MAX) +#define X_DBL_MAX X_DOUBLE_MAX /* alias compatible with limits.h */ + +#define X_SIZE_MAX X_UINT_MAX +#define X_OFF_MAX X_INT_MAX + + +/* Begin ncx_len */ + +/* + * ncx_len_xxx() interfaces are defined as macros below, + * These give the length of an array of nelems of the type. + * N.B. The 'char' and 'short' interfaces give the X_ALIGNED length. + */ +#define X_ALIGN 4 /* a.k.a. BYTES_PER_XDR_UNIT */ + +#define ncx_len_char(nelems) \ + _RNDUP((nelems), X_ALIGN) + +#define ncx_len_short(nelems) \ + (((nelems) + (nelems)%2) * X_SIZEOF_SHORT) + +#define ncx_len_int(nelems) \ + ((nelems) * X_SIZEOF_INT) + +#define ncx_len_long(nelems) \ + ((nelems) * X_SIZEOF_LONG) + +#define ncx_len_float(nelems) \ + ((nelems) * X_SIZEOF_FLOAT) + +#define ncx_len_double(nelems) \ + ((nelems) * X_SIZEOF_DOUBLE) + +/* End ncx_len */ + +#if __CHAR_UNSIGNED__ + /* 'char' is unsigned, declare ncbyte as 'signed char' */ +typedef signed char schar; + +#else + /* 'char' is signed */ +typedef signed char schar; + +#endif /* __CHAR_UNSIGNED__ */ + +/* + * Primitive numeric conversion functions. + * The `put' functions convert from native internal + * type to the external type, while the `get' functions + * convert from the external to the internal. + * + * These take the form + * int ncx_get_{external_type}_{internal_type}( + * const void *xp, + * internal_type *ip + * ); + * int ncx_put_{external_type}_{internal_type}( + * void *xp, + * const internal_type *ip + * ); + * where + * `external_type' and `internal_type' chosen from + schar + uchar + short + ushort + int + uint + long + ulong + float + double + * + * Not all combinations make sense. + * We may not implement all combinations that make sense. + * The netcdf functions that use this ncx interface don't + * use these primitive conversion functions. They use the + * aggregate conversion functions declared below. + * + * Storage for a single element of external type is at the `void * xp' + * argument. + * + * Storage for a single element of internal type is at `ip' argument. + * + * These functions return 0 (ENOERR) when no error occured, + * or NC_ERANGE when the value being converted is too large. + * When NC_ERANGE occurs, an undefined (implementation dependent) + * conversion may have occured. + * + * Note that loss of precision may occur silently. + * + */ + +#if 0 +extern int +ncx_get_schar_schar(const void *xp, schar *ip); +extern int +ncx_get_schar_uchar(const void *xp, uchar *ip); +extern int +ncx_get_schar_short(const void *xp, short *ip); +extern int +ncx_get_schar_int(const void *xp, int *ip); +extern int +ncx_get_schar_long(const void *xp, long *ip); +extern int +ncx_get_schar_float(const void *xp, float *ip); +extern int +ncx_get_schar_double(const void *xp, double *ip); + +extern int +ncx_put_schar_schar(void *xp, const schar *ip); +extern int +ncx_put_schar_uchar(void *xp, const uchar *ip); +extern int +ncx_put_schar_short(void *xp, const short *ip); +extern int +ncx_put_schar_int(void *xp, const int *ip); +extern int +ncx_put_schar_long(void *xp, const long *ip); +extern int +ncx_put_schar_float(void *xp, const float *ip); +extern int +ncx_put_schar_double(void *xp, const double *ip); +#endif + + +extern int +ncx_get_short_schar(const void *xp, schar *ip); +extern int +ncx_get_short_uchar(const void *xp, uchar *ip); +extern int +ncx_get_short_short(const void *xp, short *ip); +extern int +ncx_get_short_int(const void *xp, int *ip); +extern int +ncx_get_short_long(const void *xp, long *ip); +extern int +ncx_get_short_float(const void *xp, float *ip); +extern int +ncx_get_short_double(const void *xp, double *ip); + +extern int +ncx_put_short_schar(void *xp, const schar *ip); +extern int +ncx_put_short_uchar(void *xp, const uchar *ip); +extern int +ncx_put_short_short(void *xp, const short *ip); +extern int +ncx_put_short_int(void *xp, const int *ip); +extern int +ncx_put_short_long(void *xp, const long *ip); +extern int +ncx_put_short_float(void *xp, const float *ip); +extern int +ncx_put_short_double(void *xp, const double *ip); + + +extern int +ncx_get_int_schar(const void *xp, schar *ip); +extern int +ncx_get_int_uchar(const void *xp, uchar *ip); +extern int +ncx_get_int_short(const void *xp, short *ip); +extern int +ncx_get_int_int(const void *xp, int *ip); +extern int +ncx_get_int_long(const void *xp, long *ip); +extern int +ncx_get_int_float(const void *xp, float *ip); +extern int +ncx_get_int_double(const void *xp, double *ip); + +extern int +ncx_put_int_schar(void *xp, const schar *ip); +extern int +ncx_put_int_uchar(void *xp, const uchar *ip); +extern int +ncx_put_int_short(void *xp, const short *ip); +extern int +ncx_put_int_int(void *xp, const int *ip); +extern int +ncx_put_int_long(void *xp, const long *ip); +extern int +ncx_put_int_float(void *xp, const float *ip); +extern int +ncx_put_int_double(void *xp, const double *ip); + + +extern int +ncx_get_float_schar(const void *xp, schar *ip); +extern int +ncx_get_float_uchar(const void *xp, uchar *ip); +extern int +ncx_get_float_short(const void *xp, short *ip); +extern int +ncx_get_float_int(const void *xp, int *ip); +extern int +ncx_get_float_long(const void *xp, long *ip); +extern int +ncx_get_float_float(const void *xp, float *ip); +extern int +ncx_get_float_double(const void *xp, double *ip); + +extern int +ncx_put_float_schar(void *xp, const schar *ip); +extern int +ncx_put_float_uchar(void *xp, const uchar *ip); +extern int +ncx_put_float_short(void *xp, const short *ip); +extern int +ncx_put_float_int(void *xp, const int *ip); +extern int +ncx_put_float_long(void *xp, const long *ip); +extern int +ncx_put_float_float(void *xp, const float *ip); +extern int +ncx_put_float_double(void *xp, const double *ip); + + +extern int +ncx_get_double_schar(const void *xp, schar *ip); +extern int +ncx_get_double_uchar(const void *xp, uchar *ip); +extern int +ncx_get_double_short(const void *xp, short *ip); +extern int +ncx_get_double_int(const void *xp, int *ip); +extern int +ncx_get_double_long(const void *xp, long *ip); +extern int +ncx_get_double_float(const void *xp, float *ip); +extern int +ncx_get_double_double(const void *xp, double *ip); + +extern int +ncx_put_double_schar(void *xp, const schar *ip); +extern int +ncx_put_double_uchar(void *xp, const uchar *ip); +extern int +ncx_put_double_short(void *xp, const short *ip); +extern int +ncx_put_double_int(void *xp, const int *ip); +extern int +ncx_put_double_long(void *xp, const long *ip); +extern int +ncx_put_double_float(void *xp, const float *ip); +extern int +ncx_put_double_double(void *xp, const double *ip); + + +/* + * Other primitive conversion functions + * N.B. slightly different interface + * Used by netcdf. + */ + +/* ncx_get_int_size_t */ +extern int +ncx_get_size_t(const void **xpp, size_t *ulp); +/* ncx_get_int_off_t */ +extern int +ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t); + +/* ncx_put_int_size_t */ +extern int +ncx_put_size_t(void **xpp, const size_t *ulp); +/* ncx_put_int_off_t */ +extern int +ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t); + + +/* + * Aggregate numeric conversion functions. + * Convert an array. Replaces xdr_array(...). + * These functions are used by netcdf. Unlike the xdr + * interface, we optimize for aggregate conversions. + * This functions should be implemented to take advantage + * of multiple processor / parallel hardware where available. + * + * These take the form + * int ncx_getn_{external_type}_{internal_type}( + * const void *xpp, + * size_t nelems, + * internal_type *ip + * ); + * int ncx_putn_{external_type}_{internal_type}( + * void **xpp, + * size_t nelems, + * const internal_type *ip + * ); + * Where the types are as in the primitive numeric conversion functions. + * + * The value of the pointer to pointer argument, *xpp, is + * expected to reference storage for `nelems' of the external + * type. On return, it modified to reference just past the last + * converted external element. + * + * The types whose external size is less than X_ALIGN also have `pad' + * interfaces. These round (and zero fill on put) *xpp up to X_ALIGN + * boundaries. (This is the usual xdr behavior.) + * + * The `ip' argument should point to an array of `nelems' of + * internal_type. + * + * Range errors (NC_ERANGE) for a individual values in the array + * DO NOT terminate the array conversion. All elements are converted, + * with some having undefined values. + * If any range error occurs, the function returns NC_ERANGE. + * + */ + +extern int +ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *ip); +extern int +ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *ip); +extern int +ncx_getn_schar_short(const void **xpp, size_t nelems, short *ip); +extern int +ncx_getn_schar_int(const void **xpp, size_t nelems, int *ip); +extern int +ncx_getn_schar_long(const void **xpp, size_t nelems, long *ip); +extern int +ncx_getn_schar_float(const void **xpp, size_t nelems, float *ip); +extern int +ncx_getn_schar_double(const void **xpp, size_t nelems, double *ip); +extern int +ncx_getn_schar_uint(const void **xpp, size_t nelems, unsigned int *ip); +extern int +ncx_getn_schar_longlong(const void **xpp, size_t nelems, longlong *ip); +extern int +ncx_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); + +extern int +ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *ip); +extern int +ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *ip); +extern int +ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *ip); +extern int +ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *ip); +extern int +ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *ip); +extern int +ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *ip); +extern int +ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *ip); +extern int +ncx_pad_getn_schar_uint(const void **xpp, size_t nelems, unsigned int *ip); +extern int +ncx_pad_getn_schar_longlong(const void **xpp, size_t nelems, longlong *ip); +extern int +ncx_pad_getn_schar_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); + +extern int +ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *ip); +extern int +ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *ip); +extern int +ncx_putn_schar_short(void **xpp, size_t nelems, const short *ip); +extern int +ncx_putn_schar_int(void **xpp, size_t nelems, const int *ip); +extern int +ncx_putn_schar_long(void **xpp, size_t nelems, const long *ip); +extern int +ncx_putn_schar_float(void **xpp, size_t nelems, const float *ip); +extern int +ncx_putn_schar_double(void **xpp, size_t nelems, const double *ip); +extern int +ncx_putn_schar_uint(void **xpp, size_t nelems, const unsigned int *ip); +extern int +ncx_putn_schar_longlong(void **xpp, size_t nelems, const longlong *ip); +extern int +ncx_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); + +extern int +ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *ip); +extern int +ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *ip); +extern int +ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *ip); +extern int +ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *ip); +extern int +ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *ip); +extern int +ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *ip); +extern int +ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *ip); +extern int +ncx_pad_putn_schar_uint(void **xpp, size_t nelems, const unsigned int *ip); +extern int +ncx_pad_putn_schar_longlong(void **xpp, size_t nelems, const longlong *ip); +extern int +ncx_pad_putn_schar_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); + + +extern int +ncx_getn_short_schar(const void **xpp, size_t nelems, schar *ip); +extern int +ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *ip); +extern int +ncx_getn_short_short(const void **xpp, size_t nelems, short *ip); +extern int +ncx_getn_short_int(const void **xpp, size_t nelems, int *ip); +extern int +ncx_getn_short_long(const void **xpp, size_t nelems, long *ip); +extern int +ncx_getn_short_float(const void **xpp, size_t nelems, float *ip); +extern int +ncx_getn_short_double(const void **xpp, size_t nelems, double *ip); +extern int +ncx_getn_short_uint(const void **xpp, size_t nelems, unsigned int *ip); +extern int +ncx_getn_short_longlong(const void **xpp, size_t nelems, longlong *ip); +extern int +ncx_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); + +extern int +ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *ip); +extern int +ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *ip); +extern int +ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *ip); +extern int +ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *ip); +extern int +ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *ip); +extern int +ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *ip); +extern int +ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *ip); +extern int +ncx_pad_getn_short_uint(const void **xpp, size_t nelems, unsigned int *ip); +extern int +ncx_pad_getn_short_longlong(const void **xpp, size_t nelems, longlong *ip); +extern int +ncx_pad_getn_short_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); + +extern int +ncx_putn_short_schar(void **xpp, size_t nelems, const schar *ip); +extern int +ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *ip); +extern int +ncx_putn_short_short(void **xpp, size_t nelems, const short *ip); +extern int +ncx_putn_short_int(void **xpp, size_t nelems, const int *ip); +extern int +ncx_putn_short_long(void **xpp, size_t nelems, const long *ip); +extern int +ncx_putn_short_float(void **xpp, size_t nelems, const float *ip); +extern int +ncx_putn_short_double(void **xpp, size_t nelems, const double *ip); +extern int +ncx_putn_short_uint(void **xpp, size_t nelems, const unsigned int *ip); +extern int +ncx_putn_short_longlong(void **xpp, size_t nelems, const longlong *ip); +extern int +ncx_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); + +extern int +ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *ip); +extern int +ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *ip); +extern int +ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *ip); +extern int +ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *ip); +extern int +ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *ip); +extern int +ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *ip); +extern int +ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *ip); +extern int +ncx_pad_putn_short_uint(void **xpp, size_t nelems, const unsigned int *ip); +extern int +ncx_pad_putn_short_longlong(void **xpp, size_t nelems, const longlong *ip); +extern int +ncx_pad_putn_short_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); + + +extern int +ncx_getn_int_schar(const void **xpp, size_t nelems, schar *ip); +extern int +ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *ip); +extern int +ncx_getn_int_short(const void **xpp, size_t nelems, short *ip); +extern int +ncx_getn_int_int(const void **xpp, size_t nelems, int *ip); +extern int +ncx_getn_int_long(const void **xpp, size_t nelems, long *ip); +extern int +ncx_getn_int_float(const void **xpp, size_t nelems, float *ip); +extern int +ncx_getn_int_double(const void **xpp, size_t nelems, double *ip); +extern int +ncx_getn_int_uint(const void **xpp, size_t nelems, unsigned int *ip); +extern int +ncx_getn_int_longlong(const void **xpp, size_t nelems, longlong *ip); +extern int +ncx_getn_int_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); + +extern int +ncx_putn_int_schar(void **xpp, size_t nelems, const schar *ip); +extern int +ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *ip); +extern int +ncx_putn_int_short(void **xpp, size_t nelems, const short *ip); +extern int +ncx_putn_int_int(void **xpp, size_t nelems, const int *ip); +extern int +ncx_putn_int_long(void **xpp, size_t nelems, const long *ip); +extern int +ncx_putn_int_float(void **xpp, size_t nelems, const float *ip); +extern int +ncx_putn_int_double(void **xpp, size_t nelems, const double *ip); +extern int +ncx_putn_int_uint(void **xpp, size_t nelems, const unsigned int *ip); +extern int +ncx_putn_int_longlong(void **xpp, size_t nelems, const longlong *ip); +extern int +ncx_putn_int_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); + + +extern int +ncx_getn_float_schar(const void **xpp, size_t nelems, schar *ip); +extern int +ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *ip); +extern int +ncx_getn_float_short(const void **xpp, size_t nelems, short *ip); +extern int +ncx_getn_float_int(const void **xpp, size_t nelems, int *ip); +extern int +ncx_getn_float_long(const void **xpp, size_t nelems, long *ip); +extern int +ncx_getn_float_float(const void **xpp, size_t nelems, float *ip); +extern int +ncx_getn_float_double(const void **xpp, size_t nelems, double *ip); +extern int +ncx_getn_float_uint(const void **xpp, size_t nelems, unsigned int *ip); +extern int +ncx_getn_float_longlong(const void **xpp, size_t nelems, longlong *ip); +extern int +ncx_getn_float_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); + +extern int +ncx_putn_float_schar(void **xpp, size_t nelems, const schar *ip); +extern int +ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *ip); +extern int +ncx_putn_float_short(void **xpp, size_t nelems, const short *ip); +extern int +ncx_putn_float_int(void **xpp, size_t nelems, const int *ip); +extern int +ncx_putn_float_long(void **xpp, size_t nelems, const long *ip); +extern int +ncx_putn_float_float(void **xpp, size_t nelems, const float *ip); +extern int +ncx_putn_float_double(void **xpp, size_t nelems, const double *ip); +extern int +ncx_putn_float_uint(void **xpp, size_t nelems, const unsigned int *ip); +extern int +ncx_putn_float_longlong(void **xpp, size_t nelems, const longlong *ip); +extern int +ncx_putn_float_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); + + +extern int +ncx_getn_double_schar(const void **xpp, size_t nelems, schar *ip); +extern int +ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *ip); +extern int +ncx_getn_double_short(const void **xpp, size_t nelems, short *ip); +extern int +ncx_getn_double_int(const void **xpp, size_t nelems, int *ip); +extern int +ncx_getn_double_long(const void **xpp, size_t nelems, long *ip); +extern int +ncx_getn_double_float(const void **xpp, size_t nelems, float *ip); +extern int +ncx_getn_double_double(const void **xpp, size_t nelems, double *ip); +extern int +ncx_getn_double_uint(const void **xpp, size_t nelems, unsigned int *ip); +extern int +ncx_getn_double_longlong(const void **xpp, size_t nelems, longlong *ip); +extern int +ncx_getn_double_ulonglong(const void **xpp, size_t nelems, ulonglong *ip); + +extern int +ncx_putn_double_schar(void **xpp, size_t nelems, const schar *ip); +extern int +ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *ip); +extern int +ncx_putn_double_short(void **xpp, size_t nelems, const short *ip); +extern int +ncx_putn_double_int(void **xpp, size_t nelems, const int *ip); +extern int +ncx_putn_double_long(void **xpp, size_t nelems, const long *ip); +extern int +ncx_putn_double_float(void **xpp, size_t nelems, const float *ip); +extern int +ncx_putn_double_double(void **xpp, size_t nelems, const double *ip); +extern int +ncx_putn_double_uint(void **xpp, size_t nelems, const unsigned int *ip); +extern int +ncx_putn_double_longlong(void **xpp, size_t nelems, const longlong *ip); +extern int +ncx_putn_double_ulonglong(void **xpp, size_t nelems, const ulonglong *ip); + + +/* + * Other aggregate conversion functions. + */ + +/* read ASCII characters */ +extern int +ncx_getn_text(const void **xpp, size_t nchars, char *cp); +extern int +ncx_pad_getn_text(const void **xpp, size_t nchars, char *cp); + +/* write ASCII characters */ +extern int +ncx_putn_text(void **xpp, size_t nchars, const char *cp); +extern int +ncx_pad_putn_text(void **xpp, size_t nchars, const char *cp); + +/* for symmetry */ +#define ncx_getn_char_char(xpp, nelems, fillp) ncx_getn_text(xpp, nelems, fillp) +#define ncx_putn_char_char(xpp, nelems, fillp) ncx_putn_text(xpp, nelems, fillp) + +/* read opaque data */ +extern int +ncx_getn_void(const void **xpp, size_t nchars, void *vp); +extern int +ncx_pad_getn_void(const void **xpp, size_t nchars, void *vp); + +/* write opaque data */ +extern int +ncx_putn_void(void **xpp, size_t nchars, const void *vp); +extern int +ncx_pad_putn_void(void **xpp, size_t nchars, const void *vp); + +#endif /* _NCX_H_ */ diff --git a/extern/src_netcdf4/netcdf.h b/extern/src_netcdf4/netcdf.h new file mode 100644 index 0000000000000000000000000000000000000000..8ccfb0f28392db6d14c600bbc0a4821c04fcb10c --- /dev/null +++ b/extern/src_netcdf4/netcdf.h @@ -0,0 +1,1883 @@ +/*! \file + +Main header file for the C API. + +Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 University +Corporation for Atmospheric Research/Unidata. See \ref copyright file +for more info. +*/ + +#ifndef _NETCDF_ +#define _NETCDF_ + +#include /* size_t, ptrdiff_t */ +#include /* netcdf functions sometimes return system errors */ + +/*! The nc_type type is just an int. */ +typedef int nc_type; + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * The netcdf external data types + */ +#define NC_NAT 0 /**< Not A Type */ +#define NC_BYTE 1 /**< signed 1 byte integer */ +#define NC_CHAR 2 /**< ISO/ASCII character */ +#define NC_SHORT 3 /**< signed 2 byte integer */ +#define NC_INT 4 /**< signed 4 byte integer */ +#define NC_LONG NC_INT /**< deprecated, but required for backward compatibility. */ +#define NC_FLOAT 5 /**< single precision floating point number */ +#define NC_DOUBLE 6 /**< double precision floating point number */ +#define NC_UBYTE 7 /**< unsigned 1 byte int */ +#define NC_USHORT 8 /**< unsigned 2-byte int */ +#define NC_UINT 9 /**< unsigned 4-byte int */ +#define NC_INT64 10 /**< signed 8-byte int */ +#define NC_UINT64 11 /**< unsigned 8-byte int */ +#define NC_STRING 12 /**< string */ + +#define NC_MAX_ATOMIC_TYPE NC_STRING + +/* The following are use internally in support of user-defines + * types. They are also the class returned by nc_inq_user_type. */ +#define NC_VLEN 13 /**< vlen types */ +#define NC_OPAQUE 14 /**< opaque types */ +#define NC_ENUM 15 /**< enum types */ +#define NC_COMPOUND 16 /**< compound types */ + +/* Define the first user defined type id (leave some room) */ +#define NC_FIRSTUSERTYPEID 32 + +/** Default fill value. This is used unless _FillValue attribute + * is set. These values are stuffed into newly allocated space as + * appropriate. The hope is that one might use these to notice that a + * particular datum has not been set. */ +/**@{*/ +#define NC_FILL_BYTE ((signed char)-127) +#define NC_FILL_CHAR ((char)0) +#define NC_FILL_SHORT ((short)-32767) +#define NC_FILL_INT (-2147483647L) +#define NC_FILL_FLOAT (9.9692099683868690e+36f) /* near 15 * 2^119 */ +#define NC_FILL_DOUBLE (9.9692099683868690e+36) +#define NC_FILL_UBYTE (255) +#define NC_FILL_USHORT (65535) +#define NC_FILL_UINT (4294967295U) +#define NC_FILL_INT64 ((long long)-9223372036854775806LL) +#define NC_FILL_UINT64 ((unsigned long long)18446744073709551614ULL) +#define NC_FILL_STRING "" +/**@}*/ + +/*! Max or min values for a type. Nothing greater/smaller can be + * stored in a netCDF file for their associated types. Recall that a C + * compiler may define int to be any length it wants, but a NC_INT is + * *always* a 4 byte signed int. On a platform with 64 bit ints, + * there will be many ints which are outside the range supported by + * NC_INT. But since NC_INT is an external format, it has to mean the + * same thing everywhere. */ +/**@{*/ +#define NC_MAX_BYTE 127 +#define NC_MIN_BYTE (-NC_MAX_BYTE-1) +#define NC_MAX_CHAR 255 +#define NC_MAX_SHORT 32767 +#define NC_MIN_SHORT (-NC_MAX_SHORT - 1) +#define NC_MAX_INT 2147483647 +#define NC_MIN_INT (-NC_MAX_INT - 1) +#define NC_MAX_FLOAT 3.402823466e+38f +#define NC_MIN_FLOAT (-NC_MAX_FLOAT) +#define NC_MAX_DOUBLE 1.7976931348623157e+308 +#define NC_MIN_DOUBLE (-NC_MAX_DOUBLE) +#define NC_MAX_UBYTE NC_MAX_CHAR +#define NC_MAX_USHORT 65535U +#define NC_MAX_UINT 4294967295U +#define NC_MAX_INT64 (9223372036854775807LL) +#define NC_MIN_INT64 (-9223372036854775807LL-1) +#define NC_MAX_UINT64 (18446744073709551615ULL) +#define X_INT64_MAX (9223372036854775807LL) +#define X_INT64_MIN (-X_INT64_MAX - 1) +#define X_UINT64_MAX (18446744073709551615ULL) +/**@}*/ + +/** Name of fill value attribute. If you wish a variable to use a + * different value than the above defaults, create an attribute with + * the same type as the variable and this reserved name. The value you + * give the attribute will be used as the fill value for that + * variable. */ +#define _FillValue "_FillValue" +#define NC_FILL 0 /**< Argument to nc_set_fill() to clear NC_NOFILL */ +#define NC_NOFILL 0x100 /**< Argument to nc_set_fill() to turn off filling of data. */ + +/* Define the ioflags bits for nc_create and nc_open. + currently unused: 0x0010,0x0020,0x0040,0x0080 + and the whole upper 16 bits +*/ + +#define NC_NOWRITE 0x0000 /**< Set read-only access for nc_open(). */ +#define NC_WRITE 0x0001 /**< Set read-write access for nc_open(). */ +/* unused: 0x0002 */ +#define NC_CLOBBER 0x0000 /**< Destroy existing file. Mode flag for nc_create(). */ +#define NC_NOCLOBBER 0x0004 /**< Don't destroy existing file. Mode flag for nc_create(). */ + +#define NC_DISKLESS 0x0008 /**< Use diskless file. Mode flag for nc_open() or nc_create(). */ +#define NC_MMAP 0x0010 /**< Use diskless file with mmap. Mode flag for nc_open() or nc_create(). */ + +#define NC_CLASSIC_MODEL 0x0100 /**< Enforce classic model. Mode flag for nc_create(). */ +#define NC_64BIT_OFFSET 0x0200 /**< Use large (64-bit) file offsets. Mode flag for nc_create(). */ + +/** \deprecated The following flag currently is ignored, but use in + * nc_open() or nc_create() may someday support use of advisory + * locking to prevent multiple writers from clobbering a file + */ +#define NC_LOCK 0x0400 + +/** Share updates, limit cacheing. +Use this in mode flags for both nc_create() and nc_open(). */ +#define NC_SHARE 0x0800 + +#define NC_NETCDF4 0x1000 /**< Use netCDF-4/HDF5 format. Mode flag for nc_create(). */ + +/** Turn on MPI I/O. +Use this in mode flags for both nc_create() and nc_open(). */ +#define NC_MPIIO 0x2000 +/** Turn on MPI POSIX I/O. +Use this in mode flags for both nc_create() and nc_open(). */ +#define NC_MPIPOSIX 0x4000 +#define NC_PNETCDF 0x8000 /**< Use parallel-netcdf library. Mode flag for nc_open(). */ + +/** Format specifier for nc_set_default_format(). Starting with + * version 3.6, there are different format netCDF files. 4.0 + * introduces the third one. \see netcdf_format + */ +/**@{*/ +#define NC_FORMAT_CLASSIC (1) +#define NC_FORMAT_64BIT (2) +#define NC_FORMAT_NETCDF4 (3) +#define NC_FORMAT_NETCDF4_CLASSIC (4) +/**@}*/ + +/** Let nc__create() or nc__open() figure out as suitable chunk + * size. */ +#define NC_SIZEHINT_DEFAULT 0 + +/** In nc__enddef(), align to the chunk size. */ +#define NC_ALIGN_CHUNK ((size_t)(-1)) + +/** Size argument to nc_def_dim() for an unlimited dimension. */ +#define NC_UNLIMITED 0L + +/** Attribute id to put/get a global attribute. */ +#define NC_GLOBAL -1 + +/** +Maximum for classic library. + +In the classic netCDF model there are maximum values for the number of +dimensions in the file (\ref NC_MAX_DIMS), the number of global or per +variable attributes (\ref NC_MAX_ATTRS), the number of variables in +the file (\ref NC_MAX_VARS), and the length of a name (\ref +NC_MAX_NAME). + +This maximum is enforced by the interface, to facilitate writing +applications and utilities. However, nothing is statically allocated +to this size internally. + +This maximum is not used for netCDF-4/HDF5 files unless they were +created with the ::NC_CLASSIC_MODEL flag. + +As a rule, NC_MAX_VAR_DIMS <= NC_MAX_DIMS. +*/ +/**@{*/ +#define NC_MAX_DIMS 1024 +#define NC_MAX_ATTRS 8192 +#define NC_MAX_VARS 8192 +#define NC_MAX_NAME 256 +#define NC_MAX_VAR_DIMS 1024 /**< max per variable dimensions */ +/**@}*/ + +/** This is the max size of an SD dataset name in HDF4 (from HDF4 documentation).*/ +#define NC_MAX_HDF4_NAME 64 + +/** In HDF5 files you can set the endianness of variables with + nc_def_var_endian(). This define is used there. */ +/**@{*/ +#define NC_ENDIAN_NATIVE 0 +#define NC_ENDIAN_LITTLE 1 +#define NC_ENDIAN_BIG 2 +/**@}*/ + +/** In HDF5 files you can set storage for each variable to be either + * contiguous or chunked, with nc_def_var_chunking(). This define is + * used there. */ +/**@{*/ +#define NC_CHUNKED 0 +#define NC_CONTIGUOUS 1 +/**@}*/ + +/** In HDF5 files you can set check-summing for each variable. +Currently the only checksum available is Fletcher-32, which can be set +with the function nc_def_var_fletcher32. These defines are used +there. */ +/**@{*/ +#define NC_NOCHECKSUM 0 +#define NC_FLETCHER32 1 +/**@}*/ + +/**@{*/ +/** Control the HDF5 shuffle filter. In HDF5 files you can specify + * that a shuffle filter should be used on each chunk of a variable to + * improve compression for that variable. This per-variable shuffle + * property can be set with the function nc_def_var_deflate(). */ +#define NC_NOSHUFFLE 0 +#define NC_SHUFFLE 1 +/**@}*/ + +/** The netcdf version 3 functions all return integer error status. + * These are the possible values, in addition to certain values from + * the system errno.h. + */ +#define NC_ISSYSERR(err) ((err) > 0) + +#define NC_NOERR 0 /**< No Error */ +#define NC2_ERR (-1) /**< Returned for all errors in the v2 API. */ + +/** Not a netcdf id. + +The specified netCDF ID does not refer to an +open netCDF dataset. */ +#define NC_EBADID (-33) +#define NC_ENFILE (-34) /**< Too many netcdfs open */ +#define NC_EEXIST (-35) /**< netcdf file exists && NC_NOCLOBBER */ +#define NC_EINVAL (-36) /**< Invalid Argument */ +#define NC_EPERM (-37) /**< Write to read only */ + +/** Operation not allowed in data mode. This is returned for netCDF +classic or 64-bit offset files, or for netCDF-4 files, when they were +been created with ::NC_CLASSIC_MODEL flag in nc_create(). */ +#define NC_ENOTINDEFINE (-38) + +/** Operation not allowed in define mode. + +The specified netCDF is in define mode rather than data mode. + +With netCDF-4/HDF5 files, this error will not occur, unless +::NC_CLASSIC_MODEL was used in nc_create(). + */ +#define NC_EINDEFINE (-39) + +/** Index exceeds dimension bound. + +The specified corner indices were out of range for the rank of the +specified variable. For example, a negative index or an index that is +larger than the corresponding dimension length will cause an error. */ +#define NC_EINVALCOORDS (-40) +#define NC_EMAXDIMS (-41) /**< NC_MAX_DIMS exceeded */ +#define NC_ENAMEINUSE (-42) /**< String match to name in use */ +#define NC_ENOTATT (-43) /**< Attribute not found */ +#define NC_EMAXATTS (-44) /**< NC_MAX_ATTRS exceeded */ +#define NC_EBADTYPE (-45) /**< Not a netcdf data type */ +#define NC_EBADDIM (-46) /**< Invalid dimension id or name */ +#define NC_EUNLIMPOS (-47) /**< NC_UNLIMITED in the wrong index */ + +/** NC_MAX_VARS exceeded. Max number of variables exceeded in a +classic or 64-bit offset file, or an netCDF-4 file with +::NC_CLASSIC_MODEL on. */ +#define NC_EMAXVARS (-48) + +/** Variable not found. + +The variable ID is invalid for the specified netCDF dataset. */ +#define NC_ENOTVAR (-49) +#define NC_EGLOBAL (-50) /**< Action prohibited on NC_GLOBAL varid */ +#define NC_ENOTNC (-51) /**< Not a netcdf file */ +#define NC_ESTS (-52) /**< In Fortran, string too short */ +#define NC_EMAXNAME (-53) /**< NC_MAX_NAME exceeded */ +#define NC_EUNLIMIT (-54) /**< NC_UNLIMITED size already in use */ +#define NC_ENORECVARS (-55) /**< nc_rec op when there are no record vars */ +#define NC_ECHAR (-56) /**< Attempt to convert between text & numbers */ + +/** Start+count exceeds dimension bound. + +The specified edge lengths added to the specified corner would have +referenced data out of range for the rank of the specified +variable. For example, an edge length that is larger than the +corresponding dimension length minus the corner index will cause an +error. */ +#define NC_EEDGE (-57) +#define NC_ESTRIDE (-58) /**< Illegal stride */ +#define NC_EBADNAME (-59) /**< Attribute or variable name contains illegal characters */ +/* N.B. following must match value in ncx.h */ + +/** Math result not representable. + +One or more of the values are out of the range of values representable +by the desired type. */ +#define NC_ERANGE (-60) +#define NC_ENOMEM (-61) /**< Memory allocation (malloc) failure */ +#define NC_EVARSIZE (-62) /**< One or more variable sizes violate format constraints */ +#define NC_EDIMSIZE (-63) /**< Invalid dimension size */ +#define NC_ETRUNC (-64) /**< File likely truncated or possibly corrupted */ +#define NC_EAXISTYPE (-65) /**< Unknown axis type. */ + +/* Following errors are added for DAP */ +#define NC_EDAP (-66) /**< Generic DAP error */ +#define NC_ECURL (-67) /**< Generic libcurl error */ +#define NC_EIO (-68) /**< Generic IO error */ +#define NC_ENODATA (-69) /**< Attempt to access variable with no data */ +#define NC_EDAPSVC (-70) /**< DAP server error */ +#define NC_EDAS (-71) /**< Malformed or inaccessible DAS */ +#define NC_EDDS (-72) /**< Malformed or inaccessible DDS */ +#define NC_EDATADDS (-73) /**< Malformed or inaccessible DATADDS */ +#define NC_EDAPURL (-74) /**< Malformed DAP URL */ +#define NC_EDAPCONSTRAINT (-75) /**< Malformed DAP Constraint*/ +#define NC_ETRANSLATION (-76) /**< Untranslatable construct */ + +/* The following was added in support of netcdf-4. Make all netcdf-4 + error codes < -100 so that errors can be added to netcdf-3 if + needed. */ +#define NC4_FIRST_ERROR (-100) + +/** Error at HDF5 layer. */ +#define NC_EHDFERR (-101) +#define NC_ECANTREAD (-102) /**< Can't read. */ +#define NC_ECANTWRITE (-103) /**< Can't write. */ +#define NC_ECANTCREATE (-104) /**< Can't create. */ +#define NC_EFILEMETA (-105) /**< Problem with file metadata. */ +#define NC_EDIMMETA (-106) /**< Problem with dimension metadata. */ +#define NC_EATTMETA (-107) /**< Problem with attribute metadata. */ +#define NC_EVARMETA (-108) /**< Problem with variable metadata. */ +#define NC_ENOCOMPOUND (-109) /**< Not a compound type. */ +#define NC_EATTEXISTS (-110) /**< Attribute already exists. */ +#define NC_ENOTNC4 (-111) /**< Attempting netcdf-4 operation on netcdf-3 file. */ + +/** Attempting netcdf-4 operation on strict nc3 netcdf-4 file. */ +#define NC_ESTRICTNC3 (-112) +#define NC_ENOTNC3 (-113) /**< Attempting netcdf-3 operation on netcdf-4 file. */ +#define NC_ENOPAR (-114) /**< Parallel operation on file opened for non-parallel access. */ +#define NC_EPARINIT (-115) /**< Error initializing for parallel access. */ +#define NC_EBADGRPID (-116) /**< Bad group ID. */ +#define NC_EBADTYPID (-117) /**< Bad type ID. */ +#define NC_ETYPDEFINED (-118) /**< Type has already been defined and may not be edited. */ +#define NC_EBADFIELD (-119) /**< Bad field ID. */ +#define NC_EBADCLASS (-120) /**< Bad class. */ +#define NC_EMAPTYPE (-121) /**< Mapped access for atomic types only. */ +#define NC_ELATEFILL (-122) /**< Attempt to define fill value when data already exists. */ +#define NC_ELATEDEF (-123) /**< Attempt to define var properties, like deflate, after enddef. */ +#define NC_EDIMSCALE (-124) /**< Probem with HDF5 dimscales. */ +#define NC_ENOGRP (-125) /**< No group found. */ +#define NC_ESTORAGE (-126) /**< Can't specify both contiguous and chunking. */ +#define NC_EBADCHUNK (-127) /**< Bad chunksize. */ +#define NC_ENOTBUILT (-128) /**< Attempt to use feature that was not turned on when netCDF was built. */ +#define NC_EDISKLESS (-129) /**< Error in using diskless access. */ + +#define NC4_LAST_ERROR (-129) + +/* This is used in netCDF-4 files for dimensions without coordinate + * vars. */ +#define DIM_WITHOUT_VARIABLE "This is a netCDF dimension but not a netCDF variable." + +/* This is here at the request of the NCO team to support our + * mistake of having chunksizes be first ints, then size_t. Doh! */ +#define NC_HAVE_NEW_CHUNKING_API 1 + + +/*Errors for all remote access methods(e.g. DAP and CDMREMOTE)*/ +#define NC_EURL (NC_EDAPURL) /* Malformed URL */ +#define NC_ECONSTRAINT (NC_EDAPCONSTRAINT) /* Malformed Constraint*/ + + +/* + * The Interface + */ + +/* Declaration modifiers for DLL support (MSC et al) */ + +#if defined(DLL_NETCDF) /* define when library is a DLL */ +# if defined(DLL_EXPORT) /* define when building the library */ +# define MSC_EXTRA __declspec(dllexport) +# else +# define MSC_EXTRA __declspec(dllimport) +# endif +#include +/*#define lseek _lseeki64 + #define off_t __int64*/ +#else +#define MSC_EXTRA +#endif /* defined(DLL_NETCDF) */ + +# define EXTERNL MSC_EXTRA extern + +#if defined(DLL_NETCDF) /* define when library is a DLL */ +EXTERNL int ncerr; +EXTERNL int ncopts; +#endif + +EXTERNL const char * +nc_inq_libvers(void); + +EXTERNL const char * +nc_strerror(int ncerr); + +EXTERNL int +nc__create(const char *path, int cmode, size_t initialsz, + size_t *chunksizehintp, int *ncidp); + +EXTERNL int +nc_create(const char *path, int cmode, int *ncidp); + +EXTERNL int +nc__open(const char *path, int mode, + size_t *chunksizehintp, int *ncidp); + +EXTERNL int +nc_open(const char *path, int mode, int *ncidp); + +/* Learn the path used to open/create the file. */ +EXTERNL int +nc_inq_path(int ncid, size_t *pathlen, char *path); + +/* Use these with nc_var_par_access(). */ +#define NC_INDEPENDENT 0 +#define NC_COLLECTIVE 1 + +/* Set parallel access for a variable to independent (the default) or + * collective. */ +EXTERNL int +nc_var_par_access(int ncid, int varid, int par_access); + +/* Given an ncid and group name (NULL gets root group), return + * locid. */ +EXTERNL int +nc_inq_ncid(int ncid, const char *name, int *grp_ncid); + +/* Given a location id, return the number of groups it contains, and + * an array of their locids. */ +EXTERNL int +nc_inq_grps(int ncid, int *numgrps, int *ncids); + +/* Given locid, find name of group. (Root group is named "/".) */ +EXTERNL int +nc_inq_grpname(int ncid, char *name); + +/* Given ncid, find full name and len of full name. (Root group is + * named "/", with length 1.) */ +EXTERNL int +nc_inq_grpname_full(int ncid, size_t *lenp, char *full_name); + +/* Given ncid, find len of full name. */ +EXTERNL int +nc_inq_grpname_len(int ncid, size_t *lenp); + +/* Given an ncid, find the ncid of its parent group. */ +EXTERNL int +nc_inq_grp_parent(int ncid, int *parent_ncid); + +/* Given a name and parent ncid, find group ncid. */ +EXTERNL int +nc_inq_grp_ncid(int ncid, const char *grp_name, int *grp_ncid); + +/* Given a full name and ncid, find group ncid. */ +EXTERNL int +nc_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid); + +/* Get a list of ids for all the variables in a group. */ +EXTERNL int +nc_inq_varids(int ncid, int *nvars, int *varids); + +/* Find all dimids for a location. This finds all dimensions in a + * group, or any of its parents. */ +EXTERNL int +nc_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents); + +/* Find all user-defined types for a location. This finds all + * user-defined types in a group. */ +EXTERNL int +nc_inq_typeids(int ncid, int *ntypes, int *typeids); + +/* Are two types equal? */ +EXTERNL int +nc_inq_type_equal(int ncid1, nc_type typeid1, int ncid2, + nc_type typeid2, int *equal); + +/* Create a group. its ncid is returned in the new_ncid pointer. */ +EXTERNL int +nc_def_grp(int parent_ncid, const char *name, int *new_ncid); + +/* Here are functions for dealing with compound types. */ + +/* Create a compound type. */ +EXTERNL int +nc_def_compound(int ncid, size_t size, const char *name, nc_type *typeidp); + +/* Insert a named field into a compound type. */ +EXTERNL int +nc_insert_compound(int ncid, nc_type xtype, const char *name, + size_t offset, nc_type field_typeid); + +/* Insert a named array into a compound type. */ +EXTERNL int +nc_insert_array_compound(int ncid, nc_type xtype, const char *name, + size_t offset, nc_type field_typeid, + int ndims, const int *dim_sizes); + +/* Get the name and size of a type. */ +EXTERNL int +nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size); + +/* Get the id of a type from the name. */ +EXTERNL int +nc_inq_typeid(int ncid, const char *name, nc_type *typeidp); + +/* Get the name, size, and number of fields in a compound type. */ +EXTERNL int +nc_inq_compound(int ncid, nc_type xtype, char *name, size_t *sizep, + size_t *nfieldsp); + +/* Get the name of a compound type. */ +EXTERNL int +nc_inq_compound_name(int ncid, nc_type xtype, char *name); + +/* Get the size of a compound type. */ +EXTERNL int +nc_inq_compound_size(int ncid, nc_type xtype, size_t *sizep); + +/* Get the number of fields in this compound type. */ +EXTERNL int +nc_inq_compound_nfields(int ncid, nc_type xtype, size_t *nfieldsp); + +/* Given the xtype and the fieldid, get all info about it. */ +EXTERNL int +nc_inq_compound_field(int ncid, nc_type xtype, int fieldid, char *name, + size_t *offsetp, nc_type *field_typeidp, int *ndimsp, + int *dim_sizesp); + +/* Given the typeid and the fieldid, get the name. */ +EXTERNL int +nc_inq_compound_fieldname(int ncid, nc_type xtype, int fieldid, + char *name); + +/* Given the xtype and the name, get the fieldid. */ +EXTERNL int +nc_inq_compound_fieldindex(int ncid, nc_type xtype, const char *name, + int *fieldidp); + +/* Given the xtype and fieldid, get the offset. */ +EXTERNL int +nc_inq_compound_fieldoffset(int ncid, nc_type xtype, int fieldid, + size_t *offsetp); + +/* Given the xtype and the fieldid, get the type of that field. */ +EXTERNL int +nc_inq_compound_fieldtype(int ncid, nc_type xtype, int fieldid, + nc_type *field_typeidp); + +/* Given the xtype and the fieldid, get the number of dimensions for + * that field (scalars are 0). */ +EXTERNL int +nc_inq_compound_fieldndims(int ncid, nc_type xtype, int fieldid, + int *ndimsp); + +/* Given the xtype and the fieldid, get the sizes of dimensions for + * that field. User must have allocated storage for the dim_sizes. */ +EXTERNL int +nc_inq_compound_fielddim_sizes(int ncid, nc_type xtype, int fieldid, + int *dim_sizes); + +/** This is the type of arrays of vlens. */ +typedef struct { + size_t len; /**< Length of VL data (in base type units) */ + void *p; /**< Pointer to VL data */ +} nc_vlen_t; + +/** Calculate an offset for creating a compound type. This calls a + * mysterious C macro which was found carved into one of the blocks of + * the Newgrange passage tomb in County Meath, Ireland. This code has + * been carbon dated to 3200 B.C.E. */ +#define NC_COMPOUND_OFFSET(S,M) (offsetof(S,M)) + +/* Create a variable length type. */ +EXTERNL int +nc_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type *xtypep); + +/* Find out about a vlen. */ +EXTERNL int +nc_inq_vlen(int ncid, nc_type xtype, char *name, size_t *datum_sizep, + nc_type *base_nc_typep); + +/* When you read VLEN type the library will actually allocate the + * storage space for the data. This storage space must be freed, so + * pass the pointer back to this function, when you're done with the + * data, and it will free the vlen memory. */ +EXTERNL int +nc_free_vlen(nc_vlen_t *vl); + +EXTERNL int +nc_free_vlens(size_t len, nc_vlen_t vlens[]); + +/* Put or get one element in a vlen array. */ +EXTERNL int +nc_put_vlen_element(int ncid, int typeid1, void *vlen_element, + size_t len, const void *data); + +EXTERNL int +nc_get_vlen_element(int ncid, int typeid1, const void *vlen_element, + size_t *len, void *data); + +/* When you read the string type the library will allocate the storage + * space for the data. This storage space must be freed, so pass the + * pointer back to this function, when you're done with the data, and + * it will free the string memory. */ +EXTERNL int +nc_free_string(size_t len, char **data); + +/* Find out about a user defined type. */ +EXTERNL int +nc_inq_user_type(int ncid, nc_type xtype, char *name, size_t *size, + nc_type *base_nc_typep, size_t *nfieldsp, int *classp); + +/* Write an attribute of any type. */ +EXTERNL int +nc_put_att(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const void *op); + +/* Read an attribute of any type. */ +EXTERNL int +nc_get_att(int ncid, int varid, const char *name, void *ip); + +/* Enum type. */ + +/* Create an enum type. Provide a base type and a name. At the moment + * only ints are accepted as base types. */ +EXTERNL int +nc_def_enum(int ncid, nc_type base_typeid, const char *name, + nc_type *typeidp); + +/* Insert a named value into an enum type. The value must fit within + * the size of the enum type, the name size must be <= NC_MAX_NAME. */ +EXTERNL int +nc_insert_enum(int ncid, nc_type xtype, const char *name, + const void *value); + +/* Get information about an enum type: its name, base type and the + * number of members defined. */ +EXTERNL int +nc_inq_enum(int ncid, nc_type xtype, char *name, nc_type *base_nc_typep, + size_t *base_sizep, size_t *num_membersp); + +/* Get information about an enum member: a name and value. Name size + * will be <= NC_MAX_NAME. */ +EXTERNL int +nc_inq_enum_member(int ncid, nc_type xtype, int idx, char *name, + void *value); + + +/* Get enum name from enum value. Name size will be <= NC_MAX_NAME. */ +EXTERNL int +nc_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier); + +/* Opaque type. */ + +/* Create an opaque type. Provide a size and a name. */ +EXTERNL int +nc_def_opaque(int ncid, size_t size, const char *name, nc_type *xtypep); + +/* Get information about an opaque type. */ +EXTERNL int +nc_inq_opaque(int ncid, nc_type xtype, char *name, size_t *sizep); + +/* Write entire var of any type. */ +EXTERNL int +nc_put_var(int ncid, int varid, const void *op); + +/* Read entire var of any type. */ +EXTERNL int +nc_get_var(int ncid, int varid, void *ip); + +/* Write one value. */ +EXTERNL int +nc_put_var1(int ncid, int varid, const size_t *indexp, + const void *op); + +/* Read one value. */ +EXTERNL int +nc_get_var1(int ncid, int varid, const size_t *indexp, void *ip); + +/* Write an array of values. */ +EXTERNL int +nc_put_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, const void *op); + +/* Read an array of values. */ +EXTERNL int +nc_get_vara(int ncid, int varid, const size_t *startp, + const size_t *countp, void *ip); + +/* Write slices of an array of values. */ +EXTERNL int +nc_put_vars(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const void *op); + +/* Read slices of an array of values. */ +EXTERNL int +nc_get_vars(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + void *ip); + +/* Write mapped slices of an array of values. */ +EXTERNL int +nc_put_varm(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const void *op); + +/* Read mapped slices of an array of values. */ +EXTERNL int +nc_get_varm(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, void *ip); + +/* Extra netcdf-4 stuff. */ + +/* Set compression settings for a variable. Lower is faster, higher is + * better. Must be called after nc_def_var and before nc_enddef. */ +EXTERNL int +nc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, + int deflate_level); + +/* Find out compression settings of a var. */ +EXTERNL int +nc_inq_var_deflate(int ncid, int varid, int *shufflep, + int *deflatep, int *deflate_levelp); + +/* Find out szip settings of a var. */ +EXTERNL int +nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp); + +/* Set fletcher32 checksum for a var. This must be done after nc_def_var + and before nc_enddef. */ +EXTERNL int +nc_def_var_fletcher32(int ncid, int varid, int fletcher32); + +/* Inquire about fletcher32 checksum for a var. */ +EXTERNL int +nc_inq_var_fletcher32(int ncid, int varid, int *fletcher32p); + +/* Define chunking for a variable. This must be done after nc_def_var + and before nc_enddef. */ +EXTERNL int +nc_def_var_chunking(int ncid, int varid, int storage, const size_t *chunksizesp); + +/* Inq chunking stuff for a var. */ +EXTERNL int +nc_inq_var_chunking(int ncid, int varid, int *storagep, size_t *chunksizesp); + +/* Define fill value behavior for a variable. This must be done after + nc_def_var and before nc_enddef. */ +EXTERNL int +nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value); + +/* Inq fill value setting for a var. */ +EXTERNL int +nc_inq_var_fill(int ncid, int varid, int *no_fill, void *fill_valuep); + +/* Define the endianness of a variable. */ +EXTERNL int +nc_def_var_endian(int ncid, int varid, int endian); + +/* Learn about the endianness of a variable. */ +EXTERNL int +nc_inq_var_endian(int ncid, int varid, int *endianp); + +/* Set the fill mode (classic or 64-bit offset files only). */ +EXTERNL int +nc_set_fill(int ncid, int fillmode, int *old_modep); + +/* Set the default nc_create format to NC_FORMAT_CLASSIC, + * NC_FORMAT_64BIT, NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC. */ +EXTERNL int +nc_set_default_format(int format, int *old_formatp); + +/* Set the cache size, nelems, and preemption policy. */ +EXTERNL int +nc_set_chunk_cache(size_t size, size_t nelems, float preemption); + +/* Get the cache size, nelems, and preemption policy. */ +EXTERNL int +nc_get_chunk_cache(size_t *sizep, size_t *nelemsp, float *preemptionp); + +/* Set the per-variable cache size, nelems, and preemption policy. */ +EXTERNL int +nc_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems, + float preemption); + +/* Set the per-variable cache size, nelems, and preemption policy. */ +EXTERNL int +nc_get_var_chunk_cache(int ncid, int varid, size_t *sizep, size_t *nelemsp, + float *preemptionp); + +EXTERNL int +nc_redef(int ncid); + +EXTERNL int +nc__enddef(int ncid, size_t h_minfree, size_t v_align, + size_t v_minfree, size_t r_align); + +EXTERNL int +nc_enddef(int ncid); + +EXTERNL int +nc_sync(int ncid); + +EXTERNL int +nc_abort(int ncid); + +EXTERNL int +nc_close(int ncid); + +EXTERNL int +nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp); + +EXTERNL int +nc_inq_ndims(int ncid, int *ndimsp); + +EXTERNL int +nc_inq_nvars(int ncid, int *nvarsp); + +EXTERNL int +nc_inq_natts(int ncid, int *nattsp); + +EXTERNL int +nc_inq_unlimdim(int ncid, int *unlimdimidp); + +/* The next function is for NetCDF-4 only */ +EXTERNL int +nc_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp); + +/* Added in 3.6.1 to return format of netCDF file. */ +EXTERNL int +nc_inq_format(int ncid, int *formatp); + +/* Begin _dim */ + +EXTERNL int +nc_def_dim(int ncid, const char *name, size_t len, int *idp); + +EXTERNL int +nc_inq_dimid(int ncid, const char *name, int *idp); + +EXTERNL int +nc_inq_dim(int ncid, int dimid, char *name, size_t *lenp); + +EXTERNL int +nc_inq_dimname(int ncid, int dimid, char *name); + +EXTERNL int +nc_inq_dimlen(int ncid, int dimid, size_t *lenp); + +EXTERNL int +nc_rename_dim(int ncid, int dimid, const char *name); + +/* End _dim */ +/* Begin _att */ + +EXTERNL int +nc_inq_att(int ncid, int varid, const char *name, + nc_type *xtypep, size_t *lenp); + +EXTERNL int +nc_inq_attid(int ncid, int varid, const char *name, int *idp); + +EXTERNL int +nc_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep); + +EXTERNL int +nc_inq_attlen(int ncid, int varid, const char *name, size_t *lenp); + +EXTERNL int +nc_inq_attname(int ncid, int varid, int attnum, char *name); + +EXTERNL int +nc_copy_att(int ncid_in, int varid_in, const char *name, int ncid_out, int varid_out); + +EXTERNL int +nc_rename_att(int ncid, int varid, const char *name, const char *newname); + +EXTERNL int +nc_del_att(int ncid, int varid, const char *name); + +/* End _att */ +/* Begin {put,get}_att */ + +EXTERNL int +nc_put_att_text(int ncid, int varid, const char *name, + size_t len, const char *op); + +EXTERNL int +nc_get_att_text(int ncid, int varid, const char *name, char *ip); + +EXTERNL int +nc_put_att_uchar(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned char *op); + +EXTERNL int +nc_get_att_uchar(int ncid, int varid, const char *name, unsigned char *ip); + +EXTERNL int +nc_put_att_schar(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const signed char *op); + +EXTERNL int +nc_get_att_schar(int ncid, int varid, const char *name, signed char *ip); + +EXTERNL int +nc_put_att_short(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const short *op); + +EXTERNL int +nc_get_att_short(int ncid, int varid, const char *name, short *ip); + +EXTERNL int +nc_put_att_int(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const int *op); + +EXTERNL int +nc_get_att_int(int ncid, int varid, const char *name, int *ip); + +EXTERNL int +nc_put_att_long(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const long *op); + +EXTERNL int +nc_get_att_long(int ncid, int varid, const char *name, long *ip); + +EXTERNL int +nc_put_att_float(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const float *op); + +EXTERNL int +nc_get_att_float(int ncid, int varid, const char *name, float *ip); + +EXTERNL int +nc_put_att_double(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const double *op); + +EXTERNL int +nc_get_att_double(int ncid, int varid, const char *name, double *ip); + +EXTERNL int +nc_put_att_ushort(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned short *op); + +EXTERNL int +nc_get_att_ushort(int ncid, int varid, const char *name, unsigned short *ip); + +EXTERNL int +nc_put_att_uint(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned int *op); + +EXTERNL int +nc_get_att_uint(int ncid, int varid, const char *name, unsigned int *ip); + +EXTERNL int +nc_put_att_longlong(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const long long *op); + +EXTERNL int +nc_get_att_longlong(int ncid, int varid, const char *name, long long *ip); + +EXTERNL int +nc_put_att_ulonglong(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned long long *op); + +EXTERNL int +nc_get_att_ulonglong(int ncid, int varid, const char *name, + unsigned long long *ip); + +EXTERNL int +nc_put_att_string(int ncid, int varid, const char *name, + size_t len, const char **op); + +EXTERNL int +nc_get_att_string(int ncid, int varid, const char *name, char **ip); + +/* End {put,get}_att */ +/* Begin _var */ + +EXTERNL int +nc_def_var(int ncid, const char *name, nc_type xtype, int ndims, + const int *dimidsp, int *varidp); + +EXTERNL int +nc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp); + +EXTERNL int +nc_inq_varid(int ncid, const char *name, int *varidp); + +EXTERNL int +nc_inq_varname(int ncid, int varid, char *name); + +EXTERNL int +nc_inq_vartype(int ncid, int varid, nc_type *xtypep); + +EXTERNL int +nc_inq_varndims(int ncid, int varid, int *ndimsp); + +EXTERNL int +nc_inq_vardimid(int ncid, int varid, int *dimidsp); + +EXTERNL int +nc_inq_varnatts(int ncid, int varid, int *nattsp); + +EXTERNL int +nc_rename_var(int ncid, int varid, const char *name); + +EXTERNL int +nc_copy_var(int ncid_in, int varid, int ncid_out); + +#ifndef ncvarcpy +/* support the old name for now */ +#define ncvarcpy(ncid_in, varid, ncid_out) ncvarcopy((ncid_in), (varid), (ncid_out)) +#endif + +/* End _var */ +/* Begin {put,get}_var1 */ + +EXTERNL int +nc_put_var1_text(int ncid, int varid, const size_t *indexp, const char *op); + +EXTERNL int +nc_get_var1_text(int ncid, int varid, const size_t *indexp, char *ip); + +EXTERNL int +nc_put_var1_uchar(int ncid, int varid, const size_t *indexp, + const unsigned char *op); + +EXTERNL int +nc_get_var1_uchar(int ncid, int varid, const size_t *indexp, + unsigned char *ip); + +EXTERNL int +nc_put_var1_schar(int ncid, int varid, const size_t *indexp, + const signed char *op); + +EXTERNL int +nc_get_var1_schar(int ncid, int varid, const size_t *indexp, + signed char *ip); + +EXTERNL int +nc_put_var1_short(int ncid, int varid, const size_t *indexp, + const short *op); + +EXTERNL int +nc_get_var1_short(int ncid, int varid, const size_t *indexp, + short *ip); + +EXTERNL int +nc_put_var1_int(int ncid, int varid, const size_t *indexp, const int *op); + +EXTERNL int +nc_get_var1_int(int ncid, int varid, const size_t *indexp, int *ip); + +EXTERNL int +nc_put_var1_long(int ncid, int varid, const size_t *indexp, const long *op); + +EXTERNL int +nc_get_var1_long(int ncid, int varid, const size_t *indexp, long *ip); + +EXTERNL int +nc_put_var1_float(int ncid, int varid, const size_t *indexp, const float *op); + +EXTERNL int +nc_get_var1_float(int ncid, int varid, const size_t *indexp, float *ip); + +EXTERNL int +nc_put_var1_double(int ncid, int varid, const size_t *indexp, const double *op); + +EXTERNL int +nc_get_var1_double(int ncid, int varid, const size_t *indexp, double *ip); + +EXTERNL int +nc_put_var1_ushort(int ncid, int varid, const size_t *indexp, + const unsigned short *op); + +EXTERNL int +nc_get_var1_ushort(int ncid, int varid, const size_t *indexp, + unsigned short *ip); + +EXTERNL int +nc_put_var1_uint(int ncid, int varid, const size_t *indexp, + const unsigned int *op); + +EXTERNL int +nc_get_var1_uint(int ncid, int varid, const size_t *indexp, + unsigned int *ip); + +EXTERNL int +nc_put_var1_longlong(int ncid, int varid, const size_t *indexp, + const long long *op); + +EXTERNL int +nc_get_var1_longlong(int ncid, int varid, const size_t *indexp, + long long *ip); + +EXTERNL int +nc_put_var1_ulonglong(int ncid, int varid, const size_t *indexp, + const unsigned long long *op); + +EXTERNL int +nc_get_var1_ulonglong(int ncid, int varid, const size_t *indexp, + unsigned long long *ip); + +EXTERNL int +nc_put_var1_string(int ncid, int varid, const size_t *indexp, + const char **op); + +EXTERNL int +nc_get_var1_string(int ncid, int varid, const size_t *indexp, + char **ip); + +/* End {put,get}_var1 */ +/* Begin {put,get}_vara */ + +EXTERNL int +nc_put_vara_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const char *op); + +EXTERNL int +nc_get_vara_text(int ncid, int varid, const size_t *startp, + const size_t *countp, char *ip); + +EXTERNL int +nc_put_vara_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned char *op); + +EXTERNL int +nc_get_vara_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned char *ip); + +EXTERNL int +nc_put_vara_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const signed char *op); + +EXTERNL int +nc_get_vara_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, signed char *ip); + +EXTERNL int +nc_put_vara_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const short *op); + +EXTERNL int +nc_get_vara_short(int ncid, int varid, const size_t *startp, + const size_t *countp, short *ip); + +EXTERNL int +nc_put_vara_int(int ncid, int varid, const size_t *startp, + const size_t *countp, const int *op); + +EXTERNL int +nc_get_vara_int(int ncid, int varid, const size_t *startp, + const size_t *countp, int *ip); + +EXTERNL int +nc_put_vara_long(int ncid, int varid, const size_t *startp, + const size_t *countp, const long *op); + +EXTERNL int +nc_get_vara_long(int ncid, int varid, + const size_t *startp, const size_t *countp, long *ip); + +EXTERNL int +nc_put_vara_float(int ncid, int varid, + const size_t *startp, const size_t *countp, const float *op); + +EXTERNL int +nc_get_vara_float(int ncid, int varid, + const size_t *startp, const size_t *countp, float *ip); + +EXTERNL int +nc_put_vara_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const double *op); + +EXTERNL int +nc_get_vara_double(int ncid, int varid, const size_t *startp, + const size_t *countp, double *ip); + +EXTERNL int +nc_put_vara_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned short *op); + +EXTERNL int +nc_get_vara_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned short *ip); + +EXTERNL int +nc_put_vara_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned int *op); + +EXTERNL int +nc_get_vara_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned int *ip); + +EXTERNL int +nc_put_vara_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const long long *op); + +EXTERNL int +nc_get_vara_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, long long *ip); + +EXTERNL int +nc_put_vara_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned long long *op); + +EXTERNL int +nc_get_vara_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned long long *ip); + +EXTERNL int +nc_put_vara_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const char **op); + +EXTERNL int +nc_get_vara_string(int ncid, int varid, const size_t *startp, + const size_t *countp, char **ip); + +/* End {put,get}_vara */ +/* Begin {put,get}_vars */ + +EXTERNL int +nc_put_vars_text(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const char *op); + +EXTERNL int +nc_get_vars_text(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + char *ip); + +EXTERNL int +nc_put_vars_uchar(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const unsigned char *op); + +EXTERNL int +nc_get_vars_uchar(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + unsigned char *ip); + +EXTERNL int +nc_put_vars_schar(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const signed char *op); + +EXTERNL int +nc_get_vars_schar(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + signed char *ip); + +EXTERNL int +nc_put_vars_short(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const short *op); + +EXTERNL int +nc_get_vars_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + short *ip); + +EXTERNL int +nc_put_vars_int(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const int *op); + +EXTERNL int +nc_get_vars_int(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + int *ip); + +EXTERNL int +nc_put_vars_long(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const long *op); + +EXTERNL int +nc_get_vars_long(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + long *ip); + +EXTERNL int +nc_put_vars_float(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const float *op); + +EXTERNL int +nc_get_vars_float(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + float *ip); + +EXTERNL int +nc_put_vars_double(int ncid, int varid, + const size_t *startp, const size_t *countp, const ptrdiff_t *stridep, + const double *op); + +EXTERNL int +nc_get_vars_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + double *ip); + +EXTERNL int +nc_put_vars_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const unsigned short *op); + +EXTERNL int +nc_get_vars_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + unsigned short *ip); + +EXTERNL int +nc_put_vars_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const unsigned int *op); + +EXTERNL int +nc_get_vars_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + unsigned int *ip); + +EXTERNL int +nc_put_vars_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const long long *op); + +EXTERNL int +nc_get_vars_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + long long *ip); + +EXTERNL int +nc_put_vars_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const unsigned long long *op); + +EXTERNL int +nc_get_vars_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + unsigned long long *ip); + +EXTERNL int +nc_put_vars_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const char **op); + +EXTERNL int +nc_get_vars_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + char **ip); + +/* End {put,get}_vars */ +/* Begin {put,get}_varm */ + +EXTERNL int +nc_put_varm_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const char *op); + +EXTERNL int +nc_get_varm_text(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, char *ip); + +EXTERNL int +nc_put_varm_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const unsigned char *op); + +EXTERNL int +nc_get_varm_uchar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, unsigned char *ip); + +EXTERNL int +nc_put_varm_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const signed char *op); + +EXTERNL int +nc_get_varm_schar(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, signed char *ip); + +EXTERNL int +nc_put_varm_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const short *op); + +EXTERNL int +nc_get_varm_short(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, short *ip); + +EXTERNL int +nc_put_varm_int(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const int *op); + +EXTERNL int +nc_get_varm_int(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, int *ip); + +EXTERNL int +nc_put_varm_long(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const long *op); + +EXTERNL int +nc_get_varm_long(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, long *ip); + +EXTERNL int +nc_put_varm_float(int ncid, int varid,const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const float *op); + +EXTERNL int +nc_get_varm_float(int ncid, int varid,const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, float *ip); + +EXTERNL int +nc_put_varm_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t *imapp, const double *op); + +EXTERNL int +nc_get_varm_double(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, double *ip); + +EXTERNL int +nc_put_varm_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const unsigned short *op); + +EXTERNL int +nc_get_varm_ushort(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, unsigned short *ip); + +EXTERNL int +nc_put_varm_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const unsigned int *op); + +EXTERNL int +nc_get_varm_uint(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, unsigned int *ip); + +EXTERNL int +nc_put_varm_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const long long *op); + +EXTERNL int +nc_get_varm_longlong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, long long *ip); + +EXTERNL int +nc_put_varm_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const unsigned long long *op); + +EXTERNL int +nc_get_varm_ulonglong(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, unsigned long long *ip); + +EXTERNL int +nc_put_varm_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const char **op); + +EXTERNL int +nc_get_varm_string(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, char **ip); + +/* End {put,get}_varm */ +/* Begin {put,get}_var */ + +EXTERNL int +nc_put_var_text(int ncid, int varid, const char *op); + +EXTERNL int +nc_get_var_text(int ncid, int varid, char *ip); + +EXTERNL int +nc_put_var_uchar(int ncid, int varid, const unsigned char *op); + +EXTERNL int +nc_get_var_uchar(int ncid, int varid, unsigned char *ip); + +EXTERNL int +nc_put_var_schar(int ncid, int varid, const signed char *op); + +EXTERNL int +nc_get_var_schar(int ncid, int varid, signed char *ip); + +EXTERNL int +nc_put_var_short(int ncid, int varid, const short *op); + +EXTERNL int +nc_get_var_short(int ncid, int varid, short *ip); + +EXTERNL int +nc_put_var_int(int ncid, int varid, const int *op); + +EXTERNL int +nc_get_var_int(int ncid, int varid, int *ip); + +EXTERNL int +nc_put_var_long(int ncid, int varid, const long *op); + +EXTERNL int +nc_get_var_long(int ncid, int varid, long *ip); + +EXTERNL int +nc_put_var_float(int ncid, int varid, const float *op); + +EXTERNL int +nc_get_var_float(int ncid, int varid, float *ip); + +EXTERNL int +nc_put_var_double(int ncid, int varid, const double *op); + +EXTERNL int +nc_get_var_double(int ncid, int varid, double *ip); + +EXTERNL int +nc_put_var_ushort(int ncid, int varid, const unsigned short *op); + +EXTERNL int +nc_get_var_ushort(int ncid, int varid, unsigned short *ip); + +EXTERNL int +nc_put_var_uint(int ncid, int varid, const unsigned int *op); + +EXTERNL int +nc_get_var_uint(int ncid, int varid, unsigned int *ip); + +EXTERNL int +nc_put_var_longlong(int ncid, int varid, const long long *op); + +EXTERNL int +nc_get_var_longlong(int ncid, int varid, long long *ip); + +EXTERNL int +nc_put_var_ulonglong(int ncid, int varid, const unsigned long long *op); + +EXTERNL int +nc_get_var_ulonglong(int ncid, int varid, unsigned long long *ip); + +EXTERNL int +nc_put_var_string(int ncid, int varid, const char **op); + +EXTERNL int +nc_get_var_string(int ncid, int varid, char **ip); + +/* Begin Deprecated, same as functions with "_ubyte" replaced by "_uchar" */ +EXTERNL int +nc_put_att_ubyte(int ncid, int varid, const char *name, nc_type xtype, + size_t len, const unsigned char *op); +EXTERNL int +nc_get_att_ubyte(int ncid, int varid, const char *name, + unsigned char *ip); +EXTERNL int +nc_put_var1_ubyte(int ncid, int varid, const size_t *indexp, + const unsigned char *op); +EXTERNL int +nc_get_var1_ubyte(int ncid, int varid, const size_t *indexp, + unsigned char *ip); +EXTERNL int +nc_put_vara_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const unsigned char *op); +EXTERNL int +nc_get_vara_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, unsigned char *ip); +EXTERNL int +nc_put_vars_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const unsigned char *op); +EXTERNL int +nc_get_vars_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + unsigned char *ip); +EXTERNL int +nc_put_varm_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, const unsigned char *op); +EXTERNL int +nc_get_varm_ubyte(int ncid, int varid, const size_t *startp, + const size_t *countp, const ptrdiff_t *stridep, + const ptrdiff_t * imapp, unsigned char *ip); +EXTERNL int +nc_put_var_ubyte(int ncid, int varid, const unsigned char *op); +EXTERNL int +nc_get_var_ubyte(int ncid, int varid, unsigned char *ip); +/* End Deprecated */ + +#ifdef LOGGING + +/* Set the log level. 0 shows only errors, 1 only major messages, + * etc., to 5, which shows way too much information. */ +EXTERNL int +nc_set_log_level(int new_level); + +/* Use this to turn off logging by calling + nc_log_level(NC_TURN_OFF_LOGGING) */ +#define NC_TURN_OFF_LOGGING (-1) + +#else /* not LOGGING */ + +#define nc_set_log_level(e) + +#endif /* LOGGING */ + +/* Show the netCDF library's in-memory metadata for a file. */ +EXTERNL int +nc_show_metadata(int ncid); + +/* End {put,get}_var */ + +/* #ifdef _CRAYMPP */ +/* + * Public interfaces to better support + * CRAY multi-processor systems like T3E. + * A tip of the hat to NERSC. + */ +/* + * It turns out we need to declare and define + * these public interfaces on all platforms + * or things get ugly working out the + * FORTRAN interface. On !_CRAYMPP platforms, + * these functions work as advertised, but you + * can only use "processor element" 0. + */ + +EXTERNL int +nc__create_mp(const char *path, int cmode, size_t initialsz, int basepe, + size_t *chunksizehintp, int *ncidp); + +EXTERNL int +nc__open_mp(const char *path, int mode, int basepe, + size_t *chunksizehintp, int *ncidp); + +EXTERNL int +nc_delete(const char *path); + +EXTERNL int +nc_delete_mp(const char *path, int basepe); + +EXTERNL int +nc_set_base_pe(int ncid, int pe); + +EXTERNL int +nc_inq_base_pe(int ncid, int *pe); + +/* #endif _CRAYMPP */ + +/* This v2 function is used in the nc_test program. */ +EXTERNL int +nctypelen(nc_type datatype); + +/* Begin v2.4 backward compatiblity */ +/* + * defining NO_NETCDF_2 to the preprocessor + * turns off backward compatiblity declarations. + */ +#ifndef NO_NETCDF_2 + +/** Backward compatible alias. */ +/**@{*/ +#define FILL_BYTE NC_FILL_BYTE +#define FILL_CHAR NC_FILL_CHAR +#define FILL_SHORT NC_FILL_SHORT +#define FILL_LONG NC_FILL_INT +#define FILL_FLOAT NC_FILL_FLOAT +#define FILL_DOUBLE NC_FILL_DOUBLE + +#define MAX_NC_DIMS NC_MAX_DIMS +#define MAX_NC_ATTRS NC_MAX_ATTRS +#define MAX_NC_VARS NC_MAX_VARS +#define MAX_NC_NAME NC_MAX_NAME +#define MAX_VAR_DIMS NC_MAX_VAR_DIMS +/**@}*/ + + +/* + * Global error status + */ +EXTERNL int ncerr; + +#define NC_ENTOOL NC_EMAXNAME /* Backward compatibility */ +#define NC_EXDR (-32) /* */ +#define NC_SYSERR (-31) + +/* + * Global options variable. + * Used to determine behavior of error handler. + */ +#define NC_FATAL 1 +#define NC_VERBOSE 2 + +EXTERNL int ncopts; /* default is (NC_FATAL | NC_VERBOSE) */ + +EXTERNL void +nc_advise(const char *cdf_routine_name, int err, const char *fmt,...); + +/* + * C data type corresponding to a netCDF NC_LONG argument, + * a signed 32 bit object. + * + * This is the only thing in this file which architecture dependent. + */ +typedef int nclong; + +EXTERNL int +nccreate(const char* path, int cmode); + +EXTERNL int +ncopen(const char* path, int mode); + +EXTERNL int +ncsetfill(int ncid, int fillmode); + +EXTERNL int +ncredef(int ncid); + +EXTERNL int +ncendef(int ncid); + +EXTERNL int +ncsync(int ncid); + +EXTERNL int +ncabort(int ncid); + +EXTERNL int +ncclose(int ncid); + +EXTERNL int +ncinquire(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimp); + +EXTERNL int +ncdimdef(int ncid, const char *name, long len); + +EXTERNL int +ncdimid(int ncid, const char *name); + +EXTERNL int +ncdiminq(int ncid, int dimid, char *name, long *lenp); + +EXTERNL int +ncdimrename(int ncid, int dimid, const char *name); + +EXTERNL int +ncattput(int ncid, int varid, const char *name, nc_type xtype, + int len, const void *op); + +EXTERNL int +ncattinq(int ncid, int varid, const char *name, nc_type *xtypep, int *lenp); + +EXTERNL int +ncattget(int ncid, int varid, const char *name, void *ip); + +EXTERNL int +ncattcopy(int ncid_in, int varid_in, const char *name, int ncid_out, + int varid_out); + +EXTERNL int +ncattname(int ncid, int varid, int attnum, char *name); + +EXTERNL int +ncattrename(int ncid, int varid, const char *name, const char *newname); + +EXTERNL int +ncattdel(int ncid, int varid, const char *name); + +EXTERNL int +ncvardef(int ncid, const char *name, nc_type xtype, + int ndims, const int *dimidsp); + +EXTERNL int +ncvarid(int ncid, const char *name); + +EXTERNL int +ncvarinq(int ncid, int varid, char *name, nc_type *xtypep, + int *ndimsp, int *dimidsp, int *nattsp); + +EXTERNL int +ncvarput1(int ncid, int varid, const long *indexp, const void *op); + +EXTERNL int +ncvarget1(int ncid, int varid, const long *indexp, void *ip); + +EXTERNL int +ncvarput(int ncid, int varid, const long *startp, const long *countp, + const void *op); + +EXTERNL int +ncvarget(int ncid, int varid, const long *startp, const long *countp, + void *ip); + +EXTERNL int +ncvarputs(int ncid, int varid, const long *startp, const long *countp, + const long *stridep, const void *op); + +EXTERNL int +ncvargets(int ncid, int varid, const long *startp, const long *countp, + const long *stridep, void *ip); + +EXTERNL int +ncvarputg(int ncid, int varid, const long *startp, const long *countp, + const long *stridep, const long *imapp, const void *op); + +EXTERNL int +ncvargetg(int ncid, int varid, const long *startp, const long *countp, + const long *stridep, const long *imapp, void *ip); + +EXTERNL int +ncvarrename(int ncid, int varid, const char *name); + +EXTERNL int +ncrecinq(int ncid, int *nrecvarsp, int *recvaridsp, long *recsizesp); + +EXTERNL int +ncrecget(int ncid, long recnum, void **datap); + +EXTERNL int +ncrecput(int ncid, long recnum, void *const *datap); + +/* End v2.4 backward compatiblity */ +#endif /*!NO_NETCDF_2*/ + +#if defined(__cplusplus) +} +#endif + +/* Temporary hack to shut up warnings */ +#ifndef __MINGW32_VERSION +#define END_OF_MAIN() +#endif + +#endif /* _NETCDF_ */ + + + diff --git a/extern/src_netcdf4/netcdf_f.h b/extern/src_netcdf4/netcdf_f.h new file mode 100644 index 0000000000000000000000000000000000000000..096dddd83f9780540f66442df1633bdc72ab1e81 --- /dev/null +++ b/extern/src_netcdf4/netcdf_f.h @@ -0,0 +1,63 @@ +/* + * Copyright 1993-2011 University Corporation for Atmospheric Research/Unidata + * + * This header contains prototypes for functions only called by fortran 77. + */ +#ifndef _NETCDF_F_ +#define _NETCDF_F_ + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +EXTERNL int +nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp); + +EXTERNL int +nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp); + +EXTERNL int +nc_open_par_fortran(const char *path, int mode, int comm, + int info, int *ncidp); + +EXTERNL int +nc_create_par_fortran(const char *path, int cmode, int comm, + int info, int *ncidp); + +EXTERNL int +nc_set_chunk_cache_ints(int size, int nelems, int preemption); + +EXTERNL int +nc_get_chunk_cache_ints(int *sizep, int *nelemsp, int *preemptionp); + +EXTERNL int +nc_set_var_chunk_cache_ints(int ncid, int varid, int size, int nelems, + int preemption); +EXTERNL int +nc_get_var_chunk_cache_ints(int ncid, int varid, int *sizep, + int *nelemsp, int *preemptionp); + +/* Prototypes for some extra functions in fort-lib.c. */ +EXTERNL int +nc_inq_varids_f(int ncid, int *nvars, int *fvarids); + +EXTERNL int +nc_inq_dimids_f(int ncid, int *ndims, int *fdimids, int parent); + +EXTERNL int +nc_insert_array_compound_f(int ncid, int typeid, char *name, + size_t offset, nc_type field_typeid, + int ndims, int *dim_sizesp); + +EXTERNL int +nc_inq_compound_field_f(int ncid, nc_type xtype, int fieldid, char *name, + size_t *offsetp, nc_type *field_typeidp, int *ndimsp, + int *dim_sizesp); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/extern/src_netcdf4/netcdf_par.h b/extern/src_netcdf4/netcdf_par.h new file mode 100644 index 0000000000000000000000000000000000000000..1dd003720a7ca9656e7f3e7a3b8a4b9cb7459de9 --- /dev/null +++ b/extern/src_netcdf4/netcdf_par.h @@ -0,0 +1,50 @@ +/* + * Copyright 2010 University Corporation for Atmospheric + * Research/Unidata. See COPYRIGHT file for more info. + * + * This header file is for the parallel I/O functions of netCDF. + * + */ +/* "$Id: netcdf_par.h,v 1.1 2010/06/01 15:46:49 ed Exp $" */ + +#ifndef NETCDF_PAR_H +#define NETCDF_PAR_H 1 + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Use these with nc_var_par_access(). */ +#define NC_INDEPENDENT 0 +#define NC_COLLECTIVE 1 + +/* Create a file and enable parallel I/O. */ +extern int +nc_create_par(const char *path, int cmode, MPI_Comm comm, MPI_Info info, + int *ncidp); + +/* Open a file and enable parallel I/O. */ +extern int +nc_open_par(const char *path, int mode, MPI_Comm comm, MPI_Info info, + int *ncidp); + +/* Change a variable from independent (the default) to collective + * access. */ +extern int +nc_var_par_access(int ncid, int varid, int par_access); + +extern int +nc_create_par_fortran(const char *path, int cmode, int comm, + int info, int *ncidp); +extern int +nc_open_par_fortran(const char *path, int mode, int comm, + int info, int *ncidp); + +#if defined(__cplusplus) +} +#endif + +#endif /* NETCDF_PAR_H */ diff --git a/extern/src_netcdf4/oc.c b/extern/src_netcdf4/oc.c new file mode 100644 index 0000000000000000000000000000000000000000..e8143f30feaeebf7053228688ab2c819f43af042 --- /dev/null +++ b/extern/src_netcdf4/oc.c @@ -0,0 +1,957 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include +#include +#include + +#include "oc.h" +#include "ocinternal.h" +#include "occontent.h" +#include "ocdebug.h" +#include "ocdump.h" +#include "oclog.h" +#include "occlientparams.h" +#include "ochttp.h" + +#undef TRACK + +/**************************************************/ + +static int ocinitialized = 0; + +/**************************************************/ +/* Track legal ids */ + +#ifdef OC_FASTCONSISTENCY + +#define ocverify(object) ((object) != NULL && (*(object) == OCMAGIC)?1:0) + +#define ocassign(object) ((OCobject)(object)) +#define ocassignall(list) + +#else /*!OC_FASTCONSISTENCY*/ + +static OClist* ocmap = NULL; + +static int +ocverify(unsigned long object) +{ + unsigned int i; + void** map = (void**)oclistcontents(ocmap); + unsigned int len = oclistlength(ocmap); +#ifdef TRACK +fprintf(stderr,"verify: %lu\n",object); fflush(stderr); +#endif + if(object > 0) { + for(i=0;iroot; + if(root == NULL) return 0; + nodes = root->tree->nodes; + nobjects = oclistlength(nodes); + return nobjects; +} + +/* Return all the OCobjects associated with a tree with specified root */ +OCobject* +oc_inq_objects(OCconnection conn, OCobject root0) +{ + unsigned int i; + OCnode* root; + OClist* nodes; + OCobject* objects = NULL; + unsigned int nobjects; + OCVERIFYX(OCnode*,root,root0,OCNULL); + OCDEREF(OCnode*,root,root0); + + if(root == NULL) return NULL; + root = root->root; + if(root == NULL) return NULL; + nodes = root->tree->nodes; + nobjects = oclistlength(nodes); + if(nodes != NULL && nobjects > 0) { + size_t len = sizeof(OCobject)*(1+nobjects); + objects = (OCobject*)ocmalloc(len); + for(i=0;iroot; + if(root == NULL) return NULL; + return root->tree->text; +} + +OCerror +oc_inq_object(OCconnection conn, + OCobject node0, + char** namep, + OCtype* objecttypep, + OCtype* primitivetypep, /* if objecttype == OC_Primitive */ + OCobject* containerp, + unsigned int* rankp, + unsigned int* subnodesp, + unsigned int* nattrp) +{ + OCnode* node; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(namep) *namep = nulldup(node->name); + if(objecttypep) *objecttypep = node->octype; + if(primitivetypep) *primitivetypep = node->etype; + if(rankp) *rankp = node->array.rank; + if(containerp) *containerp = (OCobject)node->container; + if(subnodesp) *subnodesp = oclistlength(node->subnodes); + if(nattrp) { + if(node->octype == OC_Attribute) { + *nattrp = oclistlength(node->att.values); + } else { + *nattrp = oclistlength(node->attributes); + } + } + return OC_NOERR; +} + +/* Useful accessor functions */ +OCerror +oc_inq_name(OCconnection conn, OCobject node0, char** namep) +{ + OCstate* state; + OCnode* node; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(state == NULL || node == NULL) return OC_EINVAL; + if(namep) *namep = nulldup(node->name); + return OC_NOERR; +} + +OCerror +oc_inq_nsubnodes(OCconnection conn, OCobject node0, unsigned int* nsubnodesp) +{ + OCnode* node; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(nsubnodesp) *nsubnodesp = oclistlength(node->subnodes); + return OC_NOERR; +} + +OCerror +oc_inq_primtype(OCconnection conn, OCobject node0, OCtype* typep) +{ + OCnode* node; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(typep) *typep = node->etype; + return OC_NOERR; +} + +/* Alias for oc_inq_class */ +OCerror +oc_inq_type(OCconnection conn, OCobject node0, OCtype* typep) +{ + return oc_inq_class(conn,node0,typep); +} + +OCerror +oc_inq_class(OCconnection conn, OCobject node0, OCtype* typep) +{ + OCnode* node; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(typep) *typep = node->octype; + return OC_NOERR; +} + +OCerror +oc_inq_rank(OCconnection conn, OCobject node0, unsigned int* rankp) +{ + OCnode* node; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(rankp) *rankp = node->array.rank; + return OC_NOERR; +} + +OCerror +oc_inq_nattr(OCconnection conn, OCobject node0, unsigned int* nattrp) +{ + OCnode* node; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(nattrp) { + if(node->octype == OC_Attribute) { + *nattrp = oclistlength(node->att.values); + } else { + *nattrp = oclistlength(node->attributes); + } + } + return OC_NOERR; +} + +OCerror +oc_inq_root(OCconnection conn, OCobject node0, OCobject* rootp) +{ + OCnode* node; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(rootp) *rootp = (OCobject)node->root; + return OC_NOERR; +} + +OCerror +oc_inq_container(OCconnection conn, OCobject node0, OCobject* containerp) +{ + OCnode* node; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(containerp) *containerp = (OCobject)node->container; + return OC_NOERR; +} + +/* Return the subnode objects, if any, for a given object */ +/* Caller must free returned list */ +OCerror +oc_inq_subnodes(OCconnection conn, OCobject node0, OCobject** subnodesp) +{ + OCnode* node; + OCobject* subnodes = NULL; + unsigned int len; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + len = oclistlength(node->subnodes); + if(len > 0) { + unsigned int i; + subnodes = (OCobject*)occalloc(sizeof(OCobject),len+1); + for(i=0;isubnodes,i); + subnodes[i] = (OCobject)ocnode; + } + subnodes[len] = OCNULL; /* NULL terminate */ + } + if(subnodesp) *subnodesp = subnodes; + return OC_NOERR; +} + +OCerror +oc_inq_ith(OCconnection conn, + OCobject node0, unsigned int index, OCobject* subnodeidp) +{ + OCnode* node; + OCobject subnodeid = OCNULL; + unsigned int nsubnodes; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + nsubnodes = oclistlength(node->subnodes); + if(nsubnodes > 0 && index < nsubnodes) { + subnodeid = (OCobject)oclistget(node->subnodes,index); + } else + return OC_EINVAL; + if(subnodeidp) *subnodeidp = subnodeid; + return OC_NOERR; +} + +/* Return the dimension objects, if any, for a given object */ +/* Caller must free returned dimids */ +OCerror +oc_inq_dimset(OCconnection conn, OCobject node0, OCobject** dimids) +{ + OCnode* node; + OCobject* dims = NULL; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(node->array.rank > 0) { + unsigned int i; + dims = (OCobject*)occalloc(sizeof(OCobject),node->array.rank+1); + for(i=0;iarray.rank;i++) { + OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i); + dims[i] = (OCobject)dim; + } + dims[node->array.rank] = OCNULL; + } + if(dimids) *dimids = dims; + return OC_NOERR; +} + + +OCerror +oc_inq_ithdim(OCconnection conn, OCobject node0, unsigned int index, OCobject* dimidp) +{ + OCnode* node; + OCobject dimid = OCNULL; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + if(node->array.rank > 0 && index < node->array.rank) { + dimid = (OCobject)oclistget(node->array.dimensions,index); + } else + return OC_EINVAL; + if(dimidp) *dimidp = dimid; + return OC_NOERR; +} + +OCerror +oc_inq_dim(OCconnection conn, OCobject node0, size_t* sizep, char** namep) +{ + OCnode* dim; + OCVERIFY(OCnode*,dim,node0); + OCDEREF(OCnode*,dim,node0); + + if(dim->octype != OC_Dimension) return OC_EINVAL; + if(sizep) *sizep = dim->dim.declsize; + if(namep) *namep = nulldup(dim->name); + return OC_NOERR; +} + +/* Obtain info about the ith attribute attached to a given DDS node*/ + +/* This procedure returns the value as the original DAS string */ +OCerror +oc_inq_attrstrings(OCconnection conn, OCobject node0, unsigned int i, + char** namep, OCtype* octypep, + unsigned int* nvaluesp, char*** stringsp) +{ + OCnode* node; + OCattribute* attr; + unsigned int nattrs; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + nattrs = oclistlength(node->attributes); + if(i >= nattrs) return OC_EINVAL; + attr = (OCattribute*)oclistget(node->attributes,i); + if(namep) *namep = strdup(attr->name); + if(octypep) *octypep = attr->etype; + if(nvaluesp) *nvaluesp = attr->nvalues; + if(stringsp) { + if(attr->nvalues > 0) { + size_t space = attr->nvalues * sizeof(char*); + char** strings = ocmalloc(space); + for(i=0;invalues;i++) + strings[i] = nulldup(attr->values[i]); + *stringsp = strings; + } else + *stringsp = NULL; + } + return OC_NOERR; +} + +/* This procedure returns the value as the default binary value + corresponding to the string value +*/ + +OCerror +oc_inq_attr(OCconnection conn, OCobject node0, unsigned int i, + char** namep, OCtype* octypep, unsigned int* nvaluesp, void** valuesp) +{ + OCnode* node; + OCattribute* attr; + unsigned int nattrs; + OCVERIFY(OCnode*,node,node0); + OCDEREF(OCnode*,node,node0); + + nattrs = oclistlength(node->attributes); + if(i >= nattrs) return OC_EINVAL; + attr = (OCattribute*)oclistget(node->attributes,i); + if(namep) *namep = strdup(attr->name); + if(octypep) *octypep = attr->etype; + if(nvaluesp) *nvaluesp = attr->nvalues; + if(valuesp && attr->nvalues > 0) { + void* memory = NULL; + memory = oclinearize(attr->etype,attr->nvalues,attr->values); + *valuesp = memory; + } + return OC_NOERR; +} + +/* Convenience function */ +void +oc_attr_reclaim(OCtype etype, unsigned int nvalues, void* values) +{ + if(nvalues == 0 || values == NULL) return; + if(etype == OC_String || etype == OC_URL) { + unsigned int i; + char** strings = (char**)values; + for(i=0;ioctype != OC_Attribute) return OC_EINVAL; + if(nvaluesp) *nvaluesp = oclistlength(attr->att.values); + return OC_NOERR; +} + +OCerror +oc_inq_dasattr(OCconnection conn, OCobject node0, unsigned int i, + OCtype* primtypep, char** valuep) +{ + OCnode* attr; + unsigned int nvalues; + OCVERIFY(OCnode*,attr,node0); + OCDEREF(OCnode*,attr,node0); + + if(attr->octype != OC_Attribute) return OC_EINVAL; + nvalues = oclistlength(attr->att.values); + if(i >= nvalues) return OC_EINVAL; + if(valuep) *valuep = nulldup((char*)oclistget(attr->att.values,i)); + if(primtypep) *primtypep = attr->etype; + return OC_NOERR; +} + +/**************************************************/ +/* Fetch and parse a given class of DXD the server specified + at open time, and using a specified set of constraints. + Return the root node of the parsed tree of objects. +*/ +OCerror oc_fetch(OCconnection conn, const char* constraint, + OCdxd dxdkind, OCobject* rootp) +{ + return oc_fetchf(conn,constraint,dxdkind,0,rootp); +} + +OCerror oc_fetchf(OCconnection conn, const char* constraint, + OCdxd dxdkind, OCflags flags, OCobject* rootp) +{ + OCstate* state; + OCerror ocerr = OC_NOERR; + OCnode* root; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + + ocerr = ocfetchf(state,constraint,dxdkind,flags,&root); + if(ocerr) return ocerr; + + ocassignall(root->tree->nodes); + if(rootp) *rootp = (OCobject)ocassign(root); + return ocerr; +} + + +OCerror +oc_data_root(OCconnection conn, OCobject root0, OCdata content0) +{ + OCstate* state; + OCnode* root; + OCcontent* content; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCnode*,root,root0); + OCDEREF(OCnode*,root,root0); + OCVERIFY(OCcontent*,content,content0); + OCDEREF(OCcontent*,content,content0); + + if(root->tree == NULL) {OCTHROWCHK((ocerr=OC_EINVAL)); goto fail;} + ocerr = ocrootdata(state,root,content); + +fail: + return ocerr; +} + +OCdata +oc_data_new(OCconnection conn) +{ + OCstate* state; + OCVERIFYX(OCstate*,state,conn,OCNULL); + OCDEREF(OCstate*,state,conn); + + return (OCdata)ocassign(ocnewcontent(state)); +} + +OCerror +oc_data_free(OCconnection conn, OCdata content0) +{ + OCstate* state; + OCcontent* content; + if(content0 == OCNULL) return OC_NOERR; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCcontent*,content,content0); + OCDEREF(OCcontent*,content,content0); + + ocfreecontent(state,content); + return OC_NOERR; +} + +OCerror +oc_data_ith(OCconnection conn, OCdata parentdata, size_t index, OCdata subdata) +{ + OCstate* state; + OCcontent* parent; + OCcontent* child; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCcontent*,parent,parentdata); + OCDEREF(OCcontent*,parent,parentdata); + OCVERIFY(OCcontent*,child,subdata); + OCDEREF(OCcontent*,child,subdata); + ocerr = ocdataith(state,parent,index,child); + return ocerr; +} + +OCerror +oc_data_get(OCconnection conn, OCdata currentcontent, + void* memory, size_t memsize, size_t start, size_t count) +{ + OCstate* state; + OCcontent* current; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCcontent*,current,currentcontent); + OCDEREF(OCcontent*,current,currentcontent); + + ocerr = ocgetcontent(state,current,memory,memsize,start,count); + + if(ocerr == OC_EDATADDS) ocdataddsmsg(state,current->tree); + + return ocerr; +} + +OCerror +oc_data_count(OCconnection conn, OCdata content0, size_t* sizep) +{ + OCstate* state; + OCcontent* current; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCcontent*,current,content0); + OCDEREF(OCcontent*,current,content0); + ocerr = ocdatacount(state, current, sizep); + return ocerr; +} + +OCerror +oc_data_index(OCconnection conn, OCdata content0, size_t* sizep) +{ + OCcontent* current; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCcontent*,current,content0); + OCDEREF(OCcontent*,current,content0); + + if(sizep) + *sizep = (current->cache.valid ? current->cache.index : 0); + return ocerr; +} + +OCerror +oc_data_object(OCconnection conn, OCdata content0, OCobject* op) +{ + OCcontent* current; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCcontent*,current,content0); + OCDEREF(OCcontent*,current,content0); + + if(op) *op = (OCobject)current->node; + return ocerr; +} + +OCerror +oc_data_mode(OCconnection conn, OCdata content0, OCmode* modep) +{ + OCcontent* current; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCcontent*,current,content0); + OCDEREF(OCcontent*,current,content0); + + if(modep) *modep = current->mode; + return ocerr; +} + +/**************************************************/ +/* OCtype management */ +size_t oc_typesize(OCtype etype) +{ + return octypesize(etype); +} + +const char* +oc_typetostring(OCtype octype) +{ + return octypetoddsstring(octype); +} + +OCerror +oc_typeprint(OCtype etype, char* buf, size_t bufsize, void* value) +{ + return octypeprint(etype,buf,bufsize,value); +} + +/**************************************************/ +/* The oc_logXXX procedures are define in oclog.c */ + +/**************************************************/ +/* Miscellaneous */ + +const char* +oc_errstring(int err) +{ + return ocerrstring(err); +} + +/* Get clientparameters from the URL */ +const char* +oc_clientparam_get(OCconnection conn, const char* param) +{ + OCstate* state; + OCVERIFYX(OCstate*,state,conn,NULL); + OCDEREF(OCstate*,state,conn); + + return ocparamlookup(state,param); +} + +#ifdef OCIGNORE +/* Delete client parameter + return value: + OC_NOERR => defined; deletion performed + OC_EINVAL => not already defined +*/ +OCerror +oc_clientparam_delete(OCconnection conn, const char* param) +{ + OCstate* state; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + + return ocparamdelete(state->clientparams,param); +} + +/* Insert client parameter + return value: + OC_NOERR => not already define; insertion performed + OC_EINVAL => already defined +*/ +OCerror +oc_clientparam_insert(OCconnection conn, const char* param, const char* value) +{ + OCstate* state; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + + state->clientparams = dapparaminsert(state->clientparams,param,value); + return OC_NOERR; +} + +/* Replace client parameter + return value: + OC_NOERR => already define; replacement performed + OC_EINVAL => not already defined +*/ +OCerror +oc_clientparam_replace(OCconnection conn, const char* param, const char* value) +{ + OCstate* state; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + + return dapparamreplace(state->clientparams,param,value); +} +#endif + +OCerror +oc_dd(OCconnection conn, OCobject root0, int level) +{ + OCstate* state; + OCnode* root; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCnode*,root,root0); + OCDEREF(OCnode*,root,root0); + + ocdd(state,root,1,level); + return OC_NOERR; +} + +OCerror +oc_ddnode(OCconnection conn, OCobject root0) +{ + OCnode* root; + OCVERIFY(OCnode*,root,root0); + OCDEREF(OCnode*,root,root0); + + ocdumpnode(root); + return OC_NOERR; +} + +/* Merge a specified DAS into a specified DDS or DATADDS */ +OCerror +oc_attach_das(OCconnection conn, OCobject dasroot, OCobject ddsroot) +{ + OCstate* state; + OCnode* das; + OCnode* dds; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCnode*,das,dasroot); + OCDEREF(OCnode*,das,dasroot); + OCVERIFY(OCnode*,dds,ddsroot); + OCDEREF(OCnode*,dds,ddsroot); + + return ocddsdasmerge(state,das,dds); +} + +#if 0 +/* +I suppressed this operation because I realized that it +appears to be impossible to implement correctly in general. +It also exposes a flaw in the protocol. +If I have a dds with two identical Grids, G1 and G2, +and I ask for the projection ?G1.temp,G2.temp, +then I get back a DATADDS with duplicated temp fields, +which means the DATADDS is illegal. The problem is that +the protocol throws away important scoping information +about the fact that each temp field is part of a different +grid. +*/ +/* Connect a specified DATADDS tree to a specified DDS tree */ +OCerror +oc_attach_datadds(OCconnection conn, OCobject dataddsroot, OCobject ddsroot) +{ + OCstate* state; + OCnode* dxd; + OCnode* dds; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCnode*,dxd,dataddsroot); + OCDEREF(OCnode*,dxd,dataddsroot); + OCVERIFY(OCnode*,dds,ddsroot); + OCDEREF(OCnode*,dds,ddsroot); + + /* get the true roots */ + dds = dds->root; + dxd = dxd->root; + if(dds == NULL || dxd == NULL) return OC_EBADID; + /* correlate the DATADDS to the DDS */ + return occorrelate(dxd,dds); +} + +/* Return the attached DATADDS object for a given DDS object */ +OCerror oc_inq_datadds(OCconnection conn, OCobject dds0, OCobject* dataddsp) +{ + OCstate* state; + OCnode* dds; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + OCVERIFY(OCnode*,dds,dds0); + OCDEREF(OCnode*,dds,dds0); + + if(dataddsp) *dataddsp = (OCobject)dds->datadds; + return OC_NOERR; +} +#endif + +/**************************************************/ + +OCerror +oc_svcerrordata(OCconnection conn, char** codep, + char** msgp, long* httpp) +{ + OCstate* state; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + return ocsvcerrordata(state,codep,msgp,httpp); +} + + +/**************************************************/ +/* Experimental: this is useful for the netcdf + DRNO project. +*/ + +/* New 10/31/2009: return the size (in bytes) + of the fetched datadds. +*/ + +OCerror +oc_raw_xdrsize(OCconnection conn, OCobject root0, size_t* sizep) +{ + OCnode* root; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCnode*,root,root0); + OCDEREF(OCnode*,root,root0); + + if(sizep == NULL) goto done; + if(root->tree == NULL || root->tree->dxdclass != OCDATADDS) + {OCTHROWCHK((ocerr=OC_EINVAL)); goto done;} + if(sizep) *sizep = root->tree->data.datasize; + +done: + return ocerr; +} + +/* Resend a url as a head request to check the Last-Modified time */ +OCerror +oc_update_lastmodified_data(OCconnection conn) +{ + OCstate* state; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + return ocupdatelastmodifieddata(state); +} + +long +oc_get_lastmodified_data(OCconnection conn) +{ + OCstate* state; + OCVERIFY(OCstate*,state,conn); + OCDEREF(OCstate*,state,conn); + return state->datalastmodified; +} + +int +oc_dumpnode(OCconnection conn, OCobject root0) +{ + OCnode* root; + OCerror ocerr = OC_NOERR; + OCVERIFY(OCnode*,root,root0); + OCDEREF(OCnode*,root,root0); + ocdumpnode(root); + return ocerr; +} + +OCerror +oc_ping(const char* url) +{ + return ocping(url); +} + diff --git a/extern/src_netcdf4/oc.h b/extern/src_netcdf4/oc.h new file mode 100644 index 0000000000000000000000000000000000000000..8f91a6394ec485bdd9856ca37b187cc874e1573a --- /dev/null +++ b/extern/src_netcdf4/oc.h @@ -0,0 +1,443 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT dap for more information. */ + +/* +Draft OC External Interface +Created: 4/4/2009 +Last Revised: 4/14/2009 +*/ + +#ifndef OC_H +#define OC_H + +#include +#include + +/* if defined, use magic numbers for consistency]) */ +#define OC_FASTCONSISTENCY + +/* OC_MAX_DIMS should be greater or equal to max allowed by dap or netcdf*/ +#define OC_MAX_DIMS 1024 + +/* Specifies the OCtype.*/ +/* Primitives = Duplicate of the NODE_Byte..Node_URL union nc_type*/ + +typedef unsigned long OCtype; + +/* Note: use #define rather than enum so we can extend if needed + more easily */ +/* Primitives*/ +/* OC_Ubyte, OC_Char, OC_Int64 and OC_UInt64 are defined for future extension*/ +#define OC_NAT ((OCtype)0) +#define OC_Char ((OCtype)1) +#define OC_Byte ((OCtype)2) +#define OC_UByte ((OCtype)3) +#define OC_Int16 ((OCtype)4) +#define OC_UInt16 ((OCtype)5) +#define OC_Int32 ((OCtype)6) +#define OC_UInt32 ((OCtype)7) +#define OC_Int64 ((OCtype)8) +#define OC_UInt64 ((OCtype)9) +#define OC_Float32 ((OCtype)10) +#define OC_Float64 ((OCtype)11) +#define OC_String ((OCtype)12) +#define OC_URL ((OCtype)13) + +/* Non-primitives*/ +#define OC_Dataset ((OCtype)100) +#define OC_Sequence ((OCtype)101) +#define OC_Grid ((OCtype)102) +#define OC_Structure ((OCtype)103) +#define OC_Dimension ((OCtype)104) +#define OC_Attribute ((OCtype)105) +#define OC_Attributeset ((OCtype)106) +#define OC_Primitive ((OCtype)107) +#define OC_Group ((OCtype)108) +#define OC_Type ((OCtype)109) + +/* Define a set of error + positive are system errors + (needs work) +*/ + +typedef int OCerror; +#define OC_NOERR (0) +#define OC_EBADID (-1) +#define OC_ECHAR (-2) +#define OC_EDIMSIZE (-3) +#define OC_EEDGE (-4) +#define OC_EINVAL (-5) +#define OC_EINVALCOORDS (-6) +#define OC_ENOMEM (-7) +#define OC_ENOTVAR (-8) +#define OC_EPERM (-9) +#define OC_ESTRIDE (-10) +#define OC_EDAP (-11) +#define OC_EXDR (-12) +#define OC_ECURL (-13) +#define OC_EBADURL (-14) +#define OC_EBADVAR (-15) +#define OC_EOPEN (-16) +#define OC_EIO (-17) +#define OC_ENODATA (-18) +#define OC_EDAPSVC (-19) +#define OC_ENAMEINUSE (-20) +#define OC_EDAS (-21) +#define OC_EDDS (-22) +#define OC_EDATADDS (-23) +#define OC_ERCFILE (-24) +#define OC_ENOFILE (-25) + +/* Define the classes of DAP DXD objects */ +typedef int OCdxd; +#define OCDDS 0 +#define OCDAS 1 +#define OCDATADDS 2 +#define OCDATA OCDATADDS + +/* Define flags */ +typedef int OCflags; +#define OCONDISK 1 + +typedef enum OCmode { +OCNULLMODE = 0, +OCFIELDMODE = 1, +OCSEQUENCEMODE = 2, +OCARRAYMODE = 3, +OCPRIMITIVEMODE = 4, +OCEMPTYMODE = 0x8000000 /* internal use only */ +} OCmode; + + +/* Define an unsigned alternative to off(64)_t*/ +typedef unsigned long long ocoffset_t; + +/* Define a wrapper for dimension sizes */ +typedef size_t ocindex_t; + +/* Define the effective API */ + +#ifndef OCINTERNAL_H + +/* The OCobject type references a component of a DAS or DDS + (e.g. Sequence, Grid, Dataset, etc). These objects + are nested, so most objects reference a container object + and subnode objects. +*/ + + +#ifdef OC_FASTCONSISTENCY +/* Use unsigned int * so we can dereference to get magic number */ +typedef unsigned int* OCobject; +#define OCNULL NULL +#else +typedef unsigned long OCobject; +#define OCNULL ((OCobject)0) +#endif + +/* These are the two critical types*/ +/* Think of OClink as analogous to the C stdio FILE structure; + it "holds" all the other state info about + a connection to the server, the url request, and the DAS/DDS/DATADDSinfo. +*/ +/* Renamed from OCconnection because of confusion about term "connection" + 3/24/2010 by dmh +*/ +typedef OCobject OClink; + +/* Keep old name for back compatibility */ +typedef OClink OCconnection; /*Deprecated*/ + +/* Tag kind of log entry*/ +#define OCLOGNOTE 0 +#define OCLOGWARN 1 +#define OCLOGERR 2 +#define OCLOGDBG 3 + +/**************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int oc_dumpnode(OClink conn, OCobject root0); + +/**************************************************/ +/* Link management */ + +extern OCerror oc_open(const char* url, OClink*); +extern OCerror oc_close(OClink); + +/**************************************************/ +/* Root management */ +/* Fetch and parse a given class of DXD the server specified + at open time, and using a specified set of constraints + and flags. + Return the root node of the parsed tree of objects. +*/ +extern OCerror oc_fetchf(OClink, + const char* constraints, + OCdxd, + OCflags, + OCobject* rootp); + + +/* + Equivalent to oc_fetchf with zero flag parameter +*/ +extern OCerror oc_fetch(OClink, + const char* constraints, + OCdxd, + OCobject* rootp); + +/* Release/reclaim the tree of objects associated with a given root */ +extern OCerror oc_root_free(OClink, OCobject root); + +/* Return the # of OCobjects associated with a tree with specified root */ +extern unsigned int oc_inq_nobjects(OClink, OCobject root); + +/* Return all the OCobjects associated with a tree with specified root */ +extern OCobject* oc_inq_objects(OClink, OCobject root); + +/* Return the text of the DDS or DAS as received from the server */ +extern const char* oc_inq_text(OClink, OCobject root); + +/**************************************************/ +/* Object Management */ + +/* Any of the pointers may be NULL in the following procedure call; + If the object is of type Dataset, then return # of global attributes + If the object is of type Attribute, then return the # of values in nattrp. + The caller must free the resulting name string. +*/ +extern OCerror oc_inq_object(OClink, OCobject, + char** namep, + OCtype* typep, + OCtype* primitivetypep, /* if objecttype == OC_Primitive */ + OCobject* parentp, + unsigned int* rankp, + unsigned int* nsubnodesp, + unsigned int* nattrp); + +/* Also define some more individual accessors */ + +extern OCerror oc_inq_name(OClink,OCobject,char**); +extern OCerror oc_inq_class(OClink,OCobject,OCtype*); +extern OCerror oc_inq_type(OClink,OCobject,OCtype*); /*alias for oc_inq_class*/ +extern OCerror oc_inq_primtype(OClink,OCobject,OCtype*); +extern OCerror oc_inq_nsubnodes(OClink,OCobject,unsigned int*); +extern OCerror oc_inq_rank(OClink,OCobject,unsigned int*); +extern OCerror oc_inq_nattr(OClink,OCobject,unsigned int*); +extern OCerror oc_inq_root(OClink,OCobject,OCobject*); +extern OCerror oc_inq_container(OClink,OCobject,OCobject*); + +/* Return the subnode objects, if any, associated with a given object. +Caller must free the returned subnodes memory. +*/ +extern OCerror oc_inq_subnodes(OClink,OCobject,OCobject** subnodes); + +/* Return the i'th subnode object, if any, associated with a given object */ +/* If there is none such, then return OC_EINVAL */ +extern OCerror oc_inq_ith(OClink,OCobject, unsigned int, OCobject*); + +/* Return the dimension objects, if any, associated with a given object */ +/* Caller must free returned vector for dimids */ +/* If there are no dimensions (i.e. rank == 0), then return NULL */ +extern OCerror oc_inq_dimset(OClink,OCobject, OCobject** dimids); + +/* Return the i'th dim object, if any, associated with a given object */ +/* If there is no such dim, then return OC_EINVAL */ +extern OCerror oc_inq_ithdim(OClink,OCobject, unsigned int, OCobject*); + +/* Return the size and name associated with a given dimension object + as defined in the DDS +*/ +extern OCerror oc_inq_dim(OClink,OCobject,ocindex_t*,char**); + +/* Attribute Management */ + +/* Added: 11/2/2009 DMH: + Provide access to DDS node attributes + in the form of the original underlying + DAS string. + One specifies the DDS root to get the global attributes. + Caller must free returned strings. +*/ + +extern OCerror oc_inq_attrstrings(OClink,OCobject, unsigned int i, + char** name, OCtype* octype, + unsigned int* nvalues,char*** stringvalues); + +/* Obtain the attributes associated with a given DDS OCobject. + One specifies the DDS root to get the global attributes + This code takes the DAS strings and does a default + conversion to binary values. +*/ +extern OCerror oc_inq_attr(OClink,OCobject, unsigned int i, + char** name,OCtype* octype, + unsigned int* nvalues,void** values); + +/* Convenience function to simplify reclaiming the allocated attribute + value memory +*/ +extern void oc_attr_reclaim(OCtype, unsigned int nvalues, void* values); + +/* Access ith value string of a DAS object. + OCtype of the object is assumed to be OC_Attribute. + Note that this is different than the above inq_attr + and inq_attrstrings, which work on DDS + objects. Note also that the return value is always a string. + Caller must free returned string. +*/ + +extern OCerror oc_inq_dasattr_nvalues(OClink, OCobject, + unsigned int* nvaluesp); + +extern OCerror oc_inq_dasattr(OClink,OCobject, unsigned int, + OCtype* primtypep, char** valuep); + +/**************************************************/ +/* Data management */ + +/* +These procedures allow for the location and extraction +of data from the data packet part of a DATADDS. +See ocuserman.html for detailed description. +*/ + +typedef OCobject OCdata; + +/* Obtain the OCdata object that references the + whole data from a DATADDS fetch request specified + by the root object. This does not access the server. +*/ +extern OCerror oc_data_root(OClink, OCobject root, OCdata); + +/* Create an empty OCdata object */ +extern OCdata oc_data_new(OClink); + +/* Reclaim a no longer needed OCdata object */ +extern OCerror oc_data_free(OClink, OCdata); + +/* Given an OCdata object, set the nested subnode OCdata object + to refer to the data associated with the i'th element of + the parent data object. NOTE: if the i'th element is not + present then this function will return OC_ENODATA. + See the user's manual for details on mapping multi- + dimensional arrays to single indices. +*/ +extern OCerror oc_data_ith(OClink, + OCdata parentdata, + ocindex_t index, + OCdata subdata); + +/* Return the actual data values associated with the specified OCdata. + The OCdata is assumed to be referencing either a scalar + primitive value or a (1d) array of primitive values. + If scalar, then index must be 0 and count must be 1. +*/ +extern OCerror oc_data_get(OClink,OCdata, + void* memory, size_t memsize, + ocindex_t index, ocindex_t count); + +/* Return the OCdata's current index */ +extern OCerror oc_data_index(OClink,OCdata, ocindex_t*); + +/* Return the mode associated the specified OCdata object */ +extern OCerror oc_data_mode(OClink,OCdata, OCmode*); + +/* Return the OCobject associated the specified OCdata object */ +extern OCerror oc_data_object(OClink,OCdata, OCobject*); + +/* Compute the the count associated with the specified OCdata + instance. Note: this is potentially computationally costly + when computing # records. +*/ +extern OCerror oc_data_count(OClink, OCdata, ocindex_t*); + +/**************************************************/ +/* Misc. OCtype-related functions */ + +/* Return size of the given type (Primitive only) */ +extern size_t oc_typesize(OCtype); + +/* Return a canonical printable string describing a given type: + e.g. Byte, Int16, etc. +*/ +extern const char* oc_typetostring(OCtype); + +/* Given a value of a primitive OC type, provide a canonical + string representing that value +*/ +extern OCerror oc_typeprint(OCtype, char* buf, size_t bufsize, void* value); + +/**************************************************/ +/* Logging */ + +extern void oc_loginit(void); +extern void oc_setlogging(int onoff); /* 1=>start logging 0=>stop */ +extern void oc_logopen(const char* logfilename); +extern void oc_logclose(void); + +extern void oc_logtext(int tag, const char* text); + +extern void oc_log(int tag, const char* fmt, ...); + +/**************************************************/ +/* Miscellaneous */ + +/* Convert an OCerror to a human readable string */ +extern const char* oc_errstring(int err); + +/* Get client parameters from the URL + DO NOT free the result +*/ +extern const char* oc_clientparam_get(OClink, const char* param); + +extern OCerror oc_clientparam_delete(OClink, const char* param); +extern OCerror oc_clientparam_insert(OClink, const char* param, const char* value); +extern OCerror oc_clientparam_replace(OClink, const char* param, const char* value); + +/**************************************************/ +/* Merging operations */ + +/* Merge a specified DAS into a specified DDS or DATADDS */ +extern OCerror oc_attach_das(OClink, OCobject dasroot, OCobject ddsroot); + +/**************************************************/ +/* Debugging */ +extern OCerror oc_dd(OClink,OCobject,int level); +extern OCerror oc_ddnode(OClink,OCobject); + +/* When a server error is detected, then it is possible + to get the server error info using this procedure */ +extern OCerror oc_svcerrordata(OClink link, char** codep, + char** msgp, long* httpp); + + + +/**************************************************/ +/* Experimental */ + +/* New 10/31/2009: return raw information about a datadds +*/ + +extern OCerror oc_raw_xdrsize(OClink, OCobject, size_t*); + +/* Resend a url as a head request to check the Last-Modified time */ +extern OCerror oc_update_lastmodified_data(OClink); + +/* Get last known modification time; -1 => data unknown */ +extern long oc_get_lastmodified_data(OClink); + +extern OCerror oc_ping(const char* url); + +/**************************************************/ + +#endif /*OCINTERNAL_H*/ + +#ifdef __cplusplus +} +#endif + +#endif /*OC_H*/ diff --git a/extern/src_netcdf4/ocbytes.c b/extern/src_netcdf4/ocbytes.c new file mode 100644 index 0000000000000000000000000000000000000000..7fe2f7995a1ef7f0ec3a29ba8726e89ac82178e5 --- /dev/null +++ b/extern/src_netcdf4/ocbytes.c @@ -0,0 +1,190 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" + +#include +#include +#include + +#include "ocbytes.h" + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define DEFAULTALLOC 1024 +#define ALLOCINCR 1024 + +static int ocbytesdebug = 1; + +static long +ocbytesfail(void) +{ + fflush(stdout); + fprintf(stderr,"bytebuffer failure\n"); + fflush(stderr); + if(ocbytesdebug) abort(); + return FALSE; +} + +OCbytes* +ocbytesnew(void) +{ + OCbytes* bb = (OCbytes*)malloc(sizeof(OCbytes)); + if(bb == NULL) return (OCbytes*)ocbytesfail(); + bb->alloc=0; + bb->length=0; + bb->content=NULL; + bb->nonextendible = 0; + return bb; +} + +int +ocbytessetalloc(OCbytes* bb, unsigned int sz) +{ + char* newcontent; + if(bb == NULL) return ocbytesfail(); + if(sz <= 0) {sz = (bb->alloc?2*bb->alloc:DEFAULTALLOC);} + if(bb->alloc >= sz) return TRUE; + if(bb->nonextendible) return ocbytesfail(); + newcontent=(char*)calloc(sz,sizeof(char)); + if(newcontent == NULL) return FALSE; + if(bb->alloc > 0 && bb->length > 0 && bb->content != NULL) { + memcpy((void*)newcontent,(void*)bb->content,sizeof(char)*bb->length); + } + if(bb->content != NULL) free(bb->content); + bb->content=newcontent; + bb->alloc=sz; + return TRUE; +} + +void +ocbytesfree(OCbytes* bb) +{ + if(bb == NULL) return; + if(!bb->nonextendible && bb->content != NULL) free(bb->content); + free(bb); +} + +int +ocbytessetlength(OCbytes* bb, unsigned int sz) +{ + if(bb == NULL) return ocbytesfail(); + if(sz > bb->alloc) {if(!ocbytessetalloc(bb,sz)) return ocbytesfail();} + bb->length = sz; + return TRUE; +} + +int +ocbytesfill(OCbytes* bb, char fill) +{ + unsigned int i; + if(bb == NULL) return ocbytesfail(); + for(i=0;ilength;i++) bb->content[i] = fill; + return TRUE; +} + +int +ocbytesget(OCbytes* bb, unsigned int index) +{ + if(bb == NULL) return -1; + if(index >= bb->length) return -1; + return bb->content[index]; +} + +int +ocbytesset(OCbytes* bb, unsigned int index, char elem) +{ + if(bb == NULL) return ocbytesfail(); + if(index >= bb->length) return ocbytesfail(); + bb->content[index] = elem; + return TRUE; +} + +int +ocbytesappend(OCbytes* bb, char elem) +{ + if(bb == NULL) return ocbytesfail(); + /* We need space for the char + null */ + while(bb->length+1 >= bb->alloc) { + if(!ocbytessetalloc(bb,0)) return ocbytesfail(); + } + bb->content[bb->length] = elem; + bb->length++; + bb->content[bb->length] = '\0'; + return TRUE; +} + +/* This assumes s is a null terminated string*/ +int +ocbytescat(OCbytes* bb, char* s) +{ + ocbytesappendn(bb,(void*)s,strlen(s)+1); /* include trailing null*/ + /* back up over the trailing null*/ + if(bb->length == 0) return ocbytesfail(); + bb->length--; + return 1; +} + +int +ocbytesappendn(OCbytes* bb, void* elem, unsigned int n) +{ + if(bb == NULL || elem == NULL) return ocbytesfail(); + if(n == 0) {n = strlen((char*)elem);} + while(!ocbytesavail(bb,n+1)) { + if(!ocbytessetalloc(bb,0)) return ocbytesfail(); + } + memcpy((void*)&bb->content[bb->length],(void*)elem,n); + bb->length += n; + bb->content[bb->length] = '\0'; + return TRUE; +} + +int +ocbytesprepend(OCbytes* bb, char elem) +{ + int i; /* do not make unsigned */ + if(bb == NULL) return ocbytesfail(); + if(bb->length >= bb->alloc) if(!ocbytessetalloc(bb,0)) return ocbytesfail(); + /* could we trust memcpy? instead */ + for(i=bb->alloc;i>=1;i--) {bb->content[i]=bb->content[i-1];} + bb->content[0] = elem; + bb->length++; + return TRUE; +} + +char* +ocbytesdup(OCbytes* bb) +{ + char* result = (char*)malloc(bb->length+1); + memcpy((void*)result,(const void*)bb->content,bb->length); + result[bb->length] = '\0'; /* just in case it is a string*/ + return result; +} + +char* +ocbytesextract(OCbytes* bb) +{ + char* result = bb->content; + bb->alloc = 0; + bb->length = 0; + bb->content = NULL; + return result; +} + +int +ocbytessetcontents(OCbytes* bb, char* contents, unsigned int alloc) +{ + if(bb == NULL) return ocbytesfail(); + ocbytesclear(bb); + if(!bb->nonextendible && bb->content != NULL) free(bb->content); + bb->content = contents; + bb->length = 0; + bb->alloc = alloc; + bb->nonextendible = 1; + return 1; +} diff --git a/extern/src_netcdf4/ocbytes.h b/extern/src_netcdf4/ocbytes.h new file mode 100644 index 0000000000000000000000000000000000000000..447e0e795ee66eeb1061d1447a7ad11c12877922 --- /dev/null +++ b/extern/src_netcdf4/ocbytes.h @@ -0,0 +1,54 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCBYTES_H +#define OCBYTES_H 1 + +typedef struct OCbytes { + int nonextendible; /* 1 => fail if an attempt is made to extend this buffer*/ + unsigned int alloc; + unsigned int length; + char* content; +} OCbytes; + +#if defined(_CPLUSPLUS_) || defined(__CPLUSPLUS__) || defined(__CPLUSPLUS) +#define EXTERNC extern "C" +#else +#define EXTERNC extern +#endif + +EXTERNC OCbytes* ocbytesnew(void); +EXTERNC void ocbytesfree(OCbytes*); +EXTERNC int ocbytessetalloc(OCbytes*,unsigned int); +EXTERNC int ocbytessetlength(OCbytes*,unsigned int); +EXTERNC int ocbytesfill(OCbytes*, char fill); + +/* Produce a duplicate of the contents*/ +EXTERNC char* ocbytesdup(OCbytes*); +/* Extract the contents and leave buffer empty */ +EXTERNC char* ocbytesextract(OCbytes*); + +/* Return the ith byte; -1 if no such index */ +EXTERNC int ocbytesget(OCbytes*,unsigned int); +/* Set the ith byte */ +EXTERNC int ocbytesset(OCbytes*,unsigned int,char); + +/* Append one byte */ +EXTERNC int ocbytesappend(OCbytes*,char); /* Add at Tail */ +/* Append n bytes */ +EXTERNC int ocbytesappendn(OCbytes*,void*,unsigned int); /* Add at Tail */ + +/* Concatenate a null-terminated string to the end of the buffer */ +EXTERNC int ocbytescat(OCbytes*,char*); +/* Set the contents of the buffer; mark the buffer as non-extendible */ +EXTERNC int ocbytessetcontents(OCbytes*, char*, unsigned int); + +/* Following are always "in-lined"*/ +#define ocbyteslength(bb) ((bb)?(bb)->length:0U) +#define ocbytesalloc(bb) ((bb)?(bb)->alloc:0U) +#define ocbytescontents(bb) ((bb && bb->content)?(bb)->content:(char*)"") +#define ocbytesextend(bb,len) ocbytessetalloc((bb),(len)+(bb->alloc)) +#define ocbytesclear(bb) ((bb)?(bb)->length=0:0U) +#define ocbytesavail(bb,n) ((bb)?((bb)->alloc - (bb)->length) >= (n):0U) + +#endif /*OCBYTES_H*/ diff --git a/extern/src_netcdf4/occlientparams.c b/extern/src_netcdf4/occlientparams.c new file mode 100644 index 0000000000000000000000000000000000000000..c9c9ca2542f31d17d7990a09b7c659edcbfa8abc --- /dev/null +++ b/extern/src_netcdf4/occlientparams.c @@ -0,0 +1,128 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include "ocinternal.h" +#include "ocdebug.h" + +#define LBRACKET '[' +#define RBRACKET ']' + + + +/* +Client parameters are assumed to be +one or more instances of bracketed pairs: +e.g "[...][...]...". +The bracket content in turn is assumed to be a +comma separated list of = pairs. +e.g. x=y,z=,a=b. +If the same parameter is specifed more than once, +then the first occurrence is used; this is so that +is possible to forcibly override user specified +parameters by prefixing. +IMPORTANT: client parameter string is assumed to +have blanks compress out. +*/ + +int +ocparamdecode(OCstate* state) +{ + int i; + i = ocuridecodeparams(state->uri); + return i?OC_NOERR:OC_EBADURL; +} + + +const char* +ocparamlookup(OCstate* state, const char* key) +{ + if(state == NULL || key == NULL || state->uri == NULL) return NULL; + return ocurilookup(state->uri,key); +} + +int +ocparamset(OCstate* state, const char* params) +{ + int i; + i = ocurisetparams(state->uri,params); + return i?OC_NOERR:OC_EBADURL; +} + +#ifdef OCIGNORE +void +ocparamfree(OClist* params) +{ + int i; + if(params == NULL) return; + for(i=0;i found and deleted; + 0 => param not found +*/ +int +ocparamdelete(OClist* params, const char* clientparam) +{ + int i,found = 0; + if(params == NULL || clientparam == NULL) return 0; + for(i=0;i not already defined + 0 => param already defined (no change) +*/ +int +ocparaminsert(OClist* params, const char* clientparam, const char* value) +{ + int i; + if(params == NULL || clientparam == NULL) return 0; + for(i=0;i replacement performed + 0 => insertion performed +*/ +int +ocparamreplace(OClist* params, const char* clientparam, const char* value) +{ + int i; + if(params == NULL || clientparam == NULL) return 0; + for(i=0;i> */ +} OCpath; + +/*! Specifies a ProjectionClause. */ +typedef struct OCprojectionclause { + char* target; /* "variable name" as mentioned in the projection */ + OClist* indexsets; /* oclist> */ + struct OCnode* node; /* node with name matching target, if any. */ + int gridconstraint; /* used only for testing purposes */ +} OCprojectionclause; + +/*! Selection is the node type for selection expression trees */ +typedef struct OCselectionclause { + int op; + char* value; + struct OCselectionclause* lhs; + OClist* rhs; +} OCselectionclause; + + +#endif /*CONSTRAINTS_H*/ diff --git a/extern/src_netcdf4/occontent.c b/extern/src_netcdf4/occontent.c new file mode 100644 index 0000000000000000000000000000000000000000..8da0892a2f055a9e283a1b2cb69641814e808efa --- /dev/null +++ b/extern/src_netcdf4/occontent.c @@ -0,0 +1,1174 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include "ocinternal.h" +#include "occontent.h" +#include "ocdebug.h" + +/* Mnemonic*/ +#define ISPACKED 1 + +/* Define the skipstate flags */ +#ifdef OCDEBUG +typedef enum Skipstate { +SKIPFIELDS = 1, /* skip instance without leading tag or arraycount */ +SKIPINSTANCE = 2, /*skip leading sequence tag or array counts */ +SKIPWHOLE = 4 /* skip complete object */ +} Skipstate; +#else +#define SKIPFIELDS 1 /* skip instance without leading tag or arraycount */ +#define SKIPINSTANCE 2 /*skip leading sequence tag or array counts */ +#define SKIPWHOLE 4 /* skip complete object */ +#endif + +/* Forward*/ +static OCmode modetransition(OCnode*,OCmode); +static int ocgetsequencetag(XXDR* xdrs); +static int ocskipcounts(XXDR* xdrs, OCnode*, off_t expected); + +static int ocarrayith(OCstate*, OCcontent*, OCcontent*, size_t); +static int ocsequenceith(OCstate*, OCcontent*, OCcontent*, size_t); +static int ocfieldith(OCstate*, OCcontent*, OCcontent*, size_t); + +static size_t ocarraycount(OCstate*, struct OCcontent*); +static size_t ocsequencecount(OCstate*, struct OCcontent*); +static size_t ocfieldcount(OCstate*, struct OCcontent*); +static size_t ocprimcount(OCstate*, struct OCcontent*); + +static OCcontent* occlearcontent(struct OCstate* state, OCcontent* content); + + +#ifdef OCDEBUG +static void +report(size_t memsize, char* memory) +{ +#ifdef OCIGNORE + switch(memsize) { + case 1: + oc_log(LOGNOTE,"reading xdr: %lu bytes = |%2x|",(unsigned long)memsize,memory[0]); + break; + case 4: + oc_log(LOGNOTE,"reading xdr: %lu bytes = |%4lu|",(unsigned long)memsize,*(unsigned int*)memory); + break; + case 8: + oc_log(LOGNOTE,"reading xdr: %lu bytes = |%8lu|",(unsigned long)memsize,*(unsigned long long*)memory); + break; + default: + oc_log(LOGNOTE,"reading xdr: %lu bytes",(unsigned long)memsize); + break; + } + oc_log(LOGNOTE,"reading xdr: %lu bytes",(unsigned long)memsize); +#endif +} + +static char* +modestring(OCmode mode) +{ + switch(mode) { + case OCFIELDMODE: return "FIELD"; + case OCSEQUENCEMODE: return "SEQUENCE"; + case OCARRAYMODE: return "ARRAY"; + case OCPRIMITIVEMODE: return "PRIMITIVE"; + case OCNULLMODE: return "NULL"; + case OCEMPTYMODE: return "EMPTY"; + } + return "?"; +} + +void +octrace1(char* proc, OCstate* state, OCcontent* content, int start, int count) +{ + unsigned long pos = xxdr_getpos(content->tree->data.xdrs); + fprintf(stderr,"trace: %s mode=%s node=%s (%s)", + proc,modestring(content->mode),content->node->fullname, + octypetostring(content->node->octype)); + if(content->packed) + fprintf(stderr," packed=%d",content->packed); + if(count >= 0) + fprintf(stderr," start=%lu count=%lu", + (unsigned long)start,(unsigned long)count); + else + fprintf(stderr," index=%lu",(unsigned long)start); + fprintf(stderr," xdrs.pos=%lu",pos); + fprintf(stderr,"\n"); + if(content->cache.valid) { + fprintf(stderr,"\tcache{index=%lu maxindex=%lu offset=%lu}\n", + (unsigned long)content->cache.index, + (unsigned long)content->cache.maxindex, + (unsigned long)content->cache.offset); + } + fflush(stderr); +} + +void +octrace(char* proc, OCstate* state, OCcontent* content, int index) +{ + octrace1(proc,state,content,index,-1); +} + + +#else +#define octrace(proc,state,content,index) +#define octrace1(proc,state,content,start,count) +#define report(memsize,memory) +#endif /*OCDEBUG*/ + +OCmode +ocgetmode(OCcontent* content) +{ + return (content == NULL ? OCNULLMODE : content->mode); +} + +OCcontent* +ocnewcontent(OCstate* state) +{ + OCcontent* content; + if(state == NULL) return NULL; + content = state->contentlist; + /* Search for an unused content node*/ + while(content != NULL && content->mode != OCEMPTYMODE) { + content = content->next; + } + if(content == NULL) { + content = (OCcontent*)ocmalloc(sizeof(OCcontent)); + MEMCHECK(content,(OCcontent*)NULL); + content->magic = OCMAGIC; + content->next = state->contentlist; + state->contentlist = content; + } + return occlearcontent(state,content); +} + +void +ocfreecontent(OCstate* state, OCcontent* content) +{ + if(content != NULL) {content->mode = OCEMPTYMODE;} +} + +static OCcontent* +occlearcontent(struct OCstate* state, OCcontent* content) +{ + /* save fields that should not be cleared */ + unsigned int magic = content->magic; + OCcontent* next = content->next; + memset((void*)content,sizeof(OCcontent),0); + /* set/restore non-null fields */ + content->magic = magic; + content->next = next; + content->state = state; + content->mode = OCNULLMODE; + return content; +} + +static OCcontent* +ocsetcontent(OCcontent* childcontent, OCcontent* parent, OCnode* node, int packed) +{ + childcontent->state = parent->state; + childcontent->cache.valid = 0; + childcontent->node = node; + childcontent->tree = node->root->tree; + childcontent->mode = modetransition(node,parent->mode); + childcontent->packed = packed; + return childcontent; +} + +#ifdef OCIGNORE +static OCcontent* +occlonecontent(OCstate* state, OCcontent* content) +{ + OCcontent* clone = ocnewcontent(state); + clone->mode = content->mode; + clone->node = content->node; + clone->cache = content->indexcache; + return clone; +} +#endif + +OCerror +ocdataith(OCstate* state, OCcontent* parent, size_t index, OCcontent* child) +{ + OCerror ocerr = OC_NOERR; + switch (parent->mode) { + case OCARRAYMODE: + ocerr = ocarrayith(state,parent,child,index); + break; + case OCSEQUENCEMODE: + ocerr = ocsequenceith(state,parent,child,index); + break; + case OCFIELDMODE: + ocerr = ocfieldith(state,parent,child,index); + break; + default: return OC_EINVAL; + } + if(ocerr == OC_EDATADDS) + ocdataddsmsg(state,parent->tree); + return ocerr; +} + +OCerror +ocdatacount(OCstate* state, OCcontent* current, size_t* sizep) +{ + OCerror ocerr = OC_NOERR; + size_t count = 0; + switch(current->mode) { + case OCARRAYMODE: + count = ocarraycount(state,current); + break; + case OCSEQUENCEMODE: + count = ocsequencecount(state,current); + break; + case OCFIELDMODE: + count = ocfieldcount(state,current); + break; + case OCPRIMITIVEMODE: + count = ocprimcount(state,current); + break; + default: + return OC_EINVAL; + } + current->cache.maxindex = ocmax(count,current->cache.maxindex); + if(sizep) *sizep = count; + return ocerr; +} + +OCerror +ocrootdata(OCstate* state, OCnode* root, OCcontent* content) +{ + OCtree* tree; + if(state == NULL || root == NULL || content == NULL) + return OCTHROW(OC_EINVAL); + if(root->tree == NULL) return OCTHROW(OC_EINVAL); + tree = root->tree; + if(tree->dxdclass != OCDATADDS) return OCTHROW(OC_ENODATA); + if(tree->nodes == NULL) return OCTHROW(OC_EINVAL); + if(tree->data.xdrs == NULL) + return OCTHROW(OC_EXDR); + + occlearcontent(state,content); + content->mode = OCFIELDMODE; + content->node = root; + content->tree = tree; + + content->cache.index = 0; + content->cache.maxindex = oclistlength(content->node->subnodes); + content->cache.offset = 0; + content->cache.valid = 1; + + return OCTHROW(OC_NOERR); +} + +/* Remember: we are operating wrt the datadds count, not the dds count */ +static OCerror +ocarrayith(OCstate* state, OCcontent* content, OCcontent* elemcontent, size_t index) +{ + unsigned int i; + int stat = OC_NOERR; + XXDR* xdrs; + int packed, scalar; + OCtype etype,octype; + OCnode* node; + int startindex = 0; + + octrace("ocarrayith", state, content, index); + + if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL); + if(content->mode != OCARRAYMODE) return OCTHROW(OC_EINVAL); + + etype = content->node->etype; + octype = content->node->octype; + node = content->node; + scalar = (node->array.rank == 0 ? 1 : 0); + packed = (!scalar && octype == OC_Primitive && + (etype == OC_Byte || etype == OC_UByte || etype == OC_Char)); + + xdrs = content->tree->data.xdrs; + if(xdrs == NULL) return OCTHROW(OC_EXDR); + + if(!content->cache.valid) { + content->cache.index = 0; /* because we will have to walk to index'th data */ + content->cache.maxindex = totaldimsize(node); + content->cache.valid = 1; + /* skip past the initial counts, if any */ + if(!scalar) { + if(!ocskipcounts(xdrs,node,node->skip.count)) return OCTHROW(OC_EDATADDS); + } + /* checkpoint xdr position */ + content->cache.offset = xxdr_getpos(xdrs); + } + + /* move to the checkpoint position */ + startindex = content->cache.index; + if(!xxdr_setpos(xdrs,content->cache.offset)) return xdrerror(); + + /* skip to the index'th item */ + if(packed) { + content->cache.index = 0; /* keep at beginning */ + } else { + for(i=startindex;icache.index = index; /* now we are at the index'th item */ + } + + /* update cache */ + content->cache.index = index; + content->cache.offset = xxdr_getpos(xdrs); + + /* set up the content for the current item in the array */ + ocsetcontent(elemcontent,content,node,packed); /*keep same node */ + if (index == content->cache.maxindex) { + /* mark eod */ + elemcontent->mode = OCNULLMODE; + } + + return OCTHROW(stat); +} + +static int +ocsequenceith(OCstate* state, OCcontent* content, OCcontent* structcontent, size_t index) +{ + unsigned int i; + int stat = OC_NOERR; + XXDR* xdrs; + OCtype octype,etype; + int packed,scalar; + OCnode* node = content->node; + int startindex, tag; + + octrace("ocsequenceith", state, content, index); + + if(state == NULL || content == NULL) goto einval; + if(content->mode != OCSEQUENCEMODE) goto einval; + if(node->octype != OC_Sequence) goto einval; + + octype = node->octype; + etype = node->etype; + scalar = (node->array.rank == 0 ? 1 : 0); + packed = (!scalar && octype == OC_Primitive && + (etype == OC_Byte || etype == OC_UByte || etype == OC_Char)); + + xdrs = content->tree->data.xdrs; + if(xdrs == NULL) goto exdr; + + if(!content->cache.valid) { + content->cache.valid = 1; + content->cache.index = 0; + content->cache.maxindex = 0; + content->cache.offset = xxdr_getpos(xdrs); + } + + /* move to checkpoint position*/ + startindex = content->cache.index; + if(!xxdr_setpos(xdrs,content->cache.offset)) goto exdr; + + /* Walk past the first (index-1) records */ + for(tag=StartOfSequence,i=startindex;icache.index = index; + content->cache.maxindex = ocmax(index,content->cache.index); + + /* this is a bit (too) tricky */ + /* move to point to fields */ + tag = ocgetsequencetag(xdrs); + if(tag == EndOfSequence) { + /* point past end of sequence */ + content->cache.offset = xxdr_getpos(xdrs); + } else {/*tag == StartOfSequence*/ + /* point to (next) start of sequence */ + content->cache.offset = xxdr_getpos(xdrs) - XDRUNIT; + } + /* at this point, xdrs should point unconditionally + past the index'th tag */ + + /* Set state of new content: keep same node */ + ocsetcontent(structcontent,content,node,packed); + if(tag == EndOfSequence) { + /* mark eod */ + structcontent->mode = OCNULLMODE; + } +done: + return OCTHROW(stat); +einval: + stat = OC_EINVAL; + goto done; +exdr: + stat = OC_EXDR; + goto done; +einvalcoords: + stat = OC_EINVALCOORDS; + goto done; +} + +/* +The ocfieldcontent procedure has to deal with the fact +that the dap constraints may have removed some fields +from the datadds and hence some fields may have no +representation in the xdr data (or compiled data). +Assume that xdr points to start of 0th field. +*/ +static int +ocfieldith(OCstate* state, OCcontent* content, OCcontent* fieldcontent, size_t index) +{ + unsigned int i; + int stat = OC_NOERR; + XXDR* xdrs; + OCtype octype,etype; + int packed; + int isscalar; + OCnode* node; + int startindex; + + octrace("ocfieldith", state, content, index); + + if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL); + if(content->mode != OCFIELDMODE) return OCTHROW(OC_EINVAL); + + node = content->node; + octype = node->octype; + etype = node->etype; + isscalar = (node->array.rank == 0 ? 1 : 0); + packed = (!isscalar && octype == OC_Primitive + && (etype == OC_Byte || etype == OC_UByte || etype == OC_Char)); + + xdrs = content->tree->data.xdrs; + if(xdrs == NULL) return OCTHROW(OC_EXDR); + + if(!content->cache.valid) { + content->cache.index = 0; + content->cache.maxindex = oclistlength(node->subnodes); + content->cache.valid = 1; + /* checkpoint xdr position */ + content->cache.offset = xxdr_getpos(xdrs); + } + + /* move to the checkpoint position */ + startindex = content->cache.index; + if(!xxdr_setpos(xdrs,content->cache.offset)) return xdrerror(); + + switch (octype) { + case OC_Sequence: /* assume xdrs points past sequence tag */ + case OC_Grid: /* Note that the Grid array is field 0 and the maps are 1..nsubnodes*/ + case OC_Dataset: + case OC_Structure: + /* walk to (i-1)'th field */ + for(i=startindex;isubnodes,i); + stat = ocskipinstance(ithfield,xdrs,SKIPWHOLE,NULL); + if(stat != OC_NOERR) return OCTHROW(stat); + } + break; + + default: return OCTHROW(OC_EINVAL); + } + + /* update cache */ + content->cache.index = index; + content->cache.offset = xxdr_getpos(xdrs); + /* Set state of new content: node changes to field node */ + ocsetcontent(fieldcontent,content, + (OCnode*)oclistget(node->subnodes,index), + packed); + if(index >= content->cache.maxindex) { + /* mark eod */ + fieldcontent->mode = OCNULLMODE; + } + + return OCTHROW(stat); +} + +/* +In order to actually extract data, +one must move to the specific primitive typed +field containing the data of interest by using +ocfieldcontent(). +Then, oc_getcontent() is invoked to extract +some subsequence of items from the field. +Note that oc_getcontent() will also work for scalars, +but the start must be zero and the count must be one. +*/ + +int +ocgetcontent(OCstate* state, OCcontent* content, void* memory, size_t memsize, + size_t start, size_t count) +{ + int stat = OC_NOERR; + XXDR* xdrs; + OCtype etype, octype; + int isscalar, packed; + size_t elemsize, totalsize; + OCnode* node = content->node; + + octrace1("ocgetcontent", state, content, start, count); + + if(state == NULL || content == NULL || memory == NULL) + {OCTHROWCHK(stat=OC_EINVAL); goto done;} + if(content->mode != OCPRIMITIVEMODE || node->octype != OC_Primitive) + {OCTHROWCHK(stat=OC_EINVAL); goto done;} + + octype = node->octype; + etype = node->etype; + + isscalar = (node->array.rank == 0); + packed = (!isscalar && octype == OC_Primitive + && (etype == OC_Byte || etype == OC_UByte || etype == OC_Char)); + + if(isscalar && (start != 0 || count != 1)) + {OCTHROWCHK(stat=OC_EINVALCOORDS); goto done;} + + /* validate memory space*/ + elemsize = octypesize(etype); + totalsize = elemsize*count; + if(memsize < totalsize) return OCTHROW(OC_EINVAL); + + xdrs = content->tree->data.xdrs; + if(xdrs == NULL) return OCTHROW(OC_EXDR); + + /* Need to setup the cache */ + if(!content->cache.valid) { + content->cache.valid = 1; + content->cache.index = 0; + content->cache.maxindex = totaldimsize(content->node); + if(!ocskipcounts(xdrs,content->node,content->cache.maxindex)) + return OCTHROW(OC_EXDR); + content->cache.offset = xxdr_getpos(xdrs); + } + + if(content->cache.valid && content->cache.maxindex < (start+count)) + return OCTHROW(OC_ENODATA); + + /* utilize the cache */ + if(!xxdr_setpos(xdrs,content->cache.offset)) return OCTHROW(OC_EXDR); + + /* Extract the data */ + stat = ocxdrread(content,xdrs,(char*)memory,memsize,start,count); + +#ifdef OCDEBUG + report(memsize,memory+start); +#endif + + /* Update the cache */ + if(!packed) { + content->cache.index = (start+count); + content->cache.offset = xxdr_getpos(xdrs); + } + +done: + return OCTHROW(stat); +} + +static size_t +ocfieldcount(OCstate* state, OCcontent* content) +{ + OCnode* node = content->node; + size_t count; + OCASSERT((node != NULL)); + count = oclistlength(node->subnodes); + return count; +} + +static size_t +ocarraycount(OCstate* state, OCcontent* content) +{ + unsigned int count; + OCnode* node = content->node; + + OCASSERT((node != NULL)); + OCASSERT((content->mode == OCARRAYMODE)); + + count = totaldimsize(node); + +#ifdef VERIFY + if(node->array.rank > 0) { + off_t checkpoint; + XXDR* xdrs; + unsigned int xdrcount; + /* verify against xdr */ + xdrs = content->tree->data.xdrs; + OCASSERT((xdrs != NULL)); + /* checkpoint current location */ + checkpoint = xxdr_getpos(xdrs); + /* extract the count*/ + if(!xxdr_uint(xdrs,&xdrcount)) return 0; + if(xdrcount != count) return 0; + /* return to checkpoint position*/ + if(!xxdr_setpos(xdrs,checkpoint)) return 0; + } +#endif /*VERIFY*/ + return (size_t)count; +} + +/* Counting records actually requires walking the xdr packet + so it is not necessarily cheap*/ +static size_t +ocsequencecount(OCstate* state, OCcontent* content) +{ + size_t count; + OCnode* node = content->node; + XXDR* xdrs; + off_t checkpoint; + + OCASSERT((node != NULL)); + OCASSERT((node->octype == OC_Sequence)); + OCASSERT((content->mode == OCSEQUENCEMODE)); + + xdrs = content->tree->data.xdrs; + OCASSERT((xdrs != NULL)); + + /* checkpoint location */ + checkpoint = xxdr_getpos(xdrs); + + for(count=0;;count++) { + int tag; + OCerror stat = ocskipinstance(node,xdrs,SKIPINSTANCE,&tag); + if(stat != OC_NOERR) {count = 0; break;} + if(tag == EndOfSequence) { + break; /* done with the count*/ + } else if(tag != StartOfSequence) { + oc_log(LOGERR,"missing/invalid begin/end record marker\n"); + return 0; + } + } + + /* move back to checkpoint position*/ + if(!xxdr_setpos(xdrs,checkpoint)) return 0; + + return count; +} + +static size_t +ocprimcount(OCstate* state, OCcontent* content) +{ + unsigned int count; + OCnode* node = content->node; + + OCASSERT((node != NULL)); + OCASSERT((content->mode == OCPRIMITIVEMODE)); + + count = totaldimsize(node); + +#ifdef VERIFY + if(node->array.rank > 0) { + off_t checkpoint; + XXDR* xdrs; + unsigned int xdrcount; + /* verify against xdr */ + xdrs = content->tree->data.xdrs; + OCASSERT((xdrs != NULL)); + /* checkpoint current location */ + checkpoint = xxdr_getpos(xdrs); + /* extract the count*/ + if(!xxdr_uint(xdrs,&xdrcount)) return 0; + if(xdrcount != count) return 0; + /* return to checkpoint position*/ + if(!xxdr_setpos(xdrs,checkpoint)) return 0; + } +#endif /*VERIFY*/ + return (size_t)count; +} + +static OCmode +modetransition(OCnode* node, OCmode srcmode) +{ + OCmode newmode = OCNULLMODE; + switch (srcmode) { + case OCARRAYMODE: + switch (node->octype) { + case OC_Sequence: + newmode = OCSEQUENCEMODE; + break; + case OC_Grid: + case OC_Structure: + newmode = OCFIELDMODE; + break; + default: + break; + } + break; + + case OCSEQUENCEMODE: + switch (node->octype) { + default: + newmode = OCFIELDMODE; + break; + } + break; + + case OCFIELDMODE: + switch (node->octype) { + case OC_Sequence: + case OC_Grid: + case OC_Structure: + newmode = OCARRAYMODE; + break; + case OC_Primitive: + newmode = OCPRIMITIVEMODE; + break; + default: + break; + } + break; + + case OCPRIMITIVEMODE: + case OCNULLMODE: + case OCEMPTYMODE: + default: + newmode = OCNULLMODE; + break; + } + if(newmode == OCNULLMODE) + OCPANIC1("No defined mode transition: %d",(int)srcmode); + return newmode; +} + +/* get the presumed current sequence tag */ +static int +ocgetsequencetag(XXDR* xdrs) +{ + char tag[XDRUNIT]; + if(!xxdr_getbytes(xdrs,tag,sizeof(tag))) return 0; + return tag[0]; +} + +static int +ocskipcounts(XXDR* xdrs, OCnode* node, off_t expected) +{ + if(node->array.rank == 0) return 1; /* simple scalar */ +#ifdef VERIFY + unsigned int xdrcount0,xdrcount1; + /* Collect the dimension count from the xdr data packet*/ + if(!xxdr_uint(xdrs,&xdrcount0)) OCGOTO(shortxdr); + if(expected >= 0 && xdrcount0 != expected) return 0; + /* pull out redundant second count*/ + /* (note that String/URL do not have redundant count)*/ + if(node->octype == OC_Primitive + && node->etype != OC_String && node->etype != OC_URL) { + if(!xxdr_uint(xdrs,&xdrcount1)) return 0; + if(xdrcount0 != xdrcount1) return 0; + } +#else + /* skip the counts */ + expected = expected; /*shut up compiler*/ + if(node->octype == OC_Primitive + && node->etype != OC_String && node->etype != OC_URL) { + if(!xxdr_skip(xdrs,2*XDRUNIT)) return 0; + } else { + if(!xxdr_skip(xdrs,XDRUNIT)) return 0; + } +#endif + return 1; +} + +/**************************************************/ +/* Moved ocdata.c here */ +/**************************************************/ + +const char StartOfSequence = '\x5A'; +const char EndOfSequence = '\xA5'; + +static int ocerrorstring(XXDR* xdrs); + +#define LOCALMEMMAX 1024 + +/* +Skip arbitrary object based on its octype +and a state + +Cases: + +octype Skip State actions +------------------------------------------- +Structure + |Grid + |DataSet SKIPINSTANCE Skip single instance + |SKIPFIELDS + SKIPWHOLE Skip array of instances + including leading counts + +Sequence SKIPFIELDS Skip single record + (assume leading tag already skipped) + SKIPINSTANCE Skip single record + (including leading tag) + + SKIPWHOLE Skip all records + including leading tags + and trailing end marker + +Primitive Skip whole primitive array + including leading counts + +Notes: +1. unlisted combinations are not legal/possible. +2. assume that xxdr_getpos is properly positioned. +3. If octype is OC_Sequence, tagp will be set with the + last tag encountered. +*/ + +OCerror +ocskipinstance(OCnode* node, XXDR* xdrs, int state, int* tagp) +{ + int i,tag; + int stat = OC_NOERR; + +/* Support switch on combination of octype X state to simply code */ +#define CASE(octype,state) ((octype)<<3 | state) + + switch (CASE(node->octype,state)) { + + case CASE(OC_Dataset,SKIPINSTANCE): + case CASE(OC_Grid,SKIPINSTANCE): + case CASE(OC_Structure,SKIPINSTANCE): + + case CASE(OC_Dataset,SKIPFIELDS): + case CASE(OC_Grid,SKIPFIELDS): + case CASE(OC_Structure,SKIPFIELDS): + case CASE(OC_Sequence,SKIPFIELDS): /* NOTE this special case */ + if(node->skip.instancesize != OCINDETERMINATE) { + if(!xxdr_skip(xdrs,node->skip.instancesize)) OCGOTO(shortxdr); + } else {/* skip field by field */ + for(i=0;isubnodes);i++) { + OCnode* field = (OCnode*)oclistget(node->subnodes,i); + stat = ocskipinstance(field, xdrs, SKIPWHOLE,NULL); + if(stat != OC_NOERR) {OCTHROWCHK(stat); goto done;} + } + } + break; + + case CASE(OC_Dataset,SKIPWHOLE): + case CASE(OC_Grid,SKIPWHOLE): + case CASE(OC_Structure,SKIPWHOLE): + OCASSERT(node->skip.count != OCINDETERMINATE); + if(node->skip.totalsize != OCINDETERMINATE) { + if(!xxdr_skip(xdrs,node->skip.totalsize)) goto badxdr; + } else {/* skip each instance */ + if(node->array.rank > 0) { + if(!ocskipcounts(xdrs,node,node->skip.count)) goto badxdr; + for(i=0;iskip.count;i++) { + stat = ocskipinstance(node, xdrs, SKIPFIELDS,NULL); + if(stat != OC_NOERR) {OCTHROWCHK(stat); goto done;} + } + } else { /* scalar */ + stat = ocskipinstance(node, xdrs, SKIPINSTANCE,NULL); + if(stat != OC_NOERR) {OCTHROWCHK(stat); goto done;} + } + } + break; + + case CASE(OC_Sequence,SKIPINSTANCE): /* Skip record including tag */ + tag = ocgetsequencetag(xdrs); /* always read the tag */ + if(tagp) *tagp = tag; + if(tag == StartOfSequence) { /* skip record fields */ + stat = ocskipinstance(node, xdrs, SKIPFIELDS,NULL); + if(stat != OC_NOERR) {OCTHROWCHK(stat); break;} + } /* let caller handle */ + break; + + case CASE(OC_Sequence,SKIPWHOLE): /* Skip multiple records including tags */ + for(i=0;;i++) { + stat = ocskipinstance(node, xdrs, SKIPINSTANCE, &tag); + if(stat != OC_NOERR) {OCTHROWCHK(stat); break;} + if(tag == EndOfSequence) break; /* done */ + if(tag != StartOfSequence) goto badxdr; /* malformed */ + } + break; + + case CASE(OC_Primitive,SKIPWHOLE): + case CASE(OC_Primitive,SKIPINSTANCE): + case CASE(OC_Primitive,SKIPFIELDS): + OCASSERT(node->skip.count != OCINDETERMINATE); + if(node->skip.totalsize != OCINDETERMINATE) { + /* skip directly past it */ + if(!xxdr_skip(xdrs,node->skip.totalsize)) goto badxdr; + } else {/* Walk instance by instance */ + if(state == SKIPWHOLE) { + /* read the counts */ + if(!ocskipcounts(xdrs,node,node->skip.count)) + goto badxdr; + } + OCASSERT(node->etype == OC_String || node->etype == OC_URL); + /* get the count */ + for(i=0;iskip.count;i++) { + /* read and skip the string */ + unsigned int len; + /* read string size */ + if(!xxdr_uint(xdrs,&len)) OCGOTO(shortxdr); + /* round up to next XDRUNIT and skip string contents */ + len = RNDUP(len); + if(!xxdr_skip(xdrs,(size_t)len)) OCGOTO(shortxdr); + } + } + break; + + default: + OCPANIC2("ocskipinstance: encountered unexpected node type or state: %d,%d", + node->octype,state); + break; + } +done: + return OCTHROW(stat); +shortxdr: + oc_log(LOGERR,"short xdr packet"); + stat = OC_EXDR; + goto done; +badxdr: + oc_log(LOGERR,"malformed xdr packet"); + stat = OC_EXDR; + goto done; +} + +/* +Extract data from the xdr packet into a chunk of memory. +Normally, it is assumed that we are (at least virtually) +"at" a single instance in the xdr packet; which we read. +Virtually because for packed data, we need to point to +the beginning of the packed data and use the index to indicate +which packed element to get. Assume that in any case, +any leading counts have been passed. +*/ +OCerror +ocxdrread(OCcontent* content, XXDR* xdrs, char* memory, size_t memsize, + ocindex_t start, ocindex_t count) +{ + int stat = OC_NOERR; + unsigned int i; + size_t elemsize; + size_t readsize; + size_t skipsize; + char localmem[LOCALMEMMAX]; + char* srcmem; + unsigned int* p; + int packed; + int scalar; + OCtype octype,etype; + ocindex_t localstart = start; /* will change if node is cacheing */ + OCnode* node; + + node = content->node; + octype = node->octype; + etype = node->etype; + + elemsize = octypesize(etype); + + scalar = (node->array.rank == 0 ? 1 : 0); + + /* check if the data is packed*/ + packed = (octype == OC_Primitive && !scalar + && (etype == OC_Byte || etype == OC_UByte || etype == OC_Char)); + + /* validate memory space*/ + if(memsize < elemsize*count) return OCTHROW(OC_EINVAL); + +#ifdef OCIGNORE + if(!scalar && (!node->cache.cacheable || !node->cache.valid)) { + unsigned int xdrcount0,xdrcount1; + /* assume xdr position is correct */ + /* Read leading double count if ! scalar*/ + if(!xxdr_uint(xdrs,&xdrcount0)) OCGOTO(shortxdr); + if(!xxdr_uint(xdrs,&xdrcount1)) OCGOTO(shortxdr); + if(xdrcount0 != xdrcount1) return OCTHROW(OC_EXDR); + if(xdrcount0 < start+count) OCGOTO(shortxdr); + } +#endif + + /* Handle packed data specially*/ + if(packed) { + readsize = count*1; /* |OC_(Char,Byte,UByte)| == 1 */ + skipsize = start*1; /* |OC_(Char,Byte,UByte)| == 1 */ + /* skip to start of what we want to read */ + if(!xxdr_skip(xdrs,skipsize)) OCGOTO(shortxdr); + /* read data, keeping xdrs on XDRUNIT boundary */ + if(!xxdr_opaque(xdrs,memory,readsize)) + OCGOTO(shortxdr); + return OCTHROW(OC_NOERR); + } + + /* Not packed */ + +#ifdef OCIGNORE + /* If this (primitive) object is cacheable and is valid cache, + then modify start and set the xdr position accordingly + */ + if(node->cache.cacheable && node->cache.valid) { + if(node->cache.index <= start) { + localstart -= node->cache.index; + if(!xxdr_setpos(xdrs,node->cache.offset)) return xdrerror(); + } + } +#endif + + /* Compute how much to skip based on the content's cache index */ + localstart = start - content->cache.index; + if(localstart < 0) localstart = 0; + + /* extract count items; use xxdr_getbytes to speed up*/ + srcmem = memory; + switch (etype) { + case OC_Float64: case OC_Int64: case OC_UInt64: + readsize = count*2*XDRUNIT; + skipsize = localstart*2*XDRUNIT; + /* skip to start of what we want to read */ + if(!xxdr_skip(xdrs,skipsize)) OCGOTO(shortxdr); + if(!xxdr_opaque(xdrs,(char*)srcmem,readsize)) OCGOTO(shortxdr); + if(etype == OC_Float64) { + double* dp; + for(dp=(double*)srcmem,i=0;i sizeof(localmem)) { + srcmem = (char*)ocmalloc(count*sizeof(unsigned int)); + if(srcmem == NULL) {stat = OCTHROW(OC_ENOMEM); goto done;} + } + /* fall thru */ + case OC_Int32: case OC_UInt32: + case OC_Float32: + readsize = (count)*XDRUNIT; + skipsize = (localstart)*XDRUNIT; + if(!xxdr_skip(xdrs,skipsize)) OCGOTO(shortxdr); + if(!xxdr_opaque(xdrs,(char*)srcmem,readsize)) OCGOTO(shortxdr); + if(!xxdr_network_order) { + for(p=(unsigned int*)srcmem,i=0;icache.index = start + count; /* should be our current index */ + content->cache.offset = xxdr_getpos(xdrs); /* should be our current position */ + +done: + return OCTHROW(stat); + +shortxdr: + content->cache.valid = 0; /* no longer valid */ + if(!ocerrorstring(xdrs)) + oc_log(LOGERR,"DAP DATADDS packet is apparently too short"); + stat = OCTHROW(OC_EDATADDS); + goto done; +} + +int +occountrecords(OCnode* node, XXDR* xdrs, size_t* nrecordsp) +{ + int stat = OC_NOERR; + size_t nrecords = 0; + + if(node->octype != OC_Sequence) return OCTHROW(OC_EINVAL); + /* checkpoint the xdr position*/ + for(nrecords=0;;nrecords++) { + int tag = 0; + stat = ocskipinstance(node,xdrs,SKIPINSTANCE,&tag); + if(stat != OC_NOERR) break; + if(tag == EndOfSequence) break; + if(tag != StartOfSequence) { + oc_log(LOGERR,"missing/invalid begin/end record marker\n"); + stat = OC_EINVALCOORDS; + break; + } + if(stat != OC_NOERR) break; + } + if(nrecordsp != NULL) *nrecordsp = nrecords; + return OCTHROW(stat); +} + + + +#define tag "Error {\n" + +static int +ocerrorstring(XXDR* xdrs) +{ + /* Check to see if the xdrs contains "Error {\n'; assume it is at the beginning of data */ + off_t avail = xxdr_getavail(xdrs); + char* data = (char*)malloc(avail); + if(!xxdr_setpos(xdrs,0)) return 0; + if(!xxdr_opaque(xdrs,data,avail)) return 0; + /* check for error tag at front */ + if(ocstrncmp(data,tag,sizeof(tag))==0) { + char* p; + if((p=strchr(data,'}')) != NULL) *(++p)='\0'; + oc_log(LOGERR,"Server error: %s",data); + /* Since important, report to stderr as well */ + fprintf(stderr,"Server error: %s",data); + return 1; + } + return 0; +} diff --git a/extern/src_netcdf4/occontent.h b/extern/src_netcdf4/occontent.h new file mode 100644 index 0000000000000000000000000000000000000000..0c6f9dc0c8ab9b8d0e837c88c64d33ca457a73a3 --- /dev/null +++ b/extern/src_netcdf4/occontent.h @@ -0,0 +1,35 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCCONTENT_H +#define OCCONTENT_H + +/*! Specifies the OCcontent*/ +typedef struct OCcontent { + unsigned int magic; + OCmode mode; + struct OCstate* state; + struct OCnode* node; + struct OCtree* tree; + int packed; /* track OC_Char and OC_Byte specially*/ + struct OCCACHE { + int valid; + ocindex_t index; /* index corresponding to offset */ + ocindex_t maxindex; /* max allowable index, if known0 => max unknown */ + ocoffset_t offset; /* location of this content in the xdr data */ + } cache; /* track last xdr position and index of this content */ + struct OCcontent* next; +} OCcontent; + +extern OCcontent* ocnewcontent(OCstate* state); +extern void ocfreecontent(OCstate* state, OCcontent* content); +extern OCmode ocgetmode(OCcontent* content); + +extern int ocdataith(struct OCstate*, OCcontent*, size_t, OCcontent*); +extern int ocdatacount(struct OCstate*, OCcontent*, size_t*); + +extern int ocrootdata(struct OCstate*, struct OCnode*, struct OCcontent*); +extern int ocgetcontent(struct OCstate*, struct OCcontent*, void* memory, + size_t memsize, size_t start, size_t count); + +#endif /*OCCONTENT_H*/ diff --git a/extern/src_netcdf4/occurlfunctions.c b/extern/src_netcdf4/occurlfunctions.c new file mode 100644 index 0000000000000000000000000000000000000000..bfc3b82e0bb0b835abbe8183f92eacd860984c30 --- /dev/null +++ b/extern/src_netcdf4/occurlfunctions.c @@ -0,0 +1,206 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include "ocinternal.h" +#include "ocdebug.h" +#include "ocdata.h" +#include "occontent.h" + +#include "ocrc.h" + +/* Condition on libcurl version */ +/* Set up an alias as needed */ +#ifndef HAVE_CURLOPT_KEYPASSWD +#define CURLOPT_KEYPASSWD CURLOPT_SSLKEYPASSWD +#endif + +static char* combinecredentials(const char* user, const char* pwd); + + +/* Set various general curl flags */ +int +ocset_curl_flags(OCstate* state) +{ + CURLcode cstat = CURLE_OK; + CURL* curl = state->curl; + struct OCcurlflags* flags = &state->curlflags; + +#ifdef CURLOPT_ENCODING + if (flags->compress) { + cstat = curl_easy_setopt(curl, CURLOPT_ENCODING,"deflate, gzip"); + if(cstat != CURLE_OK) goto done; + OCDBG(1,"CURLOPT_ENCODING=deflate, gzip"); + } +#endif + if (flags->cookiejar || flags->cookiefile) { + cstat = curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1); + if (cstat != CURLE_OK) goto done; + OCDBG(1,"CURLOPT_COOKIESESSION=1"); + } + if (flags->cookiejar) { + cstat = curl_easy_setopt(curl, CURLOPT_COOKIEJAR, flags->cookiejar); + if (cstat != CURLE_OK) goto done; + OCDBG1(1,"CURLOPT_COOKIEJAR=%s",flags->cookiejar); + } + if (flags->cookiefile) { + cstat = curl_easy_setopt(curl, CURLOPT_COOKIEFILE, flags->cookiefile); + if (cstat != CURLE_OK) goto done; + OCDBG1(1,"CURLOPT_COOKIEFILE=%s",flags->cookiefile); + } + if (flags->verbose) { + cstat = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + if (cstat != CURLE_OK) goto done; + OCDBG1(1,"CURLOPT_VERBOSE=%ld",1L); + } + + if (flags->timeout) { + cstat = curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)flags->timeout); + if (cstat != CURLE_OK) goto done; + OCDBG1(1,"CURLOPT_TIMEOUT=%ld",1L); + } + + /* Following are always set */ + cstat = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L); + cstat = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); + OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L); + + cstat = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->error.curlerrorbuf); + OCDBG1(1,"CURLOPT_ERRORBUFFER",0); + +done: + return cstat; +} + +int +ocset_proxy(OCstate* state) +{ + CURLcode cstat; + CURL* curl = state->curl; + struct OCproxy *proxy = &state->proxy; + struct OCcredentials *creds = &state->creds; + + cstat = curl_easy_setopt(curl, CURLOPT_PROXY, proxy->host); + if (cstat != CURLE_OK) return OC_ECURL; + OCDBG1(1,"CURLOPT_PROXY=%s",proxy->host); + + cstat = curl_easy_setopt(curl, CURLOPT_PROXYPORT, proxy->port); + if (cstat != CURLE_OK) return OC_ECURL; + OCDBG1(1,"CURLOPT_PROXYPORT=%d",proxy->port); + + if (creds->username) { + char *combined = combinecredentials(creds->username,creds->password); + if (!combined) return OC_ENOMEM; + cstat = curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, combined); + if (cstat != CURLE_OK) return OC_ECURL; + OCDBG1(1,"CURLOPT_PROXYUSERPWD=%s",combined); +#ifdef CURLOPT_PROXYAUTH + cstat = curl_easy_setopt(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); + if(cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_PROXYAUTH=%ld",(long)CURLAUTH_ANY); +#endif + free(combined); + } + return OC_NOERR; +} + +int +ocset_ssl(OCstate* state) +{ + CURLcode cstat = CURLE_OK; + CURL* curl = state->curl; + struct OCSSL* ssl = &state->ssl; + long verify = (ssl->validate?1L:0L); + cstat=curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, verify); + if (cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_SSL_VERIFYPEER=%ld",verify); + cstat=curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (verify?2L:0L)); + if (cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_SSL_VERIFYHOST=%ld",(verify?2L:0L)); +#ifdef OCIGNORE + if(verify) +#endif + { + if(ssl->certificate) { + cstat = curl_easy_setopt(curl, CURLOPT_SSLCERT, ssl->certificate); + if(cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_SSLCERT=%s",ssl->certificate); + } + if(ssl->key) { + cstat = curl_easy_setopt(curl, CURLOPT_SSLKEY, ssl->key); + if(cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_SSLKEY=%s",ssl->key); + } + if(ssl->keypasswd) { + /* libcurl prior to 7.16.4 used 'CURLOPT_SSLKEYPASSWD' */ + cstat = curl_easy_setopt(curl, CURLOPT_KEYPASSWD, ssl->keypasswd); + if(cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_SSLKEY=%s",ssl->key); + } + if(ssl->cainfo) { + cstat = curl_easy_setopt(curl, CURLOPT_CAINFO, ssl->cainfo); + if(cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_CAINFO=%s",ssl->cainfo); + } + if(ssl->capath) { + cstat = curl_easy_setopt(curl, CURLOPT_CAPATH, ssl->capath); + if(cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_CAPATH=%s",ssl->capath); + } + { + cstat = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, ssl->verifypeer); + if(cstat != CURLE_OK) goto fail; + OCDBG1(1,"CURLOPT_SSL_VERIFYPEER=%d",ssl->verifypeer); + } + } + return OC_NOERR; + +fail: + return OC_ECURL; +} + +/* This is called with arguments while the other functions in this file are + * used with global values read from the.dodsrc file. The reason is that + * we may have multiple password sources. + */ +int +ocset_user_password(OCstate* state) +{ + CURLcode cstat; + CURL* curl = state->curl; + char* combined = NULL; + const char* userC = state->creds.username; + const char* passwordC = state->creds.password; + + if(userC == NULL || passwordC == NULL) return OC_NOERR; + + combined = combinecredentials(userC,passwordC); + if (!combined) return OC_ENOMEM; + cstat = curl_easy_setopt(curl, CURLOPT_USERPWD, combined); + if (cstat != CURLE_OK) goto done; + OCDBG1(1,"CURLOPT_USERPWD=%s",combined); + cstat = curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long) CURLAUTH_ANY); + if (cstat != CURLE_OK) goto done; + OCDBG1(1,"CURLOPT_HTTPAUTH=%ld",(long)CURLAUTH_ANY); + +done: + if(combined != NULL) free(combined); + return (cstat == CURLE_OK?OC_NOERR:OC_ECURL); +} + + +static char* +combinecredentials(const char* user, const char* pwd) +{ + int userPassSize = strlen(user) + strlen(pwd) + 2; + char *userPassword = malloc(sizeof(char) * userPassSize); + if (!userPassword) { + oc_log(LOGERR,"Out of Memory\n"); + return NULL; + } + strcpy(userPassword, user); + strcat(userPassword, ":"); + strcat(userPassword, pwd); + return userPassword; +} diff --git a/extern/src_netcdf4/occurlfunctions.h b/extern/src_netcdf4/occurlfunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..17d28053fcfd4cab2a2a935c6655a326e2f3c4d3 --- /dev/null +++ b/extern/src_netcdf4/occurlfunctions.h @@ -0,0 +1,19 @@ +/* + * rc.h + * + * Created on: Mar 5, 2009 + * Author: rikki + */ + +#ifndef _CURLFUNCTION_H_ +#define _CURLFUNCTION_H_ + +extern int ocset_curl_flags(OCstate*); +extern int ocset_user_password(OCstate*); +extern int ocset_proxy(OCstate*); +extern int ocset_ssl(OCstate*); + +#endif /*_CURLFUNCTION_H_*/ + + + diff --git a/extern/src_netcdf4/ocdata.h b/extern/src_netcdf4/ocdata.h new file mode 100644 index 0000000000000000000000000000000000000000..5a3ca41dd3eac7f8bbcd22b29b07f77dca52a552 --- /dev/null +++ b/extern/src_netcdf4/ocdata.h @@ -0,0 +1,28 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCDATA_H +#define OCDATA_H + +typedef struct OCdimcounter { + int rank; + size_t index[OC_MAX_DIMS]; + size_t size[OC_MAX_DIMS]; +} OCdimcounter; + +extern const char StartOfSequence; +extern const char EndOfSequence; + +/*Forward */ +struct OCcontent; + +/* Skip arbitrary dimensioned instance; Handles dimensioning.*/ +extern int ocskip(OCnode* node, XXDR* xdrs); + +extern int occountrecords(OCnode* node, XXDR* xdrs, size_t* nrecordsp); + +extern int ocxdrread(struct OCcontent*, XXDR*, char* memory, size_t, ocindex_t index, ocindex_t count); + +extern int ocskipinstance(OCnode* node, XXDR* xdrs, int state, int* tagp); + +#endif /*OCDATA_H*/ diff --git a/extern/src_netcdf4/ocdatatypes.h b/extern/src_netcdf4/ocdatatypes.h new file mode 100644 index 0000000000000000000000000000000000000000..d34c508e44eba6b099bad6c0e35a3a984a84942f --- /dev/null +++ b/extern/src_netcdf4/ocdatatypes.h @@ -0,0 +1,61 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCDATATYPES_H +#define OCDATATYPES_H + +/* Define some useful info about the supported + primitive datatypes*/ + +#define DCHAR char +#define DBYTE signed char +#define DUBYTE unsigned char +#define DINT16 short +#define DUINT16 unsigned short +#define DINT32 int +#define DUINT32 unsigned int +#define DINT64 int +#define DUINT64 unsigned int +#define DFLOAT32 float +#define DFLOAT64 double + +#define OC_CHAR_MIN ((char)0x00) +#define OC_CHAR_MAX ((char)0xff) +#define OC_BYTE_MIN -128 +#define OC_BYTE_MAX 127 +#define OC_UBYTE_MIN 0 +#define OC_UBYTE_MAX 255U +#define OC_INT16_MIN -32768 +#define OC_INT16_MAX 32767 +#define OC_UINT16_MIN 0 +#define OC_UINT16_MAX 65535U +#define OC_INT32_MIN (-2147483647 - 1) +#define OC_INT32_MAX 2147483647 +#define OC_UINT32_MIN 0 +#define OC_UINT32_MAX 4294967295U +#define OC_INT64_MIN (-9223372036854775807LL-1) +#define OC_INT64_MAX (9223372036854775807LL) +#define OC_UINT64_MIN 0LL +#define OC_UINT64_MAX (18446744073709551615ULL) +#define OC_FLOAT32_MAX 3.402823466E+38F /* max decimal value of a "float" */ +#define OC_FLOAT32_MIN (-OC_FLOAT_MAX) +#define OC_FLOAT64_MAX 1.7976931348623157E+308 /* max decimal value of a double */ +#define OC_FLOAT64_MIN (-OC_FLOAT64_MAX) + +/* Similar to netcdf*/ +#define OC_FILL_CHAR ((char)0) +#define OC_FILL_BYTE ((signed char)-127) +#define OC_FILL_UBYTE (255) +#define OC_FILL_INT16 ((short)-32767) +#define OC_FILL_UINT16 (65535) +#define OC_FILL_INT32 (-2147483647L) +#define OC_FILL_UINT32 (4294967295U) +#define OC_FILL_INT64 ((long long)-9223372036854775806LL) +#define OC_FILL_UINT64 ((unsigned long long)18446744073709551614ULL) +#define OC_FILL_FLOAT32 (9.9692099683868690e+36f) /* near 15 * 2^119 */ +#define OC_FILL_FLOAT64 (9.9692099683868690e+36) +#define OC_FILL_STRING "" +#define OC_FILL_URL "" + + +#endif /*OCDATATYPES_H*/ diff --git a/extern/src_netcdf4/ocdebug.c b/extern/src_netcdf4/ocdebug.c new file mode 100644 index 0000000000000000000000000000000000000000..ef51f09c0c9e51a5dc5bca427a954839a4dc102a --- /dev/null +++ b/extern/src_netcdf4/ocdebug.c @@ -0,0 +1,67 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include +#include "ocinternal.h" +#include "ocdebug.h" + +int ocdebug; + +#ifdef OCCATCHERROR +/* Place breakpoint here to catch errors close to where they occur*/ +int +ocbreakpoint(int err) {return err;} + +int +octhrow(int err) +{ + if(err == 0) return err; + return ocbreakpoint(err); +} +#endif + +int +xdrerror(void) +{ + oc_log(LOGERR,"xdr failure"); + return OCTHROW(OC_EDATADDS); +} + + +void* +occalloc(size_t size, size_t nelems) +{ + return ocmalloc(size*nelems); +} + +void* +ocmalloc(size_t size) +{ + void* memory = calloc(size,1); /* use calloc to zero memory*/ + if(memory == NULL) oc_log(LOGERR,"ocmalloc: out of memory"); + return memory; +} + +void +ocfree(void* mem) +{ + if(mem != NULL) free(mem); +} + +int +ocpanic(const char* fmt, ...) +{ + va_list args; + if(fmt != NULL) { + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n" ); + va_end( args ); + } else { + fprintf(stderr, "panic" ); + } + fprintf(stderr, "\n" ); + fflush(stderr); + return 0; +} diff --git a/extern/src_netcdf4/ocdebug.h b/extern/src_netcdf4/ocdebug.h new file mode 100644 index 0000000000000000000000000000000000000000..1d2dff7e09fedacf033c260d3314ab5c8313bc36 --- /dev/null +++ b/extern/src_netcdf4/ocdebug.h @@ -0,0 +1,93 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCOCDBG_H +#define OCOCDBG_H + +#include + +#if 0 +#define OCDEBUG +#define DAPDEBUG 1 +#endif + +#ifdef OCDEBUG +#define OCVERBOSE +#endif + +/* OCCATCHERROR is used to detect errors as close + to their point of origin as possible. When + enabled, one can set a breakpoint in ocbreakpoint() + to catch the failure. Turing it on incurs a significant + performance penalty, so it is off by default.*/ + +#define OCCATCHERROR + +#define OCPANIC(msg) assert(ocpanic(msg)) +#define OCPANIC1(msg,arg) assert(ocpanic(msg,arg)) +#define OCPANIC2(msg,arg1,arg2) assert(ocpanic(msg,arg1,arg2)) + +/* Make it possible to catch assertion failures by breakpointing ocpanic*/ +#define OCASSERT(expr) if(!(expr)) {OCPANIC((#expr));} else {} + +/* Need some syntactic trickery to make these macros work*/ +#ifdef OCDEBUG +#define OCDBG(l,msg) {oc_log(LOGDBG,msg);} +#define OCDBG1(l,msg,arg) {oc_log(LOGDBG,msg,arg);} +#define OCDBG2(l,msg,arg1,arg2) {oc_log(LOGDBG,msg,arg1,arg2);} +#define OCDBGTEXT(l,text) {oc_logtext(LOGNOTE,text);} else {} +#define OCDBGCODE(l,code) {code;} + +#else +#define OCDBG(l,msg) +#define OCDBG1(l,msg,arg) +#define OCDBG2(l,msg,arg1,arg2) +#define OCDBGTEXT(l,text) +#define OCDBGCODE(l,code) +#endif + + +/* +OCPROGRESS attempts to provide some info +about how IO is getting along. +*/ +#undef OCPROGRESS + +extern int ocdebug; +extern int cedebug; + +/*extern char* dent2(int n);*/ +/*/extern char* dent(int n);*/ +extern int ocpanic(const char* fmt, ...); + +extern int xdrerror(void); + +/* +Provide wrapped versions of calloc and malloc. +The wrapped version panics if memory +is exhausted. It also guarantees that the +memory has been zero'd. +*/ + +extern void* occalloc(size_t size, size_t nelems); +extern void* ocmalloc(size_t size); +extern void ocfree(void*); + +#define MEMCHECK(var,throw) {if((var)==NULL) return (throw);} + +#ifdef OCCATCHERROR +/* Place breakpoint on ocbreakpoint to catch errors close to where they occur*/ +#define OCTHROW(e) octhrow(e) +#define OCTHROWCHK(e) (void)octhrow(e) +#define OCGOTO(label) {ocbreakpoint(-1); goto label;} +extern int ocbreakpoint(int err); +extern int octhrow(int err); +#else +#define OCTHROW(e) (e) +#define OCTHROWCHK(e) +#define OCGOTO(label) goto label +#endif + + +#endif /*OCOCDBG_H*/ + diff --git a/extern/src_netcdf4/ocdrno.c b/extern/src_netcdf4/ocdrno.c new file mode 100644 index 0000000000000000000000000000000000000000..05eea02da5cce31fa858bc6f7bdf4d4eebdfcaec --- /dev/null +++ b/extern/src_netcdf4/ocdrno.c @@ -0,0 +1,62 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include "oc.h" +#include "ocinternal.h" +#include "ocdebug.h" + +/* +This file exports procedures +that access the internals of +oc. They are intended to be called +by the drno code to avoid at least +the appearance of breaking the oc +encapsulation. +*/ + +#if 0 + +OCerror +oc_svcerrordata(OCconnection conn, char** codep, char** msgp, long* httpp) +{ + OCstate* state = (OCstate*)conn; + if(codep) *codep = state->error.code; + if(msgp) *msgp = state->error.message; + if(httpp) *httpp = state->error.httpcode; + return OC_NOERR; +} + +/* DRNO need to explicitly get and walk string values*/ +int +oc_stringcontent(OCstate* state, OCcontent* content, char** stringp, size_t* slenp) +{ + int stat = OC_NOERR; + XDR* xdrs; + unsigned int slen; + char* stringmemory; + + if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL); + + if(content->node->octype != OC_Primitive) return OCTHROW(OC_EINVAL); + if(content->node->etype != OC_String + && content->node->etype != OC_URL) return OCTHROW(OC_EINVAL); + + xdrs = state->dap.xdrs; + if(xdrs == NULL) return OCTHROW(OC_EXDR); + + if(oc_contentmode(state,content) != Datamode) return OCTHROW(OC_EINVAL); + /* We are at a single instance of a string data type*/ + if(!xdr_setpos(xdrs,content->xdroffset)) return xdrerror(); + if(!xdr_u_int(xdrs,&slen)) return xdrerror(); + stringmemory = (char*)ocmalloc(slen+1); + MEMCHECK(stringmemory,OC_ENOMEM); + if(!xdr_opaque(xdrs,stringmemory,slen)) return xdrerror(); + stringmemory[slen] = '\0'; + /* restore location*/ + if(!xdr_setpos(xdrs,content->xdroffset)) return xdrerror(); + if(stringp != NULL) *stringp = stringmemory; + if(slenp != NULL) *slenp = slen; + return OCTHROW(stat); +} +#endif diff --git a/extern/src_netcdf4/ocdrno.h b/extern/src_netcdf4/ocdrno.h new file mode 100644 index 0000000000000000000000000000000000000000..6948081df65bb6cf1180b2fc97e5c1c70efec770 --- /dev/null +++ b/extern/src_netcdf4/ocdrno.h @@ -0,0 +1,18 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCDRNO_H +#define OCDRNO_H +/* +This file exports procedures +that access the internals of +oc. They are intended to be called +by the drno code to avoid at least +the appearance of breaking the oc +encapsulation. +*/ + +/* DO NOT FREE THE RETURNED STRINGS */ +extern OCerror ocdaperrorcode(OCconnection,char**,char**,long*); + +#endif /*OCDRNO_H*/ diff --git a/extern/src_netcdf4/ocdump.c b/extern/src_netcdf4/ocdump.c new file mode 100644 index 0000000000000000000000000000000000000000..f3d1c68dd338dc773d88a4a28697065e25d12a47 --- /dev/null +++ b/extern/src_netcdf4/ocdump.c @@ -0,0 +1,482 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. +*/ + +#include "config.h" +#include + +#ifdef NETINET_IN_H +#include +#endif + +#include "ocinternal.h" +#include "ocdata.h" +#include "ocdebug.h" + +#define MAXLEVEL 1 + +/*Forward*/ +static void dumpocnode1(OCnode* node, int depth); +static void dumpdimensions(OCnode* node); +static void dumpattvalue(OCtype nctype, char** aset, int index); + +static char* sindent = NULL; + +static char* +dent(int n) +{ + if(sindent == NULL) { + sindent = (char*)ocmalloc(102); + MEMCHECK(sindent,NULL); + memset((void*)sindent,(int)' ',(size_t)101); + sindent[101] = '\0'; + } + if(n > 100) n = 100; + return sindent+(100-n); +} + +/* support [dd] leader*/ +static char* +dent2(int n) {return dent(n+4);} + +void +ocdumpnode(OCnode* node) +{ + if(node != NULL) { + dumpocnode1(node,0); + } else { + fprintf(stdout,"\n"); + } + fflush(stdout); +} + +static void +dumpskip(OCnode* node) +{ + char tmpc[64]; + char tmpi[64]; + char tmpt[64]; + char tmpo[64]; + if(node->skip.count == OCINDETERMINATE) + strcpy(tmpc,"?"); + else + snprintf(tmpc,sizeof(tmpc),"%lu",(unsigned long)node->skip.count); + if(node->skip.instancesize == OCINDETERMINATE) + strcpy(tmpi,"?"); + else + snprintf(tmpi,sizeof(tmpi),"%lu",(unsigned long)node->skip.instancesize); + if(node->skip.totalsize == OCINDETERMINATE) + strcpy(tmpt,"?"); + else + snprintf(tmpt,sizeof(tmpt),"%lu",(unsigned long)node->skip.totalsize); + if(node->skip.offset == OCINDETERMINATE) + strcpy(tmpo,"?"); + else + snprintf(tmpo,sizeof(tmpo),"%lu",(unsigned long)node->skip.offset); + + fprintf(stdout," [(%s*%s)/%s@%s]",tmpi,tmpc,tmpt,tmpo); +} + +static void +dumpocnode1(OCnode* node, int depth) +{ + unsigned int n; + switch (node->octype) { + case OC_Primitive: { + fprintf(stdout,"[%2d]%s ",depth,dent(depth)); + if(node->name == NULL) OCPANIC("prim without name"); + fprintf(stdout,"%s %s",octypetostring(node->etype),node->name); + dumpdimensions(node); +#ifdef OCIGNORE + if(node->cache.cacheable) fprintf(stdout," [cached]"); +#endif + dumpskip(node); + fprintf(stdout," &%lx",(unsigned long)node); + fprintf(stdout,"\n"); + } break; + + case OC_Dataset: { + fprintf(stdout,"[%2d]%s ",depth,dent(depth)); + fprintf(stdout,"dataset %s\n", + (node->name?node->name:"")); + for(n=0;nsubnodes);n++) { + dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1); + } + } break; + + case OC_Structure: { + fprintf(stdout,"[%2d]%s ",depth,dent(depth)); + fprintf(stdout,"struct %s", + (node->name?node->name:"")); + dumpdimensions(node); + dumpskip(node); + fprintf(stdout," &%lx",(unsigned long)node); + fprintf(stdout,"\n"); + for(n=0;nsubnodes);n++) { + dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1); + } + } break; + + case OC_Sequence: { + fprintf(stdout,"[%2d]%s ",depth,dent(depth)); + fprintf(stdout,"sequence %s", + (node->name?node->name:"")); + dumpdimensions(node); + dumpskip(node); + fprintf(stdout," &%lx",(unsigned long)node); + fprintf(stdout,"\n"); + for(n=0;nsubnodes);n++) { + dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1); + } + } break; + + case OC_Grid: { + unsigned int i; + fprintf(stdout,"[%2d]%s ",depth,dent(depth)); + fprintf(stdout,"grid %s", + (node->name?node->name:"")); + dumpdimensions(node); + dumpskip(node); + fprintf(stdout," &%lx",(unsigned long)node); + fprintf(stdout,"\n"); + fprintf(stdout,"%sarray:\n",dent2(depth+1)); + dumpocnode1((OCnode*)oclistget(node->subnodes,0),depth+2); + fprintf(stdout,"%smaps:\n",dent2(depth+1)); + for(i=1;isubnodes);i++) { + dumpocnode1((OCnode*)oclistget(node->subnodes,i),depth+2); + } + } break; + + case OC_Attribute: { + fprintf(stdout,"[%2d]%s ",depth,dent(depth)); + if(node->name == NULL) OCPANIC("Attribute without name"); + fprintf(stdout,"%s %s",octypetostring(node->etype),node->name); + for(n=0;natt.values);n++) { + char* value = (char*)oclistget(node->att.values,n); + if(n > 0) fprintf(stdout,","); + fprintf(stdout," %s",value); + } + fprintf(stdout," &%lx",(unsigned long)node); + fprintf(stdout,"\n"); + } break; + + case OC_Attributeset: { + fprintf(stdout,"[%2d]%s ",depth,dent(depth)); + fprintf(stdout,"%s:\n",node->name?node->name:"Attributes"); + for(n=0;nsubnodes);n++) { + dumpocnode1((OCnode*)oclistget(node->subnodes,n),depth+1); + } + } break; + + default: + OCPANIC1("encountered unexpected node type: %x",node->octype); + } + + if(node->attributes != NULL) { + unsigned int i; + for(i=0;iattributes);i++) { + OCattribute* att = (OCattribute*)oclistget(node->attributes,i); + fprintf(stdout,"%s[%s=",dent2(depth+2),att->name); + if(att->nvalues == 0) + OCPANIC("Attribute.nvalues == 0"); + if(att->nvalues == 1) { + dumpattvalue(att->etype,att->values,0); + } else { + unsigned int j; + fprintf(stdout,"{"); + for(j=0;jnvalues;j++) { + if(j>0) fprintf(stdout,", "); + dumpattvalue(att->etype,att->values,j); + } + fprintf(stdout,"}"); + } + fprintf(stdout,"]\n"); + } + } +} + +static void +dumpdimensions(OCnode* node) +{ + unsigned int i; + for(i=0;iarray.rank;i++) { + OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i); + fprintf(stdout,"[%s=%lu]", + (dim->name?dim->name:"?"), + (unsigned long)dim->dim.declsize); + } +} + +static void +dumpattvalue(OCtype nctype, char** strings, int index) +{ + if(nctype == OC_String || nctype == OC_URL) { + fprintf(stdout,"\"%s\"",strings[index]); + } else { + fprintf(stdout,"%s",strings[index]); + } +} + +void +ocdumpslice(OCslice* slice) +{ + fprintf(stdout,"["); + fprintf(stdout,"%lu",(unsigned long)slice->first); + if(slice->stride > 1) fprintf(stdout,":%lu",(unsigned long)slice->stride); + fprintf(stdout,":%lu",(unsigned long)(slice->first+slice->count)-1); + fprintf(stdout,"]"); +} + +void +ocdumpclause(OCprojectionclause* ref) +{ + unsigned int i; + OClist* path = oclistnew(); + occollectpathtonode(ref->node,path); + for(i=0;itree != NULL) continue; /* leave off the root node*/ + fprintf(stdout,"%s%s",(i>0?PATHSEPARATOR:""),node->name); + sliceset = (OClist*)oclistget(ref->indexsets,i); + if(sliceset != NULL) { + unsigned int j; + for(j=0;j 0) strcat(line," "); +} + +static void +dumpfield(int index, char* n8, int isxdr) +{ + char line[1024]; + char tmp[32]; + + union { + unsigned int uv; + int sv; + char cv[4]; + float fv; + } form; + union { + char cv[8]; + unsigned long long ll; + double d; + } dform; + + line[0] = '\0'; + + /* offset */ + sprintf(tmp,"%6d",index); + addfield(tmp,line,5); + + memcpy(form.cv,n8,4); + + /* straight hex*/ + sprintf(tmp,"%08x",form.uv); + addfield(tmp,line,8); + + if(isxdr) {swapinline32(&form.uv);} + + /* unsigned integer */ + sprintf(tmp,"%12u",form.uv); + addfield(tmp,line,12); + + /* signed integer */ + sprintf(tmp,"%12d",form.sv); + addfield(tmp,line,12); + + /* float */ + sprintf(tmp,"%#g",form.fv); + addfield(tmp,line,12); + + /* char[4] */ + { + /* use raw form (i.e. n8)*/ + int i; + tmp[0] = '\0'; + for(i=0;i<4;i++) { + char stmp[64]; + unsigned int c = (n8[i] & 0xff); + if(c < ' ' || c > 126) + sprintf(stmp,"\\%02x",c); + else + sprintf(stmp,"%c",c); + strcat(tmp,stmp); + } + } + + addfield(tmp,line,16); + + /* double */ + memcpy(dform.cv,n8,2*XDRUNIT); + if(isxdr) xxdrntohdouble(dform.cv,&dform.d); + sprintf(tmp,"%#g",dform.d); + addfield(tmp,line,12); + + fprintf(stdout,"%s\n",line); +} + +static void +typedmemorydump(char* memory, size_t len, int fromxdr) +{ + unsigned int i,count,rem; + char line[1024]; + char* pmem; + char mem[8]; + + assert(memory[len] == 0); + + /* build the header*/ + line[0] = '\0'; + addfield("offset",line,6); + addfield("hex",line,8); + addfield("uint",line,12); + addfield("int",line,12); + addfield("float",line,12); + addfield("char[4]",line,16); + addfield("double",line,12); + strcat(line,"\n"); + fprintf(stdout,"%s",line); + + count = (len / sizeof(int)); + rem = (len % sizeof(int)); + + for(pmem=memory,i=0;i 0) { + memset(mem,0,8); + memcpy(mem,pmem,4); + dumpfield(i*sizeof(unsigned int),mem,fromxdr); + } + fflush(stdout); +} + +static void +simplememorydump(char* memory, size_t len, int fromxdr) +{ + unsigned int i,count,rem; + int* imemory; + char tmp[32]; + char line[1024]; + + assert(memory[len] == 0); + + /* build the header*/ + line[0] = '\0'; + addfield("offset",line,6); + addfield("XDR (hex)",line,9); + addfield("!XDR (hex)",line,10); + fprintf(stdout,"%s\n",line); + + count = (len / sizeof(int)); + rem = (len % sizeof(int)); + if(rem != 0) + fprintf(stderr,"ocdump: |mem|%%4 != 0\n"); + imemory = (int*)memory; + + for(i=0;i MAXLEVEL) level = MAXLEVEL; + switch (level) { + case 1: /* Do a multi-type dump */ + typedmemorydump(memory,len,xdrencoded); + break; + case 0: /* Dump a simple linear list of the contents of the memory as 32-bit hex and decimal */ + default: + simplememorydump(memory,len,xdrencoded); + break; + } +} + +static int +ocreadfile(FILE* file, int datastart, char** memp, size_t* lenp) +{ + char* mem; + size_t len; + size_t pos; + size_t red; + struct stat stats; + + pos = ftell(file); + fseek(file,0,SEEK_SET); + fseek(file,datastart,SEEK_SET); + + fstat(fileno(file),&stats); + len = stats.st_size; + len -= datastart; + + mem = (char*)calloc(len+1,1); + if(mem == NULL) return 0; + + /* Read only the data part */ + red = fread(mem,1,len,file); + if(red < len) { + fprintf(stderr,"ocreadfile: short file\n"); + return 0; + } + fseek(file,pos,SEEK_SET); /* leave it as we found it*/ + if(memp) *memp = mem; + if(lenp) *lenp = len; + return 1; +} + +void +ocdd(OCstate* state, OCnode* root, int xdrencoded, int level) +{ + char* mem; + size_t len; + if(root->tree->data.file != NULL) { + if(!ocreadfile(root->tree->data.file,root->tree->data.bod,&mem,&len)) { + fprintf(stderr,"ocdd could not read data file\n"); + return; + } + ocdumpmemory(mem,len,xdrencoded,level); + free(mem); + } else { + mem = root->tree->data.memory; + mem += root->tree->data.bod; + len = root->tree->data.datasize; + len -= root->tree->data.bod; + ocdumpmemory(mem,len,xdrencoded,level); + } +} + diff --git a/extern/src_netcdf4/ocdump.h b/extern/src_netcdf4/ocdump.h new file mode 100644 index 0000000000000000000000000000000000000000..eabd28a46636e87184c54ba2bc3e53b1f2a15113 --- /dev/null +++ b/extern/src_netcdf4/ocdump.h @@ -0,0 +1,16 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCDUMP_H +#define OCDUMP_H + +extern void ocdumpnode(OCnode* node); + +extern void ocdumpslice(OCslice* slice); +extern void ocdumpclause(OCprojectionclause* ref); + +extern void ocdumpmemory(char* memory, size_t len, int xdrencoded, int level); + +extern void ocdd(OCstate*,OCnode*,int xdrencoded, int level); + +#endif /*OCDUMP_H*/ diff --git a/extern/src_netcdf4/ochttp.c b/extern/src_netcdf4/ochttp.c new file mode 100644 index 0000000000000000000000000000000000000000..099525bda6d130a9c07a9204b021fb9e71454a3e --- /dev/null +++ b/extern/src_netcdf4/ochttp.c @@ -0,0 +1,338 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include "ocinternal.h" +#include "ocdebug.h" +#include "ochttp.h" +#include "ocrc.h" + +static size_t WriteFileCallback(void*, size_t, size_t, void*); +static size_t WriteMemoryCallback(void*, size_t, size_t, void*); + +struct Fetchdata { + FILE* stream; + size_t size; +}; + +long +ocfetchhttpcode(CURL* curl) +{ + long httpcode; + CURLcode cstat = CURLE_OK; + /* Extract the http code */ + cstat = curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&httpcode); + if(cstat != CURLE_OK) httpcode = 0; + return httpcode; +} + +int +ocfetchurl_file(CURL* curl, const char* url, FILE* stream, + unsigned long* sizep, long* filetime) +{ + int stat = OC_NOERR; + CURLcode cstat = CURLE_OK; + struct Fetchdata fetchdata; + + /* Set the URL */ + cstat = curl_easy_setopt(curl, CURLOPT_URL, (void*)url); + if (cstat != CURLE_OK) + goto fail; + + /* send all data to this function */ + cstat = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteFileCallback); + if (cstat != CURLE_OK) + goto fail; + + /* we pass our file to the callback function */ + cstat = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&fetchdata); + if (cstat != CURLE_OK) + goto fail; + + /* One last thing; always try to get the last modified time */ + cstat = curl_easy_setopt(curl, CURLOPT_FILETIME, (long)1); + if (cstat != CURLE_OK) + goto fail; + + fetchdata.stream = stream; + fetchdata.size = 0; + cstat = curl_easy_perform(curl); + if (cstat != CURLE_OK) + goto fail; + + if (stat == OC_NOERR) { + /* return the file size*/ +#ifdef OCDEBUG + oc_log(LOGNOTE,"filesize: %lu bytes",fetchdata.size); +#endif + if (sizep != NULL) + *sizep = fetchdata.size; + /* Get the last modified time */ + if(filetime != NULL) + cstat = curl_easy_getinfo(curl,CURLINFO_FILETIME,filetime); + if(cstat != CURLE_OK) goto fail; + } + return OCTHROW(stat); + +fail: + oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); + return OCTHROW(OC_ECURL); +} + +int +ocfetchurl(CURL* curl, const char* url, OCbytes* buf, long* filetime) +{ + int stat = OC_NOERR; + CURLcode cstat = CURLE_OK; + size_t len; + + /* Set the URL */ + cstat = curl_easy_setopt(curl, CURLOPT_URL, (void*)url); + if (cstat != CURLE_OK) + goto fail; + + /* send all data to this function */ + cstat = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + if (cstat != CURLE_OK) + goto fail; + + /* we pass our file to the callback function */ + cstat = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)buf); + if (cstat != CURLE_OK) + goto fail; + + /* One last thing; always try to get the last modified time */ + cstat = curl_easy_setopt(curl, CURLOPT_FILETIME, (long)1); + + cstat = curl_easy_perform(curl); + if(cstat == CURLE_PARTIAL_FILE) { + /* Log it but otherwise ignore */ + oc_log(LOGWARN, "curl error: %s; ignored", + curl_easy_strerror(cstat)); + cstat = CURLE_OK; + } + if(cstat != CURLE_OK) goto fail; + + /* Get the last modified time */ + if(filetime != NULL) + cstat = curl_easy_getinfo(curl,CURLINFO_FILETIME,filetime); + if(cstat != CURLE_OK) goto fail; + + /* Null terminate the buffer*/ + len = ocbyteslength(buf); + ocbytesappend(buf, '\0'); + ocbytessetlength(buf, len); /* dont count null in buffer size*/ +#ifdef OCDEBUG + oc_log(LOGNOTE,"buffersize: %lu bytes",(unsigned long)ocbyteslength(buf)); +#endif + + return OCTHROW(stat); + +fail: + oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); + return OCTHROW(OC_ECURL); +} + +static size_t +WriteFileCallback(void* ptr, size_t size, size_t nmemb, void* data) +{ + size_t realsize = size * nmemb; + size_t count; + struct Fetchdata* fetchdata; + fetchdata = (struct Fetchdata*) data; + if(realsize == 0) + oc_log(LOGWARN,"WriteFileCallback: zero sized chunk"); + count = fwrite(ptr, size, nmemb, fetchdata->stream); + if (count > 0) { + fetchdata->size += (count * size); + } else { + oc_log(LOGWARN,"WriteFileCallback: zero sized write"); + } +#ifdef OCPROGRESS + oc_log(LOGNOTE,"callback: %lu bytes",(unsigned long)realsize); +#endif + return count; +} + +static size_t +WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) +{ + size_t realsize = size * nmemb; + OCbytes* buf = (OCbytes*) data; + if(realsize == 0) + oc_log(LOGWARN,"WriteMemoryCallback: zero sized chunk"); + /* Optimize for reading potentially large dods datasets */ + if(!ocbytesavail(buf,realsize)) { + /* double the size of the packet */ + ocbytessetalloc(buf,2*ocbytesalloc(buf)); + } + ocbytesappendn(buf, ptr, realsize); +#ifdef OCPROGRESS + oc_log(LOGNOTE,"callback: %lu bytes",(unsigned long)realsize); +#endif + return realsize; +} + +#if 0 +static void +assembleurl(DAPURL* durl, OCbytes* buf, int what) +{ + encodeurltext(durl->url,buf); + if(what & WITHPROJ) { + ocbytescat(buf,"?"); + encodeurltext(durl->projection,buf); + } + if(what & WITHSEL) encodeurltext(durl->selection,buf); + +} + +static char mustencode=""; +static char hexchars[16] = { + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f', +}; + +static void +encodeurltext(char* text, OCbytes* buf) +{ + /* Encode the URL to handle illegal characters */ + len = strlen(url); + encoded = ocmalloc(len*4+1); /* should never be larger than this*/ + if(encoded==NULL) return; + p = url; q = encoded; + while((c=*p++)) { + if(strchr(mustencode,c) != NULL) { + char tmp[8]; + int hex1, hex2; + hex1 = (c & 0x0F); + hex2 = (c & 0xF0) >> 4; + tmp[0] = '0'; tmp[1] = 'x'; + tmp[2] = hexchars[hex2]; tmp[3] = hexchars[hex1]; + tmp[4] = '\0'; + ocbytescat(buf,tmp); + } else *q++ = (char)c; + } + +} + +#endif + +int +occurlopen(CURL** curlp) +{ + int stat = OC_NOERR; + CURLcode cstat = CURLE_OK; + CURL* curl; + /* initialize curl*/ + curl = curl_easy_init(); + if (curl == NULL) + stat = OC_ECURL; + else { + cstat = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + if (cstat != CURLE_OK) + stat = OC_ECURL; + /* some servers don't like requests that are made without a user-agent */ + cstat = curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + if (cstat != CURLE_OK) + stat = OC_ECURL; + } + if (curlp) + *curlp = curl; + return OCTHROW(stat); +} + +void +occurlclose(CURL* curl) +{ + if (curl != NULL) + curl_easy_cleanup(curl); +} + +int +ocfetchlastmodified(CURL* curl, char* url, long* filetime) +{ + int stat = OC_NOERR; + CURLcode cstat = CURLE_OK; + + /* Set the URL */ + cstat = curl_easy_setopt(curl, CURLOPT_URL, (void*)url); + if (cstat != CURLE_OK) + goto fail; + + /* Ask for head */ + cstat = curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30); /* 30sec timeout*/ + cstat = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2); + cstat = curl_easy_setopt(curl, CURLOPT_HEADER, 1); + cstat = curl_easy_setopt(curl, CURLOPT_NOBODY, 1); + cstat = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + cstat = curl_easy_setopt(curl, CURLOPT_FILETIME, (long)1); + + cstat = curl_easy_perform(curl); + if(cstat != CURLE_OK) goto fail; + if(filetime != NULL) + cstat = curl_easy_getinfo(curl,CURLINFO_FILETIME,filetime); + if(cstat != CURLE_OK) goto fail; + + return OCTHROW(stat); + +fail: + oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); + return OCTHROW(OC_ECURL); +} + +int +ocping(const char* url) +{ + int stat = OC_NOERR; + CURLcode cstat = CURLE_OK; + CURL* curl = NULL; + OCbytes* buf = NULL; + + /* Create a CURL instance */ + stat = occurlopen(&curl); + if(stat != OC_NOERR) return stat; + + /* use a very short timeout: 10 seconds */ + cstat = curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)10); + if (cstat != CURLE_OK) + goto done; + + /* fail on HTTP 400 code errors */ + cstat = curl_easy_setopt(curl, CURLOPT_FAILONERROR, (long)1); + if (cstat != CURLE_OK) + goto done; + + /* Try to get the file */ + buf = ocbytesnew(); + stat = ocfetchurl(curl,url,buf,NULL); + if(stat == OC_NOERR) { + /* Don't trust curl to return an error when request gets 404 */ + long http_code = 0; + cstat = curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE, &http_code); + if (cstat != CURLE_OK) + goto done; + if(http_code >= 400) { + cstat = CURLE_HTTP_RETURNED_ERROR; + goto done; + } + } else + goto done; + +done: + ocbytesfree(buf); + occurlclose(curl); + if(cstat != CURLE_OK) { + oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); + stat = OC_EDAPSVC; + } + return OCTHROW(stat); +} + + diff --git a/extern/src_netcdf4/ochttp.h b/extern/src_netcdf4/ochttp.h new file mode 100644 index 0000000000000000000000000000000000000000..a0e26f97dccf1a70104a74cb2c140fdf572efbb8 --- /dev/null +++ b/extern/src_netcdf4/ochttp.h @@ -0,0 +1,22 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef HTTP_H +#define HTTP_H 1 + +extern int curlopen(CURL** curlp); +extern void curlclose(CURL*); + +extern int ocfetchurl(CURL*, const char*, OCbytes*, long*); +extern int ocfetchurl_file(CURL*, const char*, FILE*, unsigned long*, long*); + +extern long ocfetchhttpcode(CURL* curl); + +extern int ocfetchlastmodified(CURL* curl, char* url, long* filetime); + +extern int occurlopen(CURL** curlp); +extern void occurlclose(CURL* curlp); + +extern int ocping(const char* url); + +#endif /*HTTP_H*/ diff --git a/extern/src_netcdf4/ocinternal.c b/extern/src_netcdf4/ocinternal.c new file mode 100644 index 0000000000000000000000000000000000000000..e817e39a185b3896847d83bed4067cad73fa4bed --- /dev/null +++ b/extern/src_netcdf4/ocinternal.c @@ -0,0 +1,574 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "ocinternal.h" +#include "ocdebug.h" +#include "ocdata.h" +#include "occontent.h" +#include "occlientparams.h" +#include "ocrc.h" +#include "occurlfunctions.h" + +#include "ochttp.h" +#include "ocread.h" + +/* Note: TMPPATH must end in '/' */ +#ifdef __CYGWIN__ +#define TMPPATH1 "/cygdrive/c/temp/" +#define TMPPATH2 "./" +#elifdef WIN32 +#define TMPPATH1 "c:\\temp/" +#define TMPPATH2 ".\\" +#else +#define TMPPATH1 "/tmp/" +#define TMPPATH2 "./" +#endif + +/* Define default rc files and aliases*/ +static char* rcfilenames[3] = {".dodsrc",".ocrc",NULL}; + +static int ocextractddsinmemory(OCstate*,OCtree*,int); +static int ocextractddsinfile(OCstate*,OCtree*,int); +static char* constraintescape(const char* url); +static OCerror createtempfile(OCstate*,OCtree*); +static int createtempfile1(char*,char**); + +static void ocsetcurlproperties(OCstate*); + +extern OCnode* makeunlimiteddimension(void); + +#ifdef WIN32 +#include +#define _S_IREAD 256 +#define _S_IWRITE 128 +#else +#include +#endif + +/* Global flags*/ +int oc_curl_file_supported; +int oc_curl_https_supported; + +int +ocinternalinitialize(void) +{ + int stat = OC_NOERR; + + /* Compute some xdr related flags */ + xxdr_init(); + + oc_loginit(); + + /* Determine if this version of curl supports + "file://..." &/or "https://..." urls. + */ + { + const char* const* proto; /*weird*/ + curl_version_info_data* curldata; + curldata = curl_version_info(CURLVERSION_NOW); + oc_curl_file_supported = 0; + oc_curl_https_supported = 0; + for(proto=curldata->protocols;*proto;proto++) { + if(strcmp("file",*proto)==0) {oc_curl_file_supported=1;break;} + if(strcmp("https",*proto)==0) {oc_curl_https_supported=1;break;} + } + if(ocdebug > 0) { + oc_log(LOGNOTE,"Curl file:// support = %d",oc_curl_file_supported); + oc_log(LOGNOTE,"Curl https:// support = %d",oc_curl_file_supported); + } + } + + /* compile the .dodsrc, if any */ + { + char* path = NULL; + char* homepath = NULL; + char** alias; + FILE* f = NULL; + /* locate the configuration files: . first in '.', then $HOME */ + for(alias=rcfilenames;*alias;alias++) { + path = (char*)malloc(strlen("./")+strlen(*alias)+1); + if(path == NULL) return OC_ENOMEM; + strcpy(path,"./"); + strcat(path,*alias); + /* see if file is readable */ + f = fopen(path,"r"); + if(f != NULL) break; + if(path != NULL) {free(path); path = NULL;} /* cleanup */ + } + if(f == NULL) { /* try $HOME */ + OCASSERT(path == NULL); + homepath = getenv("HOME"); + if (homepath!= NULL) { + for(alias=rcfilenames;*alias;alias++) { + path = (char*)malloc(strlen(homepath)+1+strlen(*alias)+1); + if(path == NULL) return OC_ENOMEM; + strcpy(path,homepath); + strcat(path,"/"); + strcat(path,*alias); + f = fopen(path,"r"); + if(f != NULL) break; + if(path != NULL) {free(path); path=NULL;} + } + } + } + if(f == NULL) { + oc_log(LOGDBG,"Cannot find runtime configuration file"); + } else { + OCASSERT(path != NULL); + fclose(f); + if(ocdebug > 1) + fprintf(stderr, "DODS RC file: %s\n", path); + if(ocdodsrc_read(*alias,path) == 0) + oc_log(LOGERR, "Error parsing %s\n",path); + } + if(path != NULL) free(path); + } + return OCTHROW(stat); +} + +/**************************************************/ +OCerror +ocopen(OCstate** statep, const char* url) +{ + int stat = OC_NOERR; + OCstate * state = NULL; + OCURI* tmpurl = NULL; + CURL* curl = NULL; /* curl handle*/ + + if(!ocuriparse(url,&tmpurl)) {OCTHROWCHK(stat=OC_EBADURL); goto fail;} + + stat = occurlopen(&curl); + if(stat != OC_NOERR) {OCTHROWCHK(stat); goto fail;} + + state = (OCstate*)ocmalloc(sizeof(OCstate)); /* ocmalloc zeros memory*/ + if(state == NULL) {OCTHROWCHK(stat=OC_ENOMEM); goto fail;} + + /* Setup DAP state*/ + state->magic = OCMAGIC; + state->curl = curl; + state->trees = oclistnew(); + state->uri = tmpurl; + if(!ocuridecodeparams(state->uri)) { + oc_log(LOGWARN,"Could not parse client parameters"); + } + state->packet = ocbytesnew(); + ocbytessetalloc(state->packet,DFALTPACKETSIZE); /*initial reasonable size*/ + + /* set curl properties for this link */ + ocsetcurlproperties(state); + + /* Set up list to support reuse/reclamation of OCcontent objects. */ + state->contentlist = NULL; + + if(statep) *statep = state; + return OCTHROW(stat); + +fail: + ocurifree(tmpurl); + if(state != NULL) ocfree(state); + if(curl != NULL) occurlclose(curl); + return OCTHROW(stat); +} + +OCerror +ocfetchf(OCstate* state, const char* constraint, OCdxd kind, OCflags flags, + OCnode** rootp) +{ + OCtree* tree = NULL; + OCnode* root = NULL; + OCerror stat = OC_NOERR; + + tree = (OCtree*)ocmalloc(sizeof(OCtree)); + MEMCHECK(tree,OC_ENOMEM); + memset((void*)tree,0,sizeof(OCtree)); + tree->dxdclass = kind; + tree->state = state; + tree->constraint = constraintescape(constraint); + if(tree->constraint == NULL) + tree->constraint = nulldup(constraint); + + /* Set curl properties: pwd, flags, proxies, ssl */ + if((stat=ocset_user_password(state))!= OC_NOERR) goto fail; + if((stat=ocset_curl_flags(state)) != OC_NOERR) goto fail; + if((stat=ocset_proxy(state)) != OC_NOERR) goto fail; + if((stat=ocset_ssl(state)) != OC_NOERR) goto fail; + + ocbytesclear(state->packet); + + switch (kind) { + case OCDAS: + stat = readDAS(state,tree); + if(stat == OC_NOERR) { + tree->text = ocbytesdup(state->packet); + if(tree->text == NULL) stat = OC_EDAS; + } + break; + case OCDDS: + stat = readDDS(state,tree); + if(stat == OC_NOERR) { + tree->text = ocbytesdup(state->packet); + if(tree->text == NULL) stat = OC_EDDS; + } + break; + case OCDATADDS: + if((flags & OCONDISK) != 0) {/* store in file */ + /* Create the datadds file immediately + so that DRNO can reference it*/ + /* Make the tmp file*/ + stat = createtempfile(state,tree); + if(stat) {OCTHROWCHK(stat); goto unwind;} + stat = readDATADDS(state,tree,flags); + if(stat == OC_NOERR) { + /* Separate the DDS from data and return the dds; + will modify packet */ + stat = ocextractddsinfile(state,tree,flags); + } + } else { /*in memory*/ + stat = readDATADDS(state,tree,flags); + if(stat == OC_NOERR) { + /* Separate the DDS from data and return the dds; + will modify packet */ + stat = ocextractddsinmemory(state,tree,flags); + } + } + break; + }/*switch*/ + if(stat != OC_NOERR) { + /* Obtain any http code */ + state->error.httpcode = ocfetchhttpcode(state->curl); + if(state->error.httpcode >= 400) { + oc_log(LOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); + } else { + oc_log(LOGWARN,"oc_open: Could not read url"); + } + return OCTHROW(stat); + } + + tree->nodes = NULL; + stat = DAPparse(state,tree,tree->text); + /* Check and report on an error return from the server */ + if(stat == OC_EDAPSVC && state->error.code != NULL) { + oc_log(LOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", + state->error.code, + (state->error.message?state->error.message:"")); + } + if(stat) {OCTHROWCHK(stat); goto unwind;} + root = tree->root; + /* make sure */ + tree->root = root; + root->tree = tree; + + /* Verify the parse */ + switch (kind) { + case OCDAS: + if(root->octype != OC_Attributeset) + {OCTHROWCHK(stat=OC_EDAS); goto unwind;} + break; + case OCDDS: + if(root->octype != OC_Dataset) + {OCTHROWCHK(stat=OC_EDDS); goto unwind;} + break; + case OCDATADDS: + if(root->octype != OC_Dataset) + {OCTHROWCHK(stat=OC_EDATADDS); goto unwind;} + /* Modify the tree kind */ + tree->dxdclass = OCDATADDS; + break; + default: return OC_EINVAL; + } + + if(kind != OCDAS) { + /* Process ocnodes to assign offsets and sizes where possible */ + occomputeskipdata(state,root); + /* Process ocnodes to mark those that are cacheable */ + ocmarkcacheable(state,root); + /* Process ocnodes to handle various semantic issues*/ + occomputesemantics(tree->nodes); + } + + /* Process ocnodes to compute name info*/ + occomputefullnames(tree->root); + + if(kind == OCDATADDS) { + if((flags & OCONDISK) != 0) { + tree->data.xdrs = xxdr_filecreate(tree->data.file,tree->data.bod); + } else { + /* Switch to zero based memory */ + tree->data.xdrs + = xxdr_memcreate(tree->data.memory,tree->data.datasize,tree->data.bod); + } + MEMCHECK(tree->data.xdrs,OC_ENOMEM); + } + + /* Put root into the state->trees list */ + oclistpush(state->trees,(ocelem)root); + + if(rootp) *rootp = root; + return stat; + +unwind: + ocfreetree(tree); +fail: + return OCTHROW(stat); +} + +void +occlose(OCstate* state) +{ + unsigned int i; + if(state == NULL) return; + + /* Warning: ocfreeroot will attempt to remove the root from state->trees */ + /* Ok in this case because we are popping the root out of state->trees */ + for(i=0;itrees);i++) { + OCnode* root = (OCnode*)oclistpop(state->trees); + ocfreeroot(root); + } + oclistfree(state->trees); + ocurifree(state->uri); + ocbytesfree(state->packet); + ocfree(state->error.code); + ocfree(state->error.message); + if(state->contentlist != NULL) { + struct OCcontent* next; + struct OCcontent* curr = state->contentlist; + while(curr != NULL) { + next = curr->next; + ocfree(curr); + curr = next; + } + } + ocfree(state->curlflags.useragent); + ocfree(state->curlflags.cookiejar); + ocfree(state->curlflags.cookiefile); + ocfree(state->ssl.certificate); + ocfree(state->ssl.key); + ocfree(state->ssl.keypasswd); + ocfree(state->ssl.cainfo); + ocfree(state->ssl.capath); + ocfree(state->proxy.host); + ocfree(state->creds.username); + ocfree(state->creds.password); + if(state->curl != NULL) occurlclose(state->curl); + ocfree(state); +} + +static OCerror +ocextractddsinmemory(OCstate* state, OCtree* tree, OCflags flags) +{ + OCerror stat = OC_NOERR; + size_t ddslen, bod, bodfound; + /* Read until we find the separator (or EOF)*/ + bodfound = findbod(state->packet,&bod,&ddslen); + if(!bodfound) {/* No BOD; pretend */ + bod = tree->data.bod; + ddslen = tree->data.datasize; + } + tree->data.bod = bod; + tree->data.ddslen = ddslen; + /* copy out the dds */ + if(ddslen > 0) { + tree->text = (char*)ocmalloc(ddslen+1); + memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen); + tree->text[ddslen] = '\0'; + } else + tree->text = NULL; + /* Extract the inmemory contents */ + tree->data.memory = ocbytesextract(state->packet); +#ifdef OCIGNORE + /* guarantee the data part is on an 8 byte boundary */ + if(tree->data.bod % 8 != 0) { + unsigned long count = tree->data.datasize - tree->data.bod; + memcpy(tree->xdrmemory,tree->xdrmemory+tree->data.bod,count); + tree->data.datasize = count; + tree->data.bod = 0; + tree->data.ddslen = 0; + } +#endif + if(tree->text == NULL) stat = OC_EDATADDS; + return OCTHROW(stat); +} + +static OCerror +ocextractddsinfile(OCstate* state, OCtree* tree, OCflags flags) +{ + OCerror stat = OC_NOERR; + size_t ddslen, bod, bodfound; + + /* Read until we find the separator (or EOF)*/ + ocbytesclear(state->packet); + rewind(tree->data.file); + bodfound = 0; + do { + char chunk[1024]; + size_t count; + /* read chunks of the file until we find the separator*/ + count = fread(chunk,1,sizeof(chunk),tree->data.file); + if(count <= 0) break; /* EOF;*/ + ocbytesappendn(state->packet,chunk,count); + bodfound = findbod(state->packet,&bod,&ddslen); + } while(!bodfound); + if(!bodfound) {/* No BOD; pretend */ + bod = tree->data.bod; + ddslen = tree->data.datasize; + } + tree->data.bod = bod; + tree->data.ddslen = ddslen; + /* copy out the dds */ + if(ddslen > 0) { + tree->text = (char*)ocmalloc(ddslen+1); + memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen); + tree->text[ddslen] = '\0'; + } else + tree->text = NULL; + /* reset the position of the tmp file*/ + fseek(tree->data.file,tree->data.bod,SEEK_SET); + if(tree->text == NULL) stat = OC_EDATADDS; + return OCTHROW(stat); +} + +static OCerror +createtempfile(OCstate* state, OCtree* tree) +{ + int fd; + char* name = NULL; + fd = createtempfile1(TMPPATH1,&name); + if(fd < 0) + fd = createtempfile1(TMPPATH2,&name); + if(fd < 0) { + oc_log(LOGERR,"oc_open: attempt to open tmp file failed: %s",name); + return errno; + } +#ifdef OCDEBUG + oc_log(LOGNOTE,"oc_open: using tmp file: %s",name); +#endif + tree->data.filename = name; /* remember our tmp file name */ + tree->data.file = fdopen(fd,"w+"); + if(tree->data.file == NULL) return OC_EOPEN; + /* unlink the temp file so it will automatically be reclaimed */ + if(ocdebug == 0) unlink(tree->data.filename); + return OC_NOERR; +} + +int +createtempfile1(char* tmppath, char** tmpnamep) +{ + int fd = 0; + char* tmpname = NULL; + tmpname = (char*)malloc(strlen(tmppath)+strlen("dataddsXXXXXX")+1); + if(tmpname == NULL) return -1; + strcpy(tmpname,tmppath); +#ifdef HAVE_MKSTEMP + strcat(tmpname,"dataddsXXXXXX"); + /* Note Potential problem: old versions of this function + leave the file in mode 0666 instead of 0600 */ + fd = mkstemp(tmpname); +#else /* !HAVE_MKSTEMP */ + /* Need to simulate by using some kind of pseudo-random number */ + strcat(tmpname,"datadds"); + { + int rno = rand(); + char spid[7]; + if(rno < 0) rno = -rno; + sprintf(spid,"%06d",rno); + strcat(tmpname,spid); +# ifdef WIN32 + fd=open(tmpname,O_RDWR|O_BINARY|O_CREAT|O_EXCL|FILE_ATTRIBUTE_TEMPORARY, _S_IREAD|_S_IWRITE); +# else + fd=open(tmpname,O_RDWR|O_CREAT|O_EXCL, S_IRWXU); +# endif + } +#endif /* !HAVE_MKSTEMP */ + if(tmpname == NULL) return -1; + if(tmpnamep) *tmpnamep = tmpname; + return fd; +} + +/* Allow these (non-alpha-numerics) to pass thru */ +static char okchars[] = "&/:;,.=?@'\"<>{}!|\\^[]`~"; +static char hexdigits[] = "0123456789abcdef"; + + +/* Modify constraint to use %XX escapes */ +static char* +constraintescape(const char* url) +{ + size_t len; + char* p; + int c; + char* eurl; + + if(url == NULL) return NULL; + len = strlen(url); + eurl = ocmalloc(1+3*len); /* worst case: c -> %xx */ + MEMCHECK(eurl,NULL); + p = eurl; + *p = '\0'; + while((c=*url++)) { + if(c >= '0' && c <= '9') {*p++ = c;} + else if(c >= 'a' && c <= 'z') {*p++ = c;} + else if(c >= 'A' && c <= 'Z') {*p++ = c;} + else if(strchr(okchars,c) != NULL) {*p++ = c;} + else { + *p++ = '%'; + *p++ = hexdigits[(c & 0xf0)>>4]; + *p++ = hexdigits[(c & 0xf)]; + } + } + *p = '\0'; + return eurl; +} + +OCerror +ocupdatelastmodifieddata(OCstate* state) +{ + OCerror status = OC_NOERR; + long lastmodified; + char* base = NULL; + base = ocuribuild(state->uri,NULL,NULL,OCURIENCODE); + status = ocfetchlastmodified(state->curl, base, &lastmodified); + free(base); + if(status == OC_NOERR) { + state->datalastmodified = lastmodified; + } + return status; +} + +/* + Set curl properties for link based on rc files +*/ +static void +ocsetcurlproperties(OCstate* state) +{ + CURLcode cstat = CURLE_OK; + + /* process the triple store wrt to this state */ + if(ocdodsrc_process(state) != OC_NOERR) { + oc_log(LOGERR,"Malformed .opendaprc configuration file"); + goto fail; + } + if(state->creds.username == NULL && state->creds.password == NULL) { + if(state->uri->user != NULL && state->uri->password != NULL) { + /* this overrides .dodsrc */ + if(state->creds.password) free(state->creds.password); + state->creds.password = nulldup(state->uri->password); + if(state->creds.username) free(state->creds.username); + state->creds.username = nulldup(state->uri->user); + } + } + return; + +fail: + if(cstat != CURLE_OK) + oc_log(LOGERR, "curl error: %s", curl_easy_strerror(cstat)); + return; +} diff --git a/extern/src_netcdf4/ocinternal.h b/extern/src_netcdf4/ocinternal.h new file mode 100644 index 0000000000000000000000000000000000000000..ccb6c3371e305c9b99ecf0e65a63dac4fe95bb9e --- /dev/null +++ b/extern/src_netcdf4/ocinternal.h @@ -0,0 +1,198 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCINTERNAL_H +#define OCINTERNAL_H + +#include "config.h" + +#ifdef _AIX +#include +#endif + +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#define CURL_DISABLE_TYPECHECK 1 +#include + +#include "oclist.h" +#include "ocbytes.h" +#include "ocuri.h" + +#define OCCACHEPOS + +#include "oc.h" +#include "ocdatatypes.h" +#include "occonstraints.h" +#include "ocnode.h" +#include "ocutil.h" +#include "oclog.h" +#include "xxdr.h" +#include "ocdata.h" + +#ifndef nulldup +#define nulldup(s) (s==NULL?NULL:strdup(s)) +#endif + +#define nullstring(s) (s==NULL?"(null)":s) +#define PATHSEPARATOR "." + +/* Default initial memory packet size */ +#define DFALTPACKETSIZE 0x20000 /*approximately 100k bytes*/ + +/* Default maximum memory packet size */ +#define DFALTMAXPACKETSIZE 0x3000000 /*approximately 50M bytes*/ + +/* Extend the OCdxd type */ +#define OCVER 3 + +/* Define a magic number to mark externally visible oc objects */ +#define OCMAGIC ((unsigned int)0x0c0c0c0c) /*clever, huh?*/ + +/*! Specifies the OCstate. */ +typedef struct OCstate +{ + unsigned int magic; /* Mark each structure type */ + CURL* curl; /* curl handle*/ + OClist* trees; /* list ; all root objects */ + OCURI* uri; /* base URI*/ + OCbytes* packet; /* shared by all trees during construction */ + /* OCContent information */ + struct OCcontent* contentlist; + struct OCerrdata {/* Hold info for an error return from server */ + char* code; + char* message; + long httpcode; + char curlerrorbuf[CURL_ERROR_SIZE]; /* to get curl error message */ + } error; + /* Store .rc file info */ + struct OCcurlflags { + int compress; + int verbose; + int timeout; + int followlocation; + int maxredirs; + char* useragent; + char* cookiejar; + char* cookiefile; + } curlflags; + struct OCSSL { + int validate; + char* certificate; + char* key; + char* keypasswd; + char* cainfo; /* certificate authority */ + char* capath; + int verifypeer; + } ssl; + struct OCproxy { + char *host; + int port; + } proxy; + struct OCcredentials { + char *username; + char *password; + } creds; + long ddslastmodified; + long datalastmodified; +} OCstate; + + +/*! Specifies all the info about a particular DAP tree + i.e. DAS, DDS, or DATADDS as obtained from a fetch response + This is associated with the root object. +*/ +typedef struct OCtree +{ + OCdxd dxdclass; + char* constraint; + char* text; + struct OCnode* root; /* cross link */ + struct OCstate* state; /* cross link */ + OClist* nodes; /* all nodes in tree*/ + /* when dxdclass == OCDATADDS */ + struct { + char* memory; /* allocated memory if OC_INMEMORY is set */ + char* filename; + FILE* file; + unsigned long datasize; /* xdr size on disk or in memory */ + unsigned long bod; /* offset of the beginning of packet data */ + unsigned long ddslen; /* length of ddslen (assert(ddslen <= bod)) */ + XXDR* xdrs; /* access either memory or file */ + } data; +} OCtree; + +/* (Almost) All shared procedure definitions are kept here + except for: ocdebug.h ocutil.h + The true external interface is defined in oc.h +*/ + +/* Location: ocnode.c */ +extern OCnode* ocmakenode(char* name, OCtype ptype, OCnode* root); +extern void occollectpathtonode(OCnode* node, OClist* path); +extern void occomputefullnames(OCnode* root); +extern void occomputesemantics(OClist*); +extern void ocaddattribute(OCattribute* attr, OCnode* parent); +extern OCattribute* ocmakeattribute(char* name, OCtype ptype, OClist* values); +extern size_t ocsetsize(OCnode* node); +extern OCerror occorrelate(OCnode*,OCnode*); +extern OCerror occomputeskipdata(OCstate*, OCnode*); +extern void ocmarkcacheable(OCstate* state, OCnode* ddsroot); + +/* Location: dapparselex.c*/ +extern int dapdebug; +extern OCerror DAPparse(OCstate*, struct OCtree*, char*); +extern char* dimnameanon(char* basename, unsigned int index); + +/* Location: ceparselex.c*/ +extern int cedebug; +extern OClist* CEparse(OCstate*,char* input); + +/* Location: ocinternal.c*/ +extern OCerror ocopen(OCstate** statep, const char* url); +extern void occlose(OCstate* state); + +extern OCerror ocfetchf(OCstate*, const char*, OCdxd, OCflags, OCnode**); + +/* Location: ocinternal.c */ +extern int oc_network_order; +extern int oc_invert_xdr_double; +extern int ocinternalinitialize(void); + +/* Location: ocnode.c */ +extern void ocfreetree(OCtree* tree); +extern void ocfreeroot(OCnode* root); +extern void ocfreenodes(OClist*); + +extern void ocddsclear(struct OCstate*); +extern void ocdasclear(struct OCstate*); +extern void ocdataddsclear(struct OCstate*); +extern void* oclinearize(OCtype etype, unsigned int, char**); + +/* Merge DAS with DDS or DATADDS*/ +extern int ocddsdasmerge(struct OCstate*, OCnode* das, OCnode* dds); + +extern OCerror ocupdatelastmodifieddata(OCstate* state); + +extern int ocinternalinitialize(void); + + +extern OCerror ocsetrcfile(char* rcfile); + +/* Global stateflags */ +extern int oc_curl_file_supported; +extern int oc_curl_https_supported; + +#endif /*COMMON_H*/ diff --git a/extern/src_netcdf4/oclist.c b/extern/src_netcdf4/oclist.c new file mode 100644 index 0000000000000000000000000000000000000000..e4860dad5562f4bffe06ca51d09c55a754e0b493 --- /dev/null +++ b/extern/src_netcdf4/oclist.c @@ -0,0 +1,171 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" + +#include +#include +#include + +#include "oclist.h" + +static ocelem ocDATANULL = (ocelem)0; +/*static int ocinitialized=0;*/ + +int oclistnull(ocelem e) {return e == ocDATANULL;} + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define DEFAULTALLOC 16 +#define ALLOCINCR 16 + +OClist* oclistnewn(int prealloc) +{ + OClist* l; +/* + if(!ocinitialized) { + memset((void*)&ocDATANULL,0,sizeof(ocelem)); + ocinitialized = 1; + } +*/ + if(prealloc < 0) prealloc = 0; + l = (OClist*)malloc(sizeof(OClist)); + if(l) { + l->alloc=prealloc; + l->length=prealloc; + l->content=(prealloc==0?NULL:(ocelem*)calloc(prealloc,sizeof(ocelem))); + if(l == NULL) {free(l);return 0;} + } + return l; +} + +int +oclistfree(OClist* l) +{ + if(l) { + l->alloc = 0; + if(l->content != NULL) {free(l->content); l->content = NULL;} + free(l); + } + return TRUE; +} + +int +oclistsetalloc(OClist* l, unsigned int sz) +{ + ocelem* newcontent; + if(l == NULL) return FALSE; + if(sz <= 0) {sz = (l->length?2*l->length:DEFAULTALLOC);} + if(l->alloc >= sz) {return TRUE;} + newcontent=(ocelem*)calloc(sz,sizeof(ocelem)); + if(l->alloc > 0 && l->length > 0 && l->content != NULL) { + memcpy((void*)newcontent,(void*)l->content,sizeof(ocelem)*l->length); + free(l->content); + } + l->content=newcontent; + l->alloc=sz; + return TRUE; +} + +int +oclistsetlength(OClist* l, unsigned int sz) +{ + if(l == NULL) return FALSE; + if(sz > l->alloc && !oclistsetalloc(l,sz)) return FALSE; + l->length = sz; + return TRUE; +} + +ocelem +oclistget(OClist* l, unsigned int index) +{ + if(l == NULL || l->length == 0) return ocDATANULL; + if(index >= l->length) return ocDATANULL; + return l->content[index]; +} + +int +oclistset(OClist* l, unsigned int index, ocelem elem) +{ + if(l == NULL) return FALSE; + if(index >= l->length) return FALSE; + l->content[index] = elem; + return TRUE; +} + +/* Insert at position i of l; will push up elements i..|seq|. */ +int +oclistinsert(OClist* l, unsigned int index, ocelem elem) +{ + unsigned int i; + if(l == NULL) return FALSE; + if(index > l->length) return FALSE; + oclistsetalloc(l,0); + for(i=l->length;i>index;i--) l->content[i] = l->content[i-1]; + l->content[index] = elem; + l->length++; + return TRUE; +} + +int +oclistpush(OClist* l, ocelem elem) +{ + if(l == NULL) return FALSE; + if(l->length >= l->alloc) oclistsetalloc(l,0); + l->content[l->length] = elem; + l->length++; + return TRUE; +} + +ocelem +oclistpop(OClist* l) +{ + if(l == NULL || l->length == 0) return ocDATANULL; + l->length--; + return l->content[l->length]; +} + +ocelem +oclisttop(OClist* l) +{ + if(l == NULL || l->length == 0) return ocDATANULL; + return l->content[l->length - 1]; +} + +ocelem +oclistremove(OClist* l, unsigned int i) +{ + unsigned int len; + ocelem elem; + if(l == NULL || (len=l->length) == 0) return ocDATANULL; + if(i >= len) return ocDATANULL; + elem = l->content[i]; + for(i++;icontent[i-1] = l->content[i]; + l->length--; + return elem; +} + +/* Duplicate and return the content (null terminate) */ +ocelem* +oclistdup(OClist* l) +{ + ocelem* result = (ocelem*)malloc(sizeof(ocelem)*(l->length+1)); + memcpy((void*)result,(void*)l->content,sizeof(ocelem)*l->length); + result[l->length] = (ocelem)0; + return result; +} + +int +oclistcontains(OClist* list, ocelem elem) +{ + unsigned int i; + for(i=0;ialloc)) +#define oclistcontents(l) ((l)->content) +#define oclistlength(l) ((l)?(l)->length:0U) + +#endif /*OCLIST_H*/ + diff --git a/extern/src_netcdf4/oclog.c b/extern/src_netcdf4/oclog.c new file mode 100644 index 0000000000000000000000000000000000000000..e58861cf92b1b44e73fce13c718d51c50053cf81 --- /dev/null +++ b/extern/src_netcdf4/oclog.c @@ -0,0 +1,132 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" + +#include "ocinternal.h" +#include +#include + +#define PREFIXLEN 8 + +#define ENVFLAG "OCLOGFILE" + +static int ocloginit = 0; +static int oclogging = 0; +static char* oclogfile = NULL; +static FILE* oclogstream = NULL; + +void +oc_loginit(void) +{ + ocloginit = 1; + oc_setlogging(0); + oclogfile = NULL; + oclogstream = NULL; + /* Use environment variables to preset oclogging state*/ + /* I hope this is portable*/ + if(getenv(ENVFLAG) != NULL) { + const char* file = getenv(ENVFLAG); + oc_setlogging(1); + oc_logopen(file); + } +} + +void +oc_setlogging(int tf) +{ + if(!ocloginit) oc_loginit(); + oclogging = tf; +} + +void +oc_logopen(const char* file) +{ + if(!ocloginit) oc_loginit(); + if(oclogfile != NULL) { + fclose(oclogstream); + free(oclogfile); + oclogfile = NULL; + } + if(file == NULL || strlen(file) == 0) { + /* use stderr*/ + oclogstream = stderr; + oclogfile = NULL; + } else { + int fd; + oclogfile = (char*)malloc(strlen(file)+1); + strcpy(oclogfile,file); + oclogstream = NULL; + /* We need to deal with this file carefully + to avoid unauthorized access*/ + fd = open(oclogfile,O_WRONLY|O_APPEND|O_CREAT,0600); + if(fd >= 0) { + oclogstream = fdopen(fd,"a"); + } else { + free(oclogfile); + oclogfile = NULL; + oc_setlogging(0); + } + } +} + +void +oc_logclose(void) +{ + if(oclogfile != NULL && oclogstream != NULL) { + fclose(oclogstream); + oclogstream = NULL; + if(oclogfile != NULL) free(oclogfile); + oclogfile = NULL; + } +} + +void +oc_log(int tag, const char* fmt, ...) +{ + va_list args; + char* prefix; + if(!oclogging || oclogstream == NULL) return; + + switch (tag) { + case LOGWARN: prefix = "Warning:"; break; + case LOGERR: prefix = "Error: "; break; + case LOGNOTE: prefix = "Note: "; break; + case LOGDBG: prefix = "Debug: "; break; + default: + fprintf(oclogstream,"Error: Bad log prefix: %d\n",tag); + prefix = "Error: "; + break; + } + fprintf(oclogstream,"%s:",prefix); + + if(fmt != NULL) { + va_start(args, fmt); + vfprintf(oclogstream, fmt, args); + va_end( args ); + } + fprintf(oclogstream, "\n" ); + fflush(oclogstream); +} + +void +oc_logtext(int tag, const char* text) +{ + char line[1024]; + size_t delta = 0; + const char* eol = text; + + if(!oclogging || oclogstream == NULL) return; + + while(*text) { + eol = strchr(text,'\n'); + if(eol == NULL) + delta = strlen(text); + else + delta = (eol - text); + if(delta > 0) memcpy(line,text,delta); + line[delta] = '\0'; + fprintf(oclogstream," %s\n",line); + text = eol+1; + } +} diff --git a/extern/src_netcdf4/oclog.h b/extern/src_netcdf4/oclog.h new file mode 100644 index 0000000000000000000000000000000000000000..0dd3707228fe60d77ab4340e29ee5c038c61dc8d --- /dev/null +++ b/extern/src_netcdf4/oclog.h @@ -0,0 +1,20 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCLOG_H +#define OCLOG_H + +#define LOGNOTE 0 +#define LOGWARN 1 +#define LOGERR 2 +#define LOGDBG 3 + +extern void oc_loginit(void); +extern void oc_setlogging(int tf); +extern void oc_logopen(const char* file); +extern void oc_logclose(void); + +extern void oc_log(int tag, const char* fmt, ...); +extern void oc_logtext(int tag, const char* text); + +#endif /*OCLOG_H*/ diff --git a/extern/src_netcdf4/ocnode.c b/extern/src_netcdf4/ocnode.c new file mode 100644 index 0000000000000000000000000000000000000000..27983fb0c52580bc975940b683c50b5186b1bfe6 --- /dev/null +++ b/extern/src_netcdf4/ocnode.c @@ -0,0 +1,757 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#include "ocinternal.h" +#include "ocdebug.h" + +static const unsigned int MAX_UINT = 0xffffffff; + +static OCerror occomputeskipdatar(OCstate*, OCnode*, ocoffset_t offset); +static int mergedas1(OCnode* dds, OCnode* das); +static int converttype(OCtype etype, char* value, char* memory); +static char* pathtostring(OClist* path, char* separator, int usecdfname); +static void computefullname(OCnode* node); + +/* Process ocnodes to fix various semantic issues*/ +void +occomputesemantics(OClist* ocnodes) +{ + unsigned int i; + OCASSERT((ocnodes != NULL)); + for(i=0;ioctype == OC_Dimension && node->dim.array != NULL) { + node->container = node->dim.array->container; + } + } +} + +void +occomputefullnames(OCnode* root) +{ + unsigned int i; + if(root->name != NULL) computefullname(root); + if(root->subnodes != NULL) { /* recurse*/ + for(i=0;isubnodes);i++) { + OCnode* node = (OCnode*)oclistget(root->subnodes,i); + occomputefullnames(node); + } + } +} + +static void +computefullname(OCnode* node) +{ + char* tmp; + char* fullname; + OClist* path; + + OCASSERT((node->name != NULL)); + path = oclistnew(); + occollectpathtonode(node,path); + tmp = pathtostring(path,PATHSEPARATOR,1); + if(tmp == NULL) { + fullname = nulldup(node->name); + } else { + fullname = tmp; + } + node->fullname = fullname; + oclistfree(path); +} + +/* Convert path to a string; leave off the dataset name*/ +static char* +pathtostring(OClist* path, char* separator, int usecdfname) +{ + int slen,i,len; + char* pathname; + if(path == NULL || (len = oclistlength(path))==0) return NULL; + for(slen=0,i=0;icontainer == NULL || node->name == NULL) continue; + slen += strlen(node->name); + } + slen += ((len-1)*strlen(separator)); + slen += 1; /* for null terminator*/ + pathname = (char*)ocmalloc(slen); + MEMCHECK(pathname,NULL); + pathname[0] = '\0'; + for(i=0;icontainer == NULL || node->name == NULL) continue; + if(strlen(pathname) > 0) strcat(pathname,separator); + strcat(pathname,node->name); + } + return pathname; +} + +/* Collect the set of nodes ending in "node"*/ +void +occollectpathtonode(OCnode* node, OClist* path) +{ + if(node == NULL) return; + occollectpathtonode(node->container,path); + oclistpush(path,(ocelem)node); +} + +OCnode* +ocmakenode(char* name, OCtype ptype, OCnode* root) +{ + OCnode* cdf = (OCnode*)ocmalloc(sizeof(OCnode)); + MEMCHECK(cdf,(OCnode*)NULL); + memset((void*)cdf,0,sizeof(OCnode)); + cdf->magic = OCMAGIC; + cdf->name = (name?nulldup(name):NULL); + cdf->octype = ptype; + cdf->array.dimensions = NULL; + cdf->root = root; + return cdf; +} + +OCattribute* +makeattribute(char* name, OCtype ptype, OClist* values) +{ + OCattribute* att = (OCattribute*)ocmalloc(sizeof(OCattribute)); /* ocmalloc zeros*/ + MEMCHECK(att,(OCattribute*)NULL); + att->name = nulldup(name); + att->etype = ptype; + att->nvalues = oclistlength(values); + att->values = NULL; + if(att->nvalues > 0) { + int i; + att->values = (char**)ocmalloc(sizeof(char*)*att->nvalues); + for(i=0;invalues;i++) + att->values[i] = nulldup((char*)oclistget(values,i)); + } + return att; +} + +static void +marklostattribute(OCnode* att) +{ + oc_log(LOGWARN,"Lost attribute: %s",att->name); +} + +void* +oclinearize(OCtype etype, unsigned int nstrings, char** strings) +{ + int i; + size_t typesize; + char* memp; + char* memory; + + if(nstrings == 0) return NULL; + typesize = octypesize(etype); + memory = (char*)ocmalloc(nstrings*typesize); + MEMCHECK(memory,NULL); + memp = memory; + for(i=0;i OC_BYTE_MAX || iv < OC_BYTE_MIN) {iv = OC_BYTE_MAX; outofrange = 1;} + *((signed char*)memory) = (signed char)iv; + break; + case OC_UByte: + if(sscanf(value,"%lu",&uiv) != 1) goto fail; + else if(uiv > OC_UBYTE_MAX) {uiv = OC_UBYTE_MAX; outofrange = 1;} + *((unsigned char*)memory) = (unsigned char)uiv; + break; + case OC_Int16: + if(sscanf(value,"%ld",&iv) != 1) goto fail; + else if(iv > OC_INT16_MAX || iv < OC_INT16_MIN) {iv = OC_INT16_MAX; outofrange = 1;} + *((signed short*)memory) = (signed short)iv; + break; + case OC_UInt16: + if(sscanf(value,"%lu",&uiv) != 1) goto fail; + else if(uiv > OC_UINT16_MAX) {uiv = OC_UINT16_MAX; outofrange = 1;} + *((unsigned short*)memory) = (unsigned short)uiv; + break; + case OC_Int32: + if(sscanf(value,"%ld",&iv) != 1) goto fail; + else if(iv > OC_INT32_MAX || iv < OC_INT32_MIN) {iv = OC_INT32_MAX; outofrange = 1;} + *((signed int*)memory) = (signed int)iv; + break; + case OC_UInt32: + if(sscanf(value,"%lu",&uiv) != 1) goto fail; + else if(uiv > OC_UINT32_MAX) {uiv = OC_UINT32_MAX; outofrange = 1;} + *((unsigned char*)memory) = (unsigned int)uiv; + break; +#ifdef HAVE_LONG_LONG_INT + case OC_Int64: + if(sscanf(value,"%lld",&llv) != 1) goto fail; + /*else if(iv > OC_INT64_MAX || iv < OC_INT64_MIN) goto fail;*/ + *((signed long long*)memory) = (signed long long)llv; + break; + case OC_UInt64: + if(sscanf(value,"%llu",&ullv) != 1) goto fail; + *((unsigned long long*)memory) = (unsigned long long)ullv; + break; +#endif + case OC_Float32: + if(sscanf(value,"%lf",&dv) != 1) goto fail; + *((float*)memory) = (float)dv; + break; + case OC_Float64: + if(sscanf(value,"%lf",&dv) != 1) goto fail; + *((double*)memory) = (double)dv; + break; + case OC_String: case OC_URL: + *((char**)memory) = nulldup(value); + break; + default: + goto fail; + } + if(outofrange) + oc_log(LOGWARN,"converttype range failure: %d: %s",etype,value); + return 1; +fail: + oc_log(LOGERR,"converttype bad value: %d: %s",etype,value); + return 0; +} + + +void +ocfreeroot(OCnode* root) +{ + OCtree* tree; + OCstate* state; + int i; + + if(root == NULL || root->tree == NULL) return; + + tree = root->tree; + /* Remove the root from the state->trees list */ + state = tree->state; + for(i=0;itrees);i++) { + OCnode* node = (OCnode*)oclistget(state->trees,i); + if(root == node) + oclistremove(state->trees,i); + } + /* Note: it is ok if state->trees does not contain this root */ + ocfreetree(tree); +} + +void +ocfreetree(OCtree* tree) +{ + if(tree == NULL) return; + ocfreenodes(tree->nodes); + ocfree(tree->constraint); + ocfree(tree->text); + if(tree->data.xdrs != NULL) { + xxdr_free(tree->data.xdrs); + } + ocfree(tree->data.filename); /* may be null */ + if(tree->data.file != NULL) fclose(tree->data.file); + ocfree(tree->data.memory); + ocfree(tree); +} + +void +ocfreenodes(OClist* nodes) +{ + unsigned int i,j; + for(i=0;iname); + ocfree(node->fullname); + while(oclistlength(node->att.values) > 0) { + char* value = (char*)oclistpop(node->att.values); + ocfree(value); + } + while(oclistlength(node->attributes) > 0) { + OCattribute* attr = (OCattribute*)oclistpop(node->attributes); + ocfree(attr->name); + /* If the attribute type is string, then we need to free them*/ + if(attr->etype == OC_String || attr->etype == OC_URL) { + char** strings = (char**)attr->values; + for(j=0;jnvalues;j++) {ocfree(*strings); strings++;} + } + ocfree(attr->values); + ocfree(attr); + } + if(node->array.dimensions != NULL) oclistfree(node->array.dimensions); + if(node->subnodes != NULL) oclistfree(node->subnodes); + if(node->att.values != NULL) oclistfree(node->att.values); + if(node->attributes != NULL) oclistfree(node->attributes); + ocfree(node); + } + oclistfree(nodes); +} + +/* +In order to be as compatible as possible with libdap, +we try to use the same algorithm for DAS->DDS matching. +As described there, the algorithm is as follows. + If the [attribute] name contains one or + more field separators then look for a [DDS]variable whose + name matches exactly. If the name contains no field separators then + the look first in the top level [of the DDS] and then in all subsequent + levels and return the first occurrence found. In general, this + searches constructor types in the order in which they appear + in the DDS, but there is no requirement that it do so. + + Note: If a dataset contains two constructor types which have field names + that are the same (say point.x and pair.x) one should use fully qualified + names to get each of those variables. +*/ + +int +ocddsdasmerge(OCstate* state, OCnode* dasroot, OCnode* ddsroot) +{ + OClist* dasglobals = oclistnew(); + OClist* dasnodes = oclistnew(); + OClist* varnodes = oclistnew(); + OClist* ddsnodes; + unsigned int i,j; + + if(dasroot->tree == NULL || dasroot->tree->dxdclass != OCDAS) + return OCTHROW(OC_EINVAL); + if(ddsroot->tree == NULL || (ddsroot->tree->dxdclass != OCDDS + && ddsroot->tree->dxdclass != OCDATADDS)) + return OCTHROW(OC_EINVAL); + + ddsnodes = ddsroot->tree->nodes; + + /* 1. collect all the relevant DAS nodes; + namely those that contain at least one + attribute value. + Simultaneously look for potential ambiguities + if found; complain but continue: result are indeterminate. + also collect globals separately*/ + for(i=0;itree->nodes);i++) { + OCnode* das = (OCnode*)oclistget(dasroot->tree->nodes,i); + int hasattributes = 0; + if(das->octype == OC_Attribute) continue; /* ignore these for now*/ + if(das->name == NULL || das->att.isglobal) { + oclistpush(dasglobals,(ocelem)das); + continue; + } + for(j=0;jsubnodes);j++) { + OCnode* subnode = (OCnode*)oclistget(das->subnodes,j); + if(subnode->octype == OC_Attribute) {hasattributes = 1; break;} + } + if(hasattributes) { + /* Look for previously collected nodes with same name*/ + for(j=0;jname == NULL || das2->name == NULL) continue; + if(strcmp(das->name,das2->name)==0) { + oc_log(LOGWARN,"oc_mergedas: potentially ambiguous DAS name: %s",das->name); + } + } + oclistpush(dasnodes,(ocelem)das); + } + } + + /* 2. collect all the leaf DDS nodes (of type OC_Primitive)*/ + for(i=0;ioctype == OC_Primitive) oclistpush(varnodes,(ocelem)dds); + } + + /* 3. For each das node, locate matching DDS node(s) and attach + attributes to the DDS node(s). + Match means: + 1. DAS->fullname :: DDS->fullname + 2. DAS->name :: DDS->fullname (support DAS names with embedded '.' + 3. DAS->name :: DDS->name + */ + for(i=0;ifullname,dds->fullname)==0 + || strcmp(das->name,dds->fullname)==0 + || strcmp(das->name,dds->name)==0) { + mergedas1(dds,das); + /* remove from dasnodes list*/ + oclistset(dasnodes,i,(ocelem)NULL); + } + } + } + + /* 4. If there are attributes left, then complain about them being lost.*/ + for(i=0;iattributes == NULL) dds->attributes = oclistnew(); + /* assign the simple attributes in the das set to this dds node*/ + for(i=0;isubnodes);i++) { + OCnode* attnode = (OCnode*)oclistget(das->subnodes,i); + if(attnode->octype == OC_Attribute) { + OCattribute* att = makeattribute(attnode->name, + attnode->etype, + attnode->att.values); + oclistpush(dds->attributes,(ocelem)att); + } + } + return OCTHROW(stat); +} + + + +#ifdef OCIGNORE + +int +ocddsdasmerge(OCstate* state, OCnode* ddsroot, OCnode* dasroot) +{ + int i,j; + int stat = OC_NOERR; + OClist* globals = oclistnew(); + if(dasroot == NULL) return OCTHROW(stat); + /* Start by looking for global attributes*/ + for(i=0;isubnodes);i++) { + OCnode* node = (OCnode*)oclistget(dasroot->subnodes,i); + if(node->att.isglobal) { + for(j=0;jsubnodes);j++) { + OCnode* attnode = (OCnode*)oclistget(node->subnodes,j); + Attribute* att = makeattribute(attnode->name, + attnode->etype, + attnode->att.values); + oclistpush(globals,(ocelem)att); + } + } + } + ddsroot->attributes = globals; + /* Now try to match subnode names with attribute set names*/ + for(i=0;isubnodes);i++) { + OCnode* das = (OCnode*)oclistget(dasroot->subnodes,i); + int match = 0; + if(das->att.isglobal) continue; + if(das->octype == OC_Attributeset) { + for(j=0;jsubnodes) && !match;j++) { + OCnode* dds = (OCnode*)oclistget(ddsroot->subnodes,j); + if(strcmp(das->name,dds->name) == 0) { + match = 1; + stat = mergedas1(dds,das); + if(stat != OC_NOERR) break; + } + } + } + if(!match) {marklostattribute(das);} + } + if(stat == OC_NOERR) ddsroot->attributed = 1; + return OCTHROW(stat); +} + +/* Merge das attributes into the dds node*/ + +static int +mergedas1(OCnode* dds, OCnode* das) +{ + int i,j; + int stat = OC_NOERR; + if(dds->attributes == NULL) dds->attributes = oclistnew(); + /* assign the simple attributes in the das set to this dds node*/ + for(i=0;isubnodes);i++) { + OCnode* attnode = (OCnode*)oclistget(das->subnodes,i); + if(attnode->octype == OC_Attribute) { + Attribute* att = makeattribute(attnode->name, + attnode->etype, + attnode->att.values); + oclistpush(dds->attributes,(ocelem)att); + } + } + /* Try to merge any enclosed sets with subnodes of dds*/ + for(i=0;isubnodes);i++) { + OCnode* dasnode = (OCnode*)oclistget(das->subnodes,i); + int match = 0; + if(dasnode->octype == OC_Attribute) continue; /* already dealt with above*/ + for(j=0;jsubnodes) && !match;j++) { + OCnode* ddsnode = (OCnode*)oclistget(dds->subnodes,j); + if(strcmp(dasnode->name,ddsnode->name) == 0) { + match = 1; + stat = mergedas1(ddsnode,dasnode); + if(stat != OC_NOERR) break; + } + } + if(!match) {marklostattribute(dasnode);} + } + return OCTHROW(stat); +} +#endif + +static void +ocuncorrelate(OCnode* root) +{ + OCtree* tree = root->tree; + unsigned int i; + if(tree == NULL) return; + for(i=0;inodes);i++) { + OCnode* node = (OCnode*)oclistget(tree->nodes,i); + node->datadds = NULL; + } +} + +static OCerror +occorrelater(OCnode* dds, OCnode* dxd) +{ + int i,j; + OCerror ocstat = OC_NOERR; + + if(dds->octype != dxd->octype) { + OCTHROWCHK((ocstat = OC_EINVAL)); goto fail; + } + if(dxd->name != NULL && dxd->name != NULL + && strcmp(dxd->name,dds->name) != 0) { + OCTHROWCHK((ocstat = OC_EINVAL)); goto fail; + } else if(dxd->name != dxd->name) { /* test NULL==NULL */ + OCTHROWCHK((ocstat = OC_EINVAL)); goto fail; + } + + if(dxd->array.rank != dds->array.rank) { + OCTHROWCHK((ocstat = OC_EINVAL)); goto fail; + } + + dds->datadds = dxd; + + switch (dds->octype) { + case OC_Dataset: + case OC_Structure: + case OC_Grid: + case OC_Sequence: + /* Remember: there may be fewer datadds fields than dds fields */ + for(i=0;isubnodes);i++) { + OCnode* dxd1 = (OCnode*)oclistget(dxd->subnodes,i); + for(j=0;jsubnodes);j++) { + OCnode* dds1 = (OCnode*)oclistget(dds->subnodes,j); + if(strcmp(dxd1->name,dds1->name) == 0) { + ocstat = occorrelater(dds1,dxd1); + if(ocstat != OC_NOERR) {OCTHROWCHK(ocstat); goto fail;} + break; + } + } + } + break; + case OC_Dimension: + case OC_Primitive: + break; + default: OCPANIC1("unexpected node type: %d",dds->octype); + } + /* Correlate the dimensions */ + if(dds->array.rank > 0) { + for(i=0;isubnodes);i++) { + OCnode* ddsdim = (OCnode*)oclistget(dds->array.dimensions,i); + OCnode* dxddim = (OCnode*)oclistget(dxd->array.dimensions,i); + ocstat = occorrelater(ddsdim,dxddim); + if(!ocstat) goto fail; + } + } + +fail: + return OCTHROW(ocstat); + +} + +OCerror +occorrelate(OCnode* dds, OCnode* dxd) +{ + if(dds == NULL || dxd == NULL) return OC_EINVAL; + ocuncorrelate(dds); + return occorrelater(dds,dxd); +} + +/* +Mark cacheable those primitive String/URL typed nodes +that are contained only in structures with rank > 0. +*/ +void +ocmarkcacheable(OCstate* state, OCnode* ddsroot) +{ + int i,j; +#ifdef OCIGNORE + int ok; +#endif + OClist* treenodes = ddsroot->tree->nodes; + OClist* path = oclistnew(); + for(i=0;ioctype != OC_Primitive) continue; + if(node->etype != OC_String && node->etype != OC_URL) continue; + /* collect node path */ + oclistclear(path); + occollectpathtonode(node,path); +#ifdef OCIGNORE + ok = 1; +#endif + for(j=1;joctype != OC_Structure + || pathnode->array.rank > 0) { +#ifdef OCIGNORE + ok=0; +#endif + break; + } + } +#ifdef OCIGNORE + if(ok) { + node->cache.cacheable = 1; + node->cache.valid = 0; + } +#endif + } + oclistfree(path); +} + + +/* +Fill in the OCnode.skip fields +*/ +OCerror +occomputeskipdata(OCstate* state, OCnode* ddsroot) +{ + OCerror stat = OC_NOERR; + OCASSERT(ddsroot->octype == OC_Dataset); + stat = occomputeskipdatar(state,ddsroot,0); + return stat; +} + +/* Recursive helper for computeskipdata */ +static OCerror +occomputeskipdatar(OCstate* state, OCnode* xnode, ocoffset_t offset) +{ + OCerror stat = OC_NOERR; + int i,nfields; + int scalar = 0; + ocoffset_t instancesize = 0; + ocoffset_t totalsize = 0; + + scalar = (xnode->array.rank == 0 ? 1 : 0); + + /* Set skip count and offset*/ + if(xnode->octype == OC_Sequence) + xnode->skip.count = OCINDETERMINATE; + else + xnode->skip.count = totaldimsize(xnode); + + xnode->skip.offset = offset; /* possibly overridden below */ + + switch (xnode->octype) { + + case OC_Primitive: + switch(xnode->etype) { + case OC_String: case OC_URL: + instancesize = OCINDETERMINATE; + totalsize = OCINDETERMINATE; + break; + case OC_Char: case OC_Byte: case OC_UByte: + if(!scalar) {/*=>packed*/ + instancesize = octypesize(xnode->etype); + totalsize = instancesize * xnode->skip.count; + totalsize = RNDUP(totalsize); + totalsize += 2*XDRUNIT; /* overhead is double count */ + break; + } + /* !packed => singleton char object */ + /* fall thru */ + case OC_Int16: case OC_UInt16: + case OC_Int32: case OC_UInt32: + case OC_Int64: case OC_UInt64: + case OC_Float32: case OC_Float64: + instancesize = octypesize(xnode->etype); + instancesize = RNDUP(instancesize); /* make multiple of XDRUNIT */ + totalsize = (instancesize*xnode->skip.count); /* overhead is double count */ + if(!scalar) + totalsize += 2*XDRUNIT; /* overhead is double count */ + break; + + default: + OCPANIC("unexpected etype"); /* better not happen */ + } + break; + + case OC_Sequence: + offset = (xnode->skip.offset = OCINDETERMINATE); /* do not know field offsets for arbitrary record */ + case OC_Dataset: + case OC_Grid: + case OC_Structure: + /* Compute size of each field and sum */ + nfields = oclistlength(xnode->subnodes); + instancesize = 0; /* of structure as a whole */ + for(i=0;isubnodes,i); + ocoffset_t fieldsize; + if(offset == OCINDETERMINATE || instancesize == OCINDETERMINATE) + stat = occomputeskipdatar(state,subnode,OCINDETERMINATE); + else + stat = occomputeskipdatar(state,subnode,offset+instancesize); + if(stat != OC_NOERR) goto done; + fieldsize = subnode->skip.totalsize; + if(instancesize == OCINDETERMINATE || fieldsize == OCINDETERMINATE) + instancesize = OCINDETERMINATE; + else + instancesize += fieldsize; + } + if(instancesize != OCINDETERMINATE) { + instancesize = RNDUP(instancesize); /* make multiple of XDRUNIT */ + totalsize = (instancesize*xnode->skip.count); /* overhead is single count */ + if(!scalar) + totalsize += XDRUNIT; /* overhead is single count */ + } else { + totalsize = OCINDETERMINATE; + } + if(xnode->octype == OC_Sequence) { + totalsize = OCINDETERMINATE; + offset = OCINDETERMINATE; + } + break; + + default: OCPANIC("unexpected octype"); /* better not happen */ + } + + xnode->skip.offset = offset; + xnode->skip.instancesize = instancesize; + xnode->skip.totalsize = totalsize; + +done: + return stat; +} diff --git a/extern/src_netcdf4/ocnode.h b/extern/src_netcdf4/ocnode.h new file mode 100644 index 0000000000000000000000000000000000000000..544b9ea9021596816f503b6834ac13dd873f7972 --- /dev/null +++ b/extern/src_netcdf4/ocnode.h @@ -0,0 +1,81 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCNODE_H +#define OCNODE_H + +/*! Specifies the Diminfo. */ +/* Track info purely about declared dimensions. + More information is included in the Dimdata structure (dim.h) +*/ +typedef struct OCdiminfo { + struct OCnode* array; /* defining array node (if known)*/ + unsigned int arrayindex;/* rank position ofthis dimension in the array*/ + ocindex_t declsize; /* from DDS*/ +} OCdiminfo; + +/*! Specifies the Arrayinfo.*/ +typedef struct OCarrayinfo { + /* The complete set of dimension info applicable to this node*/ + OClist* dimensions; + /* convenience (because they are computed so often*/ + unsigned int rank; /* == |dimensions|*/ +} OCarrayinfo; + +/*! Specifies Attribute info */ +typedef struct OCattribute { + char* name; + OCtype etype; /* type of the attribute */ + size_t nvalues; + char** values; /* |values| = nvalues*sizeof(char**)*/ +} OCattribute; + +/*! Specifies the Attinfo.*/ +/* This is the form as it comes out of the DAS parser*/ +typedef struct OCattinfo { + int isglobal; /* is this supposed to be a global attribute set?*/ + OClist* values; /* oclist*/ +} OCattinfo; + +/*! Specifies the OCnode. */ +typedef struct OCnode { + unsigned int magic; + OCtype octype; + OCtype etype; /* essentially the dap type from the dds*/ + char* name; + char* fullname; + struct OCnode* container; /* this node is subnode of container */ + struct OCnode* root; /* root node of tree containing this node */ + struct OCtree* tree; /* !NULL iff this is a root node */ + struct OCnode* datadds; /* correlated datadds node, if any */ + OCdiminfo dim; /* octype == OC_Dimension*/ + OCarrayinfo array; /* octype == {OC_Structure, OC_Primitive}*/ + OCattinfo att; /* octype == OC_Attribute */ + /* primary edge info*/ + OClist* subnodes; /*oclist*/ + /*int attributed;*/ /* 1 if merge was done*/ + OClist* attributes; /* oclist*/ + struct OCSKIP {/* Support fast skipping ; in following, 0 => undefined */ + ocindex_t count; /* no. instances (== dimension cross product); may be indeterminate*/ + ocoffset_t instancesize;/*size of single instance; may be indeterminate*/ + ocoffset_t totalsize; /* usually: count*instancesize + overhead; may be indeterminate */ + ocoffset_t offset; /* mostly for debugging */ + } skip; +#ifdef OCIGNORE + struct {/* do simple index cache */ + int cacheable; /* is this object cacheable? */ + int valid; /* is this cache valid */ + ocindex_t index; /* last index */ + ocoffset_t offset; /* position of the last indexed instance */ + } cache; +#endif +} OCnode; + +#if SIZEOF_SIZE_T == 4 +#define OCINDETERMINATE ((size_t)0xffffffff) +#endif +#if SIZEOF_SIZE_T == 8 +#define OCINDETERMINATE ((size_t)0xffffffffffffffff) +#endif + +#endif /*OCNODE_H*/ diff --git a/extern/src_netcdf4/ocrc.c b/extern/src_netcdf4/ocrc.c new file mode 100644 index 0000000000000000000000000000000000000000..27465e67cb703d23ce5f9702ab6b007db8aa951d --- /dev/null +++ b/extern/src_netcdf4/ocrc.c @@ -0,0 +1,548 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +#include "ocinternal.h" +#include "ocdebug.h" +#include "ocdata.h" +#include "occontent.h" +#include "oclog.h" + +#include "ocrc.h" + +#define RTAG ']' +#define LTAG '[' + +#define TRIMCHARS " \t\r\n" + +#define TRIM(x) rctrimright(rctrimleft((x),TRIMCHARS),TRIMCHARS) + +#define HTTPPREFIXDEPRECATED "CURL." +#define HTTPPREFIX "HTTP." + +/* the .dodsrc triple store */ +struct OCTriplestore* ocdodsrc = NULL; + +static int parseproxy(OCstate* state, char* v); +static int rcreadline(FILE* f, char* more, int morelen); +static char* rctrimright(char* more, char* trimchars); +static char* rctrimleft(char* more, char* trimchars); + +static void ocdodsrcdump(char* msg, struct OCTriple*, int ntriples); + +static char* curllookup(char* suffix,char* url); + +/* The Username and password are in the URL if the URL is of the form: + * http://:@/.... + */ +int +occredentials_in_url(const char *url) +{ + char *pos = strstr(url, "http://"); + if (!pos) + return 0; + pos += 7; + if (strchr(pos, '@') && strchr(pos, ':')) + return 1; + + return 0; +} + +int +ocextract_credentials(const char *url, char **name, char **pw, char **result_url) +{ + char *pos; + char *end; + char *middle; + int up_len = 0; + int mid_len = 0; + int midpas_len = 0; + int url_len = 0; + + if (strchr(url, '@')) { + pos = strstr(url, "http://"); + if (pos) + pos += 7; + middle = strchr(pos, ':'); + mid_len = middle - pos; + *name = malloc(sizeof(char) * (mid_len + 1)); + strncpy(*name, pos, mid_len); + (*name)[mid_len] = '\0'; + + if (middle) + middle += 1; + + end = strchr(middle, '@'); + midpas_len = end - middle; + *pw = malloc(sizeof(char) * (midpas_len + 1)); + strncpy(*pw, middle, midpas_len); + (*pw)[midpas_len] = '\0'; + + up_len = end - pos; + url_len = strlen(url) - up_len; + + *result_url = malloc(sizeof(char) * (url_len + 1)); + if (!result_url) + return OC_ENOMEM; + + strncpy(*result_url, url, pos - url); + strncpy(*result_url + (pos - url), end + 1, url_len - (pos - url)); + +#if 0 + fprintf(stderr, "URL without username and password: %s:%d\n", sURL, url_len ); + fprintf(stderr, "URL username and password: %s:%d\n", sUP, up_len); + fprintf(stderr, "URL username: %s:%d\n", sUser, mid_len); + fprintf(stderr, "URL password: %s:%d\n", sPassword, midpas_len); +#endif + (*result_url)[url_len] = '\0'; + + return OC_NOERR; + } + else { + return OC_EIO; + } +} + +static int +rcreadline(FILE* f, char* more, int morelen) +{ + int i = 0; + int c = getc(f); + if(c < 0) return 0; + for(;;) { + if(i < morelen) /* ignore excess characters */ + more[i++]=c; + c = getc(f); + if(c < 0) break; /* eof */ + if(c == '\n') break; /* eol */ + } + /* null terminate more */ + more[i] = '\0'; + return 1; +} + +/* Trim specified characters from front/left */ +static char* +rctrimleft(char* more, char* trimchars) +{ + char* p = more; + int c; + while((c=*p) != '\0') {if(strchr(trimchars,c) != NULL) p++; else break;} + return p; +} + +/* Trim specified characters from end/right */ +static char* +rctrimright(char* more, char* trimchars) +{ + int len = strlen(more); + char* p = more + (len - 1); + while(p != more) {if(strchr(trimchars,*p) != NULL) p--; else break;} + /* null terminate */ + p[1] = '\0'; + return more; +} + +static int +parseproxy(OCstate* state, char* v) +{ + char *host_pos = NULL; + char *port_pos = NULL; + + if(strlen(v) == 0) return OC_NOERR; /* nothing there*/ + if (occredentials_in_url(v)) { + char *result_url = NULL; + ocextract_credentials(v, &state->creds.username, + &state->creds.password, + &result_url); + v = result_url; + } + /* allocating a bit more than likely needed ... */ + host_pos = strstr(v, "http://"); + if (host_pos) + host_pos += strlen("http://"); + else + host_pos = v; + port_pos = strchr(host_pos, ':'); + if (port_pos) { + int host_len; + char *port_sep = port_pos; + port_pos++; + *port_sep = '\0'; + host_len = strlen(host_pos); + state->proxy.host = malloc(sizeof(char) * host_len + 1); + if (!state->proxy.host) + return OC_ENOMEM; + + strncpy(state->proxy.host, host_pos, host_len); + state->proxy.host[host_len + 1] = '\0'; + + state->proxy.port = atoi(port_pos); + } else { + int host_len = strlen(host_pos); + state->proxy.host = malloc(sizeof(char) * host_len + 1); + if (!state->proxy.host) + return OC_ENOMEM; + + strncpy(state->proxy.host, host_pos, host_len); + state->proxy.host[host_len + 1] = '\0'; + + state->proxy.port = 80; + } +#if 0 + state->proxy.host[v_len] = '\0'; + state->proxy.port = atoi(v); + s_len = strlen(v); + state->proxy.user = malloc(sizeof(char) * s_len + 1); + if (!state->proxy.user) + return OC_ENOMEM; + strncpy(state->proxy.user, v, s_len); + state->proxy.user[s_len] = '\0'; + p_len = strlen(v); + state->proxy.password = malloc(sizeof(char) * p_len + 1); + if (!state->proxy.password) + return OC_ENOMEM; + strncpy(state->proxy.password, v, p_len); + state->proxy.password[p_len] = '\0'; +#endif /*0*/ + if (ocdebug > 1) { + oc_log(LOGNOTE,"host name: %s", state->proxy.host); + oc_log(LOGNOTE,"user name: %s", state->creds.username); +#ifdef INSECURE + oc_log(LOGNOTE,"password: %s", state->creds.password); +#endif + oc_log(LOGNOTE,"port number: %d", state->proxy.port); + } + if(v) free(v); + return OC_NOERR; +} + +/* insertion sort the triplestore based on url */ +static void +sorttriplestore(void) +{ + int i, nsorted; + struct OCTriple* sorted = NULL; + + if(ocdodsrc->ntriples <= 1) return; /* nothing to sort */ + if(ocdebug > 2) + ocdodsrcdump("initial:",ocdodsrc->triples,ocdodsrc->ntriples); + + sorted = (struct OCTriple*)malloc(sizeof(struct OCTriple)*ocdodsrc->ntriples); + if(sorted == NULL) { + oc_log(LOGERR,"sorttriplestore: out of memory"); + return; + } + + nsorted = 0; + while(nsorted < ocdodsrc->ntriples) { + int largest; + /* locate first non killed entry */ + for(largest=0;largestntriples;largest++) { + if(ocdodsrc->triples[largest].key[0] != '\0') break; + } + OCASSERT(ocdodsrc->triples[largest].key[0] != '\0'); + for(i=0;intriples;i++) { + if(ocdodsrc->triples[i].key[0] != '\0') { /* avoid empty slots */ + int lexorder = strcmp(ocdodsrc->triples[i].url,ocdodsrc->triples[largest].url); + int leni = strlen(ocdodsrc->triples[i].url); + int lenlarge = strlen(ocdodsrc->triples[largest].url); + /* this defines the ordering */ + if(leni == 0 && lenlarge == 0) continue; /* if no urls, then leave in order */ + if(leni != 0 && lenlarge == 0) largest = i; + else if(lexorder > 0) largest = i; + } + } + /* Move the largest entry */ + OCASSERT(ocdodsrc->triples[largest].key[0] != 0); + sorted[nsorted] = ocdodsrc->triples[largest]; + ocdodsrc->triples[largest].key[0] = '\0'; /* kill entry */ + nsorted++; + if(ocdebug > 2) + ocdodsrcdump("pass:",sorted,nsorted); + } + + memcpy((void*)ocdodsrc->triples,(void*)sorted,sizeof(struct OCTriple)*nsorted); + free(sorted); + + if(ocdebug > 0) + ocdodsrcdump("final .dodsrc order:",ocdodsrc->triples,ocdodsrc->ntriples); +} + +/* Create a triple store from a file */ +int +ocdodsrc_read(char* basename, char* path) +{ + char line0[MAXRCLINESIZE]; + FILE *in_file = NULL; + int linecount = 0; + + if(ocdodsrc == NULL) { + ocdodsrc = (struct OCTriplestore*)malloc(sizeof(struct OCTriplestore)); + if(ocdodsrc == NULL) { + oc_log(LOGERR,"ocdodsrc_read: out of memory"); + return 0; + } + } + ocdodsrc->ntriples = 0; + + in_file = fopen(path, "r"); /* Open the file to read it */ + if (in_file == NULL) { + oc_log(LOGERR, "Could not open configuration file: %s",basename); + return OC_EPERM; + } + + for(;;) { + char *line,*key,*value; + if(!rcreadline(in_file,line0,sizeof(line0))) break; + linecount++; + if(linecount >= MAXRCLINES) { + oc_log(LOGERR, ".dodsrc has too many lines"); + return 0; + } + line = line0; + /* check for comment */ + if (line[0] == '#') continue; + /* trim leading blanks */ + line = rctrimleft(line,TRIMCHARS); + if(strlen(line) >= MAXRCLINESIZE) { + oc_log(LOGERR, "%s line too long: %s",basename,line0); + return 0; + } + /* parse the line */ + ocdodsrc->triples[ocdodsrc->ntriples].url[0] = '\0'; /*assume no url*/ + if(line[0] == LTAG) { + char* url = ++line; + char* rtag = strchr(line,RTAG); + if(rtag == NULL) { + oc_log(LOGERR, "Malformed [url] in %s entry: %s",basename,line); + continue; + } + line = rtag + 1; + *rtag = '\0'; + /* trim again */ + line = rctrimleft(line,TRIMCHARS); + /* save the url */ + strcpy(ocdodsrc->triples[ocdodsrc->ntriples].url,TRIM(url)); + } + if(strlen(line)==0) continue; /* empty line */ + /* split off key and value */ + key=line; + value = strchr(line, '='); + if(value == NULL) { + /* add fake '=1' */ + if(strlen(line) + strlen("=1") >= MAXRCLINESIZE) { + oc_log(LOGERR, "%s entry too long: %s",basename,line); + continue; + } + strcat(line,"=1"); + value = strchr(line,'='); + } + *value = '\0'; + value++; + strcpy(ocdodsrc->triples[ocdodsrc->ntriples].key,TRIM(key)); + strcpy(ocdodsrc->triples[ocdodsrc->ntriples].value,TRIM(value)); + ocdodsrc->ntriples++; + } + fclose(in_file); + sorttriplestore(); + return 1; +} + + +int +ocdodsrc_process(OCstate* state) +{ + int stat = 0; + char* value; + char* url = ocuribuild(state->uri,NULL,NULL,OCURIENCODE); + if(ocdodsrc == NULL) goto done; + value = curllookup("DEFLATE",url); + if(value != NULL) { + if(atoi(value)) state->curlflags.compress = 1; + if(ocdebug > 0) + oc_log(LOGNOTE,"Compression: %ld", state->curlflags.compress); + } + if((value = curllookup("VERBOSE",url)) != NULL) { + if(atoi(value)) state->curlflags.verbose = 1; + if(ocdebug > 0) + oc_log(LOGNOTE,"curl.verbose: %ld", state->curlflags.verbose); + } + if((value = curllookup("TIMEOUT",url)) != NULL) { + if(atoi(value)) state->curlflags.timeout = atoi(value); + if(ocdebug > 0) + oc_log(LOGNOTE,"curl.timeout: %ld", state->curlflags.timeout); + } + + if((value = curllookup("COOKIEFILE",url)) != NULL) { + state->curlflags.cookiefile = strdup(TRIM(value)); + if(!state->curlflags.cookiefile) {stat = OC_ENOMEM; goto done;} + if(ocdebug > 0) + oc_log(LOGNOTE,"COOKIEFILE: %s", state->curlflags.cookiefile); + } + if((value = curllookup("COOKIEJAR",url)) + || (value = curllookup("COOKIE_JAR",url))) { + state->curlflags.cookiejar = strdup(TRIM(value)); + if(!state->curlflags.cookiejar) {stat = OC_ENOMEM; goto done;} + if(ocdebug > 0) + oc_log(LOGNOTE,"COOKIEJAR: %s", state->curlflags.cookiejar); + } + + /* Some servers (e.g. thredds) appear to require a place + to put cookies in order for some security functions to work + */ + if(state->curlflags.cookiejar == NULL + && state->curlflags.cookiefile == NULL) { + state->curlflags.cookiefile = strdup(""); + } + + if((value = curllookup("PROXY_SERVER",url)) != NULL) { + stat = parseproxy(state,TRIM(value)); + if(stat != OC_NOERR) goto done; + } + + if((value = curllookup("SSL.VALIDATE",url)) != NULL) { + if(atoi(value)) state->ssl.validate = 1; + if(ocdebug > 0) + oc_log(LOGNOTE,"CURL.SSL.VALIDATE: %ld", state->ssl.validate); + } + + if((value = curllookup("SSL.CERTIFICATE",url)) != NULL) { + state->ssl.certificate = strdup(TRIM(value)); + if(!state->ssl.certificate) {stat = OC_ENOMEM; goto done;} + if(ocdebug > 0) + oc_log(LOGNOTE,"CREDENTIALS.SSL.CERTIFICATE: %s", state->ssl.certificate); + } + + if((value = curllookup("SSL.KEY",url)) != NULL) { + state->ssl.key = strdup(TRIM(value)); + if(!state->ssl.key) {stat = OC_ENOMEM; goto done;} + if(ocdebug > 0) + oc_log(LOGNOTE,"CREDENTIALS.SSL.KEY: %s", state->ssl.key); + } + + if((value = curllookup("SSL.KEYPASSWORD",url)) != NULL) { + state->ssl.keypasswd = strdup(TRIM(value)); + if(!state->ssl.keypasswd) {stat = OC_ENOMEM; goto done;} +#ifdef INSECURE + if(ocdebug > 0) + oc_log(LOGNOTE,"CREDENTIALS.SSL.KEYPASSWORD: %s", state->ssl.keypasswd); +#endif + } + + if((value = curllookup("SSL.CAINFO",url)) != NULL) { + state->ssl.cainfo = strdup(TRIM(value)); + if(!state->ssl.cainfo) {stat = OC_ENOMEM; goto done;} + if(ocdebug > 0) + oc_log(LOGNOTE,"SSL.CAINFO: %s", state->ssl.cainfo); + } + + if((value = curllookup("SSL.CAPATH",url)) != NULL) { + state->ssl.capath = strdup(TRIM(value)); + if(!state->ssl.capath) {stat = OC_ENOMEM; goto done;} + if(ocdebug > 0) + oc_log(LOGNOTE,"SSL.CAPATH: %s", state->ssl.capath); + } + + if((value = curllookup("SSL.VERIFYPEER",url)) != NULL) { + char* s = strdup(TRIM(value)); + int tf = 0; + if(s == NULL || strcmp(s,"0")==0 || strcasecmp(s,"false")==0) + tf = 0; + else if(strcmp(s,"1")==0 || strcasecmp(s,"true")==0) + tf = 1; + else + tf = 1; /* default if not null */ + state->ssl.verifypeer = tf; + if(ocdebug > 0) + oc_log(LOGNOTE,"SSL.VERIFYPEER: %d", state->ssl.verifypeer); + } + + if((value = curllookup("CREDENTIALS.USER",url)) != NULL) { + state->creds.username = strdup(TRIM(value)); + if(!state->creds.username) {stat = OC_ENOMEM; goto done;} + if(ocdebug > 0) + oc_log(LOGNOTE,"CREDENTIALS.USER: %s", state->creds.username); + } + + if((value = curllookup("CREDENTIALS.PASSWORD",url)) != NULL) { + state->creds.password = strdup(TRIM(value)); + if(!state->creds.password) {stat = OC_ENOMEM; goto done;} + } + /* else ignore */ + +done: + if(url != NULL) free(url); + return stat; +} + +char* +ocdodsrc_lookup(char* key, char* url) +{ + int i,found; + struct OCTriple* triple = ocdodsrc->triples; + if(key == NULL || ocdodsrc == NULL) return NULL; + if(url == NULL) url = ""; + /* Assume that the triple store has been properly sorted */ + for(found=0,i=0;intriples;i++,triple++) { + int triplelen = strlen(triple->url); + int t; + if(strcmp(key,triple->key) != 0) continue; /* keys do not match */ + /* If the triple entry has no url, then use it (because we have checked all other cases)*/ + if(triplelen == 0) {found=1;break;} + /* do url prefix comparison */ + t = ocstrncmp(url,triple->url,triplelen); + if(t == 0) {found=1; break;} + } + if(ocdebug > 2) + { + if(found) { + fprintf(stderr,"lookup %s: [%s]%s = %s\n",url,triple->url,triple->key,triple->value); + } + } + return (found ? triple->value : NULL); +} + + +static void +ocdodsrcdump(char* msg, struct OCTriple* triples, int ntriples) +{ + int i; + if(msg != NULL) fprintf(stderr,"%s\n",msg); + if(ocdodsrc == NULL) { + fprintf(stderr,"\n"); + return; + } + if(triples == NULL) triples= ocdodsrc->triples; + if(ntriples < 0 ) ntriples= ocdodsrc->ntriples; + for(i=0;i +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#ifdef HAVE_NETINET_IN_H +#include +#endif +#include "ocinternal.h" +#include "ocdebug.h" +#include "ochttp.h" +#include "ocread.h" +#include "ocrc.h" +#include "occurlfunctions.h" + +extern int oc_curl_file_supported; + +/*Forward*/ +static int readpacket(CURL*, OCURI*, OCbytes*, OCdxd, long*); +static int readfile(char* path, char* suffix, OCbytes* packet); +static int readfiletofile(char* path, char* suffix, FILE* stream, unsigned long*); + +int +readDDS(OCstate* state, OCtree* tree) +{ + int stat = OC_NOERR; + long lastmodified = -1; + + + ocurisetconstraints(state->uri,tree->constraint); + +ocset_user_password(state); + + stat = readpacket(state->curl,state->uri,state->packet,OCDDS, + &lastmodified); + if(stat == OC_NOERR) state->ddslastmodified = lastmodified; + + return stat; +} + +int +readDAS(OCstate* state, OCtree* tree) +{ + int stat = OC_NOERR; + + ocurisetconstraints(state->uri,tree->constraint); + stat = readpacket(state->curl,state->uri,state->packet,OCDAS,NULL); + + return stat; +} + +int +readversion(CURL* curl, OCURI* url, OCbytes* packet) +{ + return readpacket(curl,url,packet,OCVER,NULL); +} + +static +char* ocdxdextension[] ={ +".dds", /*OCDDS*/ +".das", /*OCDAS*/ +".dods", /*OCDATADDS*/ +".vers", /*OCVERS*/ +}; + +static int +readpacket(CURL* curl,OCURI* url,OCbytes* packet,OCdxd dxd,long* lastmodified) +{ + int stat = OC_NOERR; + int fileprotocol = 0; + char* suffix = ocdxdextension[dxd]; + char* fetchurl = NULL; + + fileprotocol = (strcmp(url->protocol,"file")==0); + + if(fileprotocol && !oc_curl_file_supported) { + /* Short circuit file://... urls*/ + /* We do this because the test code always needs to read files*/ + fetchurl = ocuribuild(url,NULL,NULL,0); + stat = readfile(fetchurl,suffix,packet); + } else { + int flags = 0; + if(!fileprotocol) flags |= OCURICONSTRAINTS; + flags |= OCURIENCODE; + fetchurl = ocuribuild(url,NULL,suffix,flags); + MEMCHECK(fetchurl,OC_ENOMEM); + if(ocdebug > 0) + {fprintf(stderr,"fetch url=%s\n",fetchurl); fflush(stderr);} + stat = ocfetchurl(curl,fetchurl,packet,lastmodified); + if(ocdebug > 0) + {fprintf(stderr,"fetch complete\n"); fflush(stderr);} + } + free(fetchurl); + return OCTHROW(stat); +} + +int +readDATADDS(OCstate* state, OCtree* tree, OCflags flags) +{ + int stat = OC_NOERR; + long lastmod = -1; + + if((flags & OCONDISK) == 0) { + ocurisetconstraints(state->uri,tree->constraint); + stat = readpacket(state->curl,state->uri,state->packet,OCDATADDS,&lastmod); + if(stat == OC_NOERR) + state->datalastmodified = lastmod; + tree->data.datasize = ocbyteslength(state->packet); + } else { + OCURI* url = state->uri; + int fileprotocol = 0; + char* readurl = NULL; + + fileprotocol = (strcmp(url->protocol,"file")==0); + + if(fileprotocol && !oc_curl_file_supported) { + readurl = ocuribuild(url,NULL,NULL,0); + stat = readfiletofile(readurl, ".dods", tree->data.file, &tree->data.datasize); + } else { + int flags = 0; + if(!fileprotocol) flags |= OCURICONSTRAINTS; + flags |= OCURIENCODE; + ocurisetconstraints(url,tree->constraint); + readurl = ocuribuild(url,NULL,".dods",flags); + MEMCHECK(readurl,OC_ENOMEM); + if (ocdebug > 0) + {fprintf(stderr, "fetch url=%s\n", readurl);fflush(stderr);} + stat = ocfetchurl_file(state->curl, readurl, tree->data.file, + &tree->data.datasize, &lastmod); + if(stat == OC_NOERR) + state->datalastmodified = lastmod; + if (ocdebug > 0) + {fprintf(stderr,"fetch complete\n"); fflush(stderr);} + } + free(readurl); + } + return OCTHROW(stat); +} + +static int +readfiletofile(char* path, char* suffix, FILE* stream, unsigned long* sizep) +{ + int stat = OC_NOERR; + OCbytes* packet = ocbytesnew(); + size_t len; + /* check for leading file:/// */ + if(ocstrncmp(path,"file:///",8)==0) path += 7; /* assume absolute path*/ + stat = readfile(path,suffix,packet); + if(stat != OC_NOERR) goto unwind; + len = oclistlength(packet); + if(stat == OC_NOERR) { + size_t written; + fseek(stream,0,SEEK_SET); + written = fwrite(ocbytescontents(packet),1,len,stream); + if(written != len) stat = OC_EIO; + } + if(sizep != NULL) *sizep = len; +unwind: + ocbytesfree(packet); + return OCTHROW(stat); +} + +static int +readfile(char* path, char* suffix, OCbytes* packet) +{ + int stat = OC_NOERR; + char buf[1024]; + char filename[1024]; + int count,size,fd; + /* check for leading file:/// */ + if(ocstrncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/ + strcpy(filename,path); + if(suffix != NULL) strcat(filename,suffix); + fd = open(filename,O_RDONLY); + if(fd < 0) { + oc_log(LOGERR,"open failed:%s",filename); + return OCTHROW(OC_EOPEN); + } + size=0; + stat = OC_NOERR; + for(;;) { + count = read(fd,buf,sizeof(buf)); + if(count <= 0) + break; + else if(count < 0) { + stat = OC_EIO; + oc_log(LOGERR,"read failed: %s",filename); + break; + } + ocbytesappendn(packet,buf,count); + size += count; + } + close(fd); + return OCTHROW(stat); +} + + diff --git a/extern/src_netcdf4/ocread.h b/extern/src_netcdf4/ocread.h new file mode 100644 index 0000000000000000000000000000000000000000..8f302ce924a2957e6afd71bbcb6293c7ad517bb6 --- /dev/null +++ b/extern/src_netcdf4/ocread.h @@ -0,0 +1,15 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef READ_H +#define READ_H + + +extern int readDDS(OCstate*, OCtree*); +extern int readDAS(OCstate*, OCtree*); + +extern int readDATADDS(OCstate*, OCtree*, int inmemory); + +extern int readversion(CURL*, OCURI*, OCbytes*); + +#endif /*READ_H*/ diff --git a/extern/src_netcdf4/ocuri.c b/extern/src_netcdf4/ocuri.c new file mode 100644 index 0000000000000000000000000000000000000000..8ef98721735c68c0fa26bd27b5ed220206bf201f --- /dev/null +++ b/extern/src_netcdf4/ocuri.c @@ -0,0 +1,737 @@ +/********************************************************************* + * Copyright 2010, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + * $Header$ + *********************************************************************/ + +#include "config.h" + +#include +#include +#include + +#include "oc.h" +#include "ocuri.h" + +#define OCURIDEBUG + +#define LBRACKET '[' +#define RBRACKET ']' + +#ifndef FIX +#define FIX(s) ((s)==NULL?"":(s)) +#endif + +#ifndef NILLEN +#define NILLEN(s) ((s)==NULL?0:strlen(s)) +#endif + +#ifdef HAVE_STRDUP +# ifndef nulldup +# define nulldup(s) ((s)==NULL?NULL:strdup(s)) +# endif +#endif + +#ifndef HAVE_STRDUP +static char* nulldup(char* s) +{ + char* dup = NULL; + if(s != NULL) { + dup = (char*)malloc(strlen(s)+1); + if(dup != NULL) + strcpy(dup,s); + } + return dup; +} +#endif + +#ifdef OCIGNORE +/* Not all systems have strndup, so provide one*/ +static char* +ocstrndup(const char* s, size_t len) +{ + char* dup; + if(s == NULL) return NULL; + dup = (char*)ocmalloc(len+1); + MEMCHECK(dup,NULL); + memcpy((void*)dup,s,len); + dup[len] = '\0'; + return dup; +} +#endif + +/* Do not trust strncmp */ +static int +ocuristrncmp(const char* s1, const char* s2, size_t len) +{ + const char *p,*q; + if(s1 == s2) return 0; + if(s1 == NULL) return -1; + if(s2 == NULL) return +1; + for(p=s1,q=s2;len > 0;p++,q++,len--) { + if(*p != *q) + return (*p - *q); + if(*p == 0) return 0; /* *p == *q == 0 */ + } + /* 1st len chars are same */ + return 0; +} + +static char* legalprotocols[] = { +"file:", +"http:", +"https:", +"ftp:", +NULL /* NULL terminate*/ +}; + +/* Allowable character sets for encode */ +static char* fileallow = +"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$&'()*+,-./:;=?@_~"; + +static char* queryallow = +"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$&'()*+,-./:;=?@_~"; + +static void ocparamfree(char** params); +static int ocfind(char** params, const char* key); + +/* Do a simple uri parse: return 0 if fail, 1 otherwise*/ +int +ocuriparse(const char* uri0, OCURI** ocurip) +{ + OCURI* ocuri = NULL; + char* uri; + char** pp; + char* p; + char* p1; + int c; + + /* accumulate parse points*/ + char* protocol = NULL; + char* params = NULL; + char* host = NULL; + char* port = NULL; + char* constraint = NULL; + char* user = NULL; + char* pwd = NULL; + char* file = NULL; + + if(uri0 == NULL) + return OC_EBADURL; + + ocuri = (OCURI*)calloc(1,sizeof(OCURI)); + if(ocuri == NULL) return 0; + + /* make local copy of uri */ + uri = nulldup(uri0); + + /* remove all whitespace*/ + p = uri; + p1 = uri; + while((c=*p1++)) {if(c != ' ' && c != '\t') *p++ = c;} + + p = uri; + + /* break up the uri string into pieces*/ + + /* 1. leading bracketed parameters */ + if(*p == LBRACKET) { + params = p+1; + /* find end of the clientparams*/ + for(;*p;p++) {if(p[0] == RBRACKET && p[1] != LBRACKET) break;} + if(*p == 0) goto fail; /* malformed client params*/ + *p = '\0'; /* leave off the trailing rbracket for now */ + p++; /* move past the params*/ + } + + /* verify that the uri starts with an acceptable protocol*/ + for(pp=legalprotocols;*pp;pp++) { + if(ocuristrncmp(p,*pp,strlen(*pp))==0) break; + } + if(*pp == NULL) goto fail; /* illegal protocol*/ + /* save the protocol */ + protocol = *pp; + + /* 4. skip protocol */ + p += strlen(protocol); + + /* 5. skip // */ + if(*p != '/' && *(p+1) != '/') + goto fail; + p += 2; + + /* 6. Mark the end of the host section */ + file = strchr(p,'/'); + if(file) { + *file++ = '\0'; /* warning: we just overwrote the leading / */ + } else + goto fail; + + /* 7. extract any user:pwd */ + p1 = strchr(p,'@'); + if(p1) {/* Assume we have user:pwd@ */ + *p1 = '\0'; + user = p; + pwd = strchr(p,':'); + if(!pwd) goto fail; /* malformed */ + *pwd++ = '\0'; + p = pwd+strlen(pwd)+1; + } + + /* 8. extract host and port */ + host = p; + port = strchr(p,':'); + if(port) { + *port++ = '\0'; + } + + /* 9. Look for '?' */ + constraint = strchr(file,'?'); + if(constraint) { + *constraint++ = '\0'; + } + + /* assemble the component pieces*/ + if(uri0 && strlen(uri0) > 0) + ocuri->uri = nulldup(uri0); + if(protocol && strlen(protocol) > 0) { + ocuri->protocol = nulldup(protocol); + /* remove trailing ':' */ + ocuri->protocol[strlen(protocol)-1] = '\0'; + } + if(user && strlen(user) > 0) + ocuri->user = nulldup(user); + if(pwd && strlen(pwd) > 0) + ocuri->password = nulldup(pwd); + if(host && strlen(host) > 0) + ocuri->host = nulldup(host); + if(port && strlen(port) > 0) + ocuri->port = nulldup(port); + if(file && strlen(file) > 0) { + /* Add back the leading / */ + ocuri->file = malloc(strlen(file)+2); + strcpy(ocuri->file,"/"); + strcat(ocuri->file,file); + } + if(constraint && strlen(constraint) > 0) + ocuri->constraint = nulldup(constraint); + ocurisetconstraints(ocuri,constraint); + if(params != NULL && strlen(params) > 0) { + ocuri->params = (char*)malloc(1+2+strlen(params)); + strcpy(ocuri->params,"["); + strcat(ocuri->params,params); + strcat(ocuri->params,"]"); + } + +#ifdef OCXDEBUG + { + fprintf(stderr,"ocuri:"); + fprintf(stderr," params=|%s|",FIX(ocuri->params)); + fprintf(stderr," protocol=|%s|",FIX(ocuri->protocol)); + fprintf(stderr," host=|%s|",FIX(ocuri->host)); + fprintf(stderr," port=|%s|",FIX(ocuri->port)); + fprintf(stderr," file=|%s|",FIX(ocuri->file)); + fprintf(stderr," constraint=|%s|",FIX(ocuri->constraint)); + fprintf(stderr,"\n"); + } +#endif + free(uri); + if(ocurip != NULL) *ocurip = ocuri; + return 1; + +fail: + if(ocuri) ocurifree(ocuri); + if(uri != NULL) free(uri); + return 0; +} + +void +ocurifree(OCURI* ocuri) +{ + if(ocuri == NULL) return; + if(ocuri->uri != NULL) {free(ocuri->uri);} + if(ocuri->protocol != NULL) {free(ocuri->protocol);} + if(ocuri->user != NULL) {free(ocuri->user);} + if(ocuri->password != NULL) {free(ocuri->password);} + if(ocuri->host != NULL) {free(ocuri->host);} + if(ocuri->port != NULL) {free(ocuri->port);} + if(ocuri->file != NULL) {free(ocuri->file);} + if(ocuri->constraint != NULL) {free(ocuri->constraint);} + if(ocuri->projection != NULL) {free(ocuri->projection);} + if(ocuri->selection != NULL) {free(ocuri->selection);} + if(ocuri->params != NULL) {free(ocuri->params);} + if(ocuri->paramlist != NULL) ocparamfree(ocuri->paramlist); + free(ocuri); +} + +/* Replace the constraints */ +void +ocurisetconstraints(OCURI* duri,const char* constraints) +{ + char* proj = NULL; + char* select = NULL; + const char* p; + + if(duri->constraint == NULL) free(duri->constraint); + if(duri->projection != NULL) free(duri->projection); + if(duri->selection != NULL) free(duri->selection); + duri->constraint = NULL; + duri->projection = NULL; + duri->selection = NULL; + + if(constraints == NULL || strlen(constraints)==0) return; + + duri->constraint = nulldup(constraints); + if(*duri->constraint == '?') + strcpy(duri->constraint,duri->constraint+1); + + p = duri->constraint; + proj = (char*) p; + select = strchr(proj,'&'); + if(select != NULL) { + size_t plen = (select - proj); + if(plen == 0) { + proj = NULL; + } else { + proj = (char*)malloc(plen+1); + memcpy((void*)proj,p,plen); + proj[plen] = '\0'; + } + select = nulldup(select); + } else { + proj = nulldup(proj); + select = NULL; + } + duri->projection = proj; + duri->selection = select; +} + + +/* Construct a complete OC URI without the client params + and optionally with the constraints; + caller frees returned string. + Optionally encode the pieces. +*/ + +char* +ocuribuild(OCURI* duri, const char* prefix, const char* suffix, int flags) +{ + size_t len = 0; + char* newuri; + char* tmpfile; + char* tmpsuffix; + char* tmpquery; + + int withparams = ((flags&OCURIPARAMS) + && duri->params != NULL); + int withuserpwd = ((flags&OCURIUSERPWD) + && duri->user != NULL && duri->password != NULL); + int withconstraints = ((flags&OCURICONSTRAINTS) + && duri->constraint != NULL); +#ifdef NEWESCAPE + int encode = (flags&OCURIENCODE); +#else + int encode = 0; +#endif + + if(prefix != NULL) len += NILLEN(prefix); + if(withparams) { + len += NILLEN("[]"); + len += NILLEN(duri->params); + } + len += (NILLEN(duri->protocol)+NILLEN("://")); + if(withuserpwd) { + len += (NILLEN(duri->user)+NILLEN(duri->password)+NILLEN(":@")); + } + len += (NILLEN(duri->host)); + if(duri->port != NULL) { + len += (NILLEN(":")+NILLEN(duri->port)); + } + + tmpfile = duri->file; + if(encode) + tmpfile = ocuriencode(tmpfile,fileallow); + len += (NILLEN(tmpfile)); + + if(suffix != NULL) { + tmpsuffix = (char*)suffix; + if(encode) + tmpsuffix = ocuriencode(tmpsuffix,fileallow); + len += (NILLEN(tmpsuffix)); + } + + if(withconstraints) { + tmpquery = duri->constraint; + if(encode) + tmpquery = ocuriencode(tmpquery,queryallow); + len += (NILLEN("?")+NILLEN(tmpquery)); + } + + len += 1; /* null terminator */ + + newuri = (char*)malloc(len); + if(newuri == NULL) return NULL; + + newuri[0] = '\0'; + if(prefix != NULL) strcat(newuri,prefix); + if(withparams) { + strcat(newuri,"["); + strcat(newuri,duri->params); + strcat(newuri,"]"); + } + if(duri->protocol != NULL) + strcat(newuri,duri->protocol); + strcat(newuri,"://"); + if(withuserpwd) { + strcat(newuri,duri->user); + strcat(newuri,":"); + strcat(newuri,duri->password); + strcat(newuri,"@"); + } + if(duri->host != NULL) { /* may be null if using file: protocol */ + strcat(newuri,duri->host); + } + if(duri->port != NULL) { + strcat(newuri,":"); + strcat(newuri,duri->port); + } + + strcat(newuri,tmpfile); + if(suffix != NULL) strcat(newuri,tmpsuffix); + if(withconstraints) { + strcat(newuri,"?"); + strcat(newuri,tmpquery); + } + return newuri; +} + +/**************************************************/ +/* Parameter support */ + +/* +Client parameters are assumed to be +one or more instances of bracketed pairs: +e.g "[...][...]...". +The bracket content in turn is assumed to be a +comma separated list of = pairs. +e.g. x=y,z=,a=b. +If the same parameter is specifed more than once, +then the first occurrence is used; this is so that +is possible to forcibly override user specified +parameters by prefixing. +IMPORTANT: client parameter string is assumed to +have blanks compress out. +Returns 1 if parse suceeded, 0 otherwise; +*/ + +int +ocuridecodeparams(OCURI* ocuri) +{ + char* cp; + char* cq; + int c; + int i; + int nparams; + char* params0; + char* params; + char* params1; + char** plist; + + if(ocuri == NULL) return 0; + if(ocuri->params == NULL) return 1; + + params0 = ocuri->params; + + /* Pass 1 to replace beginning '[' and ending ']' */ + if(params0[0] == '[') + params = nulldup(params0+1); + else + params = nulldup(params0); + + if(params[strlen(params)-1] == ']') + params[strlen(params)-1] = '\0'; + + /* Pass 2 to replace "][" pairs with ','*/ + params1 = nulldup(params); + cp=params; cq = params1; + while((c=*cp++)) { + if(c == RBRACKET && *cp == LBRACKET) {cp++; c = ',';} + *cq++ = c; + } + *cq = '\0'; + free(params); + params = params1; + + /* Pass 3 to break string into pieces and count # of pairs */ + nparams=0; + for(cp=params;(c=*cp);cp++) { + if(c == ',') {*cp = '\0'; nparams++;} + } + nparams++; /* for last one */ + + /* plist is an env style list */ + plist = (char**)calloc(1,sizeof(char*)*(2*nparams+1)); /* +1 for null termination */ + + /* Pass 4 to break up each pass into a (name,value) pair*/ + /* and insert into the param list */ + /* parameters of the form name name= are converted to name=""*/ + cp = params; + for(i=0;iparamlist != NULL) + ocparamfree(ocuri->paramlist); + ocuri->paramlist = plist; + return 1; +} + +const char* +ocurilookup(OCURI* uri, const char* key) +{ + int i; + if(uri == NULL || key == NULL || uri->params == NULL) return NULL; + if(uri->paramlist == NULL) { + i = ocuridecodeparams(uri); + if(!i) return 0; + } + i = ocfind(uri->paramlist,key); + if(i >= 0) + return uri->paramlist[(2*i)+1]; + return NULL; +} + +int +ocurisetparams(OCURI* uri, const char* newparams) +{ + if(uri == NULL) return 0; + if(uri->paramlist != NULL) ocparamfree(uri->paramlist); + uri->paramlist = NULL; + if(uri->params != NULL) free(uri->params); + uri->params = nulldup(newparams); + return 1; +} + +/* Internal version of lookup; returns the paired index of the key */ +static int +ocfind(char** params, const char* key) +{ + int i; + char** p; + for(i=0,p=params;*p;p+=2,i++) { + if(strcmp(key,*p)==0) return i; + } + return -1; +} + +static void +ocparamfree(char** params) +{ + char** p; + if(params == NULL) return; + for(p=params;*p;p+=2) { + free(*p); + if(p[1] != NULL) free(p[1]); + } + free(params); +} + +#ifdef OCIGNORE +/* +Delete the entry. +return value = 1 => found and deleted; + 0 => param not found +*/ +int +ocparamdelete(char** params, const char* key) +{ + int i; + char** p; + char** q; + if(params == NULL || key == NULL) return 0; + i = ocfind(params,key); + if(i < 0) return 0; + p = params+(2*i); + for(q=p+2;*q;) { + *p++ = *q++; + } + *p = NULL; + return 1; +} + +static int +oclength(char** params) +{ + int i = 0; + if(params != NULL) { + while(*params) {params+=2; i++;} + } + return i; +} + +/* +Insert new client param (name,value); +return value = 1 => not already defined + 0 => param already defined (no change) +*/ +char** +ocparaminsert(char** params, const char* key, const char* value) +{ + int i; + char** newp; + size_t len; + if(params == NULL || key == NULL) return 0; + i = ocfind(params,key); + if(i >= 0) return 0; + /* not found, append */ + i = oclength(params); + len = sizeof(char*)*((2*i)+1); + newp = realloc(params,len+2*sizeof(char*)); + memcpy(newp,params,len); + newp[2*i] = nulldup(key); + newp[2*i+1] = (value==NULL?NULL:nulldup(value)); + return newp; +} + +/* +Replace new client param (name,value); +return value = 1 => replacement performed + 0 => key not found (no change) +*/ +int +ocparamreplace(char** params, const char* key, const char* value) +{ + int i; + if(params == NULL || key == NULL) return 0; + i = ocfind(params,key); + if(i < 0) return 0; + if(params[2*i+1] != NULL) free(params[2*i+1]); + params[2*i+1] = nulldup(value); + return 1; +} +#endif + + +/* Provide % encoders and decoders */ + + +static char* hexchars = "0123456789abcdefABCDEF"; + +static void +toHex(unsigned int b, char hex[2]) +{ + hex[0] = hexchars[(b >> 4) & 0xff]; + hex[1] = hexchars[(b) & 0xff]; +} + + +static unsigned int +fromHex(int c) +{ + if(c >= '0' && c <= '9') return (c - '0'); + if(c >= 'a' && c <= 'f') return (10 + (c - 'a')); + if(c >= 'A' && c <= 'F') return (10 + (c - 'A')); + return -1; +} + + +/* Return a string representing encoding of input; caller must free; + watch out: will encode whole string, so watch what you give it. + Allowable argument specifies characters that do not need escaping. + */ + +char* +ocuriencode(char* s, char* allowable) +{ + size_t slen; + char* encoded; + char* inptr; + char* outptr; + + if(s == NULL) return NULL; + + slen = strlen(s); + encoded = (char*)malloc((3*slen) + 1); /* max possible size */ + + for(inptr=s,outptr=encoded;*inptr;) { + int c = *inptr++; + if(c == ' ') { + *outptr++ = '+'; + } else { + /* search allowable */ + int c2; + char* a = allowable; + while((c2=*a++)) { + if(c == c2) break; + } + if(c2) {*outptr++ = c;} + else { + char hex[2]; + toHex(c,hex); + *outptr++ = '%'; + *outptr++ = hex[0]; + *outptr++ = hex[1]; + } + } + } + *outptr = '\0'; + return encoded; +} + +/* Return a string representing decoding of input; caller must free;*/ +char* +ocuridecode(char* s) +{ + return ocuridecodeonly(s,NULL); +} + +/* Return a string representing decoding of input only for specified + characters; caller must free +*/ +char* +ocuridecodeonly(char* s, char* only) +{ + size_t slen; + char* decoded; + char* outptr; + char* inptr; + unsigned int c; + + if (s == NULL) return NULL; + if(only == NULL) only = ""; + + slen = strlen(s); + decoded = (char*)malloc(slen+1); /* Should be max we need */ + + outptr = decoded; + inptr = s; + while((c = *inptr++)) { + if(c == '+' && strchr(only,'+') != NULL) + *outptr++ = ' '; + else if(c == '%') { + /* try to pull two hex more characters */ + if(inptr[0] != '\0' && inptr[1] != '\0' + && strchr(hexchars,inptr[0]) != NULL + && strchr(hexchars,inptr[1]) != NULL) { + /* test conversion */ + int xc = (fromHex(inptr[0]) << 4) | (fromHex(inptr[1])); + if(strchr(only,xc) != NULL) { + inptr += 2; /* decode it */ + c = xc; + } + } + } + *outptr++ = c; + } + *outptr = '\0'; + return decoded; +} + diff --git a/extern/src_netcdf4/ocuri.h b/extern/src_netcdf4/ocuri.h new file mode 100644 index 0000000000000000000000000000000000000000..d5281203c5de8cfdba786b506cbf32f167235f73 --- /dev/null +++ b/extern/src_netcdf4/ocuri.h @@ -0,0 +1,52 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCURI_H +#define OCURI_H + +/*! This is an open structure meaning + it is ok to directly access its fields*/ +typedef struct OCURI { + char* uri; /* as passed by the caller */ + char* protocol; + char* user; /* from user:password@ */ + char* password; /* from user:password@ */ + char* host; /*!< host*/ + char* port; /*!< host */ + char* file; /*!< file */ + char* constraint; /*!< projection+selection */ + char* projection; /*!< without leading '?'*/ + char* selection; /*!< with leading '&'*/ + char* params; /* all params */ + char** paramlist; /*! entry not found. + Empty value should be represented as a zero length string */ +extern const char* ocurilookup(OCURI*, const char* param); + +extern char* ocuriencode(char* s, char* allowable); +extern char* ocuridecode(char* s); +extern char* ocuridecodeonly(char* s, char*); + +#endif /*OCURI_H*/ diff --git a/extern/src_netcdf4/ocutil.c b/extern/src_netcdf4/ocutil.c new file mode 100644 index 0000000000000000000000000000000000000000..d8eb240694ed314dc0787e3c5bc29bbb502153d8 --- /dev/null +++ b/extern/src_netcdf4/ocutil.c @@ -0,0 +1,442 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#include "config.h" +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include "ocinternal.h" +#include "ocdebug.h" + +#ifdef WIN32 +#define snprintf _snprintf +#endif + +/* Order is important: longest first */ +static char* DDSdatamarks[3] = {"Data:\r\n","Data:\n",(char*)NULL}; + +/* Not all systems have strndup, so provide one*/ +char* +ocstrndup(const char* s, size_t len) +{ + char* dup; + if(s == NULL) return NULL; + dup = (char*)ocmalloc(len+1); + MEMCHECK(dup,NULL); + memcpy((void*)dup,s,len); + dup[len] = '\0'; + return dup; +} + +/* Do not trust strncmp semantics */ +int +ocstrncmp(const char* s1, const char* s2, size_t len) +{ + const char *p,*q; + if(s1 == s2) return 0; + if(s1 == NULL) return -1; + if(s2 == NULL) return +1; + for(p=s1,q=s2;len > 0;p++,q++,len--) { + if(*p == 0 && *q == 0) return 0; /* *p == *q == 0 */ + if(*p != *q) + return (*p - *q); + } + /* 1st len chars are same */ + return 0; +} + + +void +makedimlist(OClist* path, OClist* dims) +{ + unsigned int i,j; + for(i=0;iarray.rank; + for(j=0;jarray.dimensions,j); + oclistpush(dims,(ocelem)dim); + } + } +} + +void +ocfreeprojectionclause(OCprojectionclause* clause) +{ + if(clause->target != NULL) free(clause->target); + while(oclistlength(clause->indexsets) > 0) { + OClist* slices = (OClist*)oclistpop(clause->indexsets); + while(oclistlength(slices) > 0) { + OCslice* slice = (OCslice*)oclistpop(slices); + if(slice != NULL) free(slice); + } + oclistfree(slices); + } + oclistfree(clause->indexsets); + free(clause); +} + +static void +freeAttributes(OClist* attset) +{ + unsigned int i,j; + for(i=0;iname != NULL) free(att->name); + if(att->etype == OC_String || att->etype == OC_URL) { + for(j=0;jnvalues;j++) { + char* s = ((char**)att->values)[j]; + if(s != NULL) free(s); + } + } else { + free(att->values); + } + } +} + +void +freeOCnode(OCnode* cdf, int deep) +{ + unsigned int i; + if(cdf == NULL) return; + if(cdf->name != NULL) free(cdf->name); + if(cdf->fullname != NULL) free(cdf->fullname); + if(cdf->attributes != NULL) freeAttributes(cdf->attributes); + if(cdf->subnodes != NULL) { + if(deep) { + for(i=0;isubnodes);i++) { + OCnode* node = (OCnode*)oclistget(cdf->subnodes,i); + freeOCnode(node,deep); + } + } + oclistfree(cdf->subnodes); + } + free(cdf); +} + +int +findbod(OCbytes* buffer, size_t* bodp, size_t* ddslenp) +{ + unsigned int i; + char* content; + size_t len = ocbyteslength(buffer); + char** marks; + + content = ocbytescontents(buffer); + + for(marks = DDSdatamarks;*marks;marks++) { + char* mark = *marks; + int tlen = strlen(mark); + for(i=0;iarray.rank;i++) { + OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i); + count *= (dim->dim.declsize); + } + return count; +} + +#ifdef OCIGNORE +size_t +totaldimsize(unsigned int rank, size_t* dimsizes) +{ + unsigned int i; + int unlim = 0; + unsigned long size = 1; + for(i=0;i"; +} + + +OCerror +octypeprint(OCtype etype, char* buf, size_t bufsize, void* value) +{ + if(buf == NULL || bufsize == 0 || value == NULL) return OC_EINVAL; + buf[0] = '\0'; + switch (etype) { + case OC_Char: + snprintf(buf,bufsize,"'%c'",*(char*)value); + break; + case OC_Byte: + snprintf(buf,bufsize,"%d",*(signed char*)value); + break; + case OC_UByte: + snprintf(buf,bufsize,"%u",*(unsigned char*)value); + break; + case OC_Int16: + snprintf(buf,bufsize,"%d",*(short*)value); + break; + case OC_UInt16: + snprintf(buf,bufsize,"%u",*(unsigned short*)value); + break; + case OC_Int32: + snprintf(buf,bufsize,"%d",*(int*)value); + break; + case OC_UInt32: + snprintf(buf,bufsize,"%u",*(unsigned int*)value); + break; + case OC_Float32: + snprintf(buf,bufsize,"%g",*(float*)value); + break; + case OC_Float64: + snprintf(buf,bufsize,"%g",*(double*)value); + break; +#ifdef HAVE_LONG_LONG_INT + case OC_Int64: + snprintf(buf,bufsize,"%lld",*(long long*)value); + break; + case OC_UInt64: + snprintf(buf,bufsize,"%llu",*(unsigned long long*)value); + break; +#endif + case OC_String: + case OC_URL: { + char* s = *(char**)value; + snprintf(buf,bufsize,"\"%s\"",s); + } break; + default: break; + } + return OC_NOERR; +} + +size_t +xxdrsize(OCtype etype) +{ + switch (etype) { + case OC_Char: + case OC_Byte: + case OC_UByte: + case OC_Int16: + case OC_UInt16: + case OC_Int32: + case OC_UInt32: + return XDRUNIT; + case OC_Int64: + case OC_UInt64: + return (2*XDRUNIT); + case OC_Float32: + return XDRUNIT; + case OC_Float64: + return (2*XDRUNIT); + case OC_String: + case OC_URL: + default: break; + } + return 0; +} + +/**************************************/ + +char* +ocerrstring(int err) +{ + if(err == 0) return "no error"; + if(err > 0) return strerror(err); + switch (err) { + case OC_EBADID: + return "OC_EBADID: Not a valid ID"; + case OC_EINVAL: + return "OC_EINVAL: Invalid argument"; + case OC_EPERM: + return "OC_EPERM: Write to read only"; + case OC_EINVALCOORDS: + return "OC_EINVALCOORDS: Index exceeds dimension bound"; + case OC_ENOTVAR: + return "OC_ENOTVAR: Variable not found"; + case OC_ECHAR: + return "OC_ECHAR: Attempt to convert between text & numbers"; + case OC_EEDGE: + return "OC_EEDGE: Start+count exceeds dimension bound"; + case OC_ESTRIDE: + return "OC_ESTRIDE: Illegal stride"; + case OC_ENOMEM: + return "OC_ENOMEM: Memory allocation (malloc) failure"; + case OC_EDIMSIZE: + return "OC_EDIMSIZE: Invalid dimension size"; + case OC_EDAP: + return "OC_EDAP: DAP failure"; + case OC_EXDR: + return "OC_EXDR: XDR failure"; + case OC_ECURL: + return "OC_ECURL: libcurl failure"; + case OC_EBADURL: + return "OC_EBADURL: malformed url"; + case OC_EBADVAR: + return "OC_EBADVAR: no such variable"; + case OC_EOPEN: + return "OC_EOPEN: temporary file open failed"; + case OC_EIO: + return "OC_EIO: I/O failure"; + case OC_ENODATA: + return "OC_ENODATA: Variable has no data in DAP request"; + case OC_EDAPSVC: + return "OC_EDAPSVC: DAP Server error"; + case OC_ENAMEINUSE: + return "OC_ENAMEINUSE: Duplicate name in DDS"; + case OC_EDAS: + return "OC_EDAS: Malformed or unreadable DAS"; + case OC_EDDS: + return "OC_EDDS: Malformed or unreadable DDS"; + case OC_EDATADDS: + return "OC_EDATADDS: Malformed or unreadable DATADDS"; + case OC_ERCFILE: + return "OC_ERCFILE: Malformed or unreadable run-time configuration file"; + case OC_ENOFILE: + return "OC_ENOFILE: cannot read content of URL"; + default: break; + } + return ""; +} + +OCerror +ocsvcerrordata(OCstate* state, char** codep, char** msgp, long* httpp) +{ + if(codep) *codep = state->error.code; + if(msgp) *msgp = state->error.message; + if(httpp) *httpp = state->error.httpcode; + return OC_NOERR; +} + +/* if we get OC_EDATADDS error, then try to capture any + error message and log it; assumes that in this case, + the datadds is not big. +*/ +void +ocdataddsmsg(OCstate* state, OCtree* tree) +{ +#define ERRCHUNK 1024 +#define ERRFILL ' ' +#define ERRTAG "Error {" + unsigned int i,j,len; + XXDR* xdrs; + char* contents; + off_t ckp; + + if(tree == NULL) return; + /* get available space */ + xdrs = tree->data.xdrs; + len = xxdr_length(xdrs); + if(len < strlen(ERRTAG)) + return; /* no room */ + ckp = xxdr_getpos(xdrs); + xxdr_setpos(xdrs,0); + /* read the whole thing */ + contents = (char*)malloc(len+1); + xxdr_getbytes(xdrs,contents,len); + contents[len] = '\0'; + /* Look for error tag */ + for(i=0;i 0 && (c < ' ' || c >= '\177')) + contents[i+j] = ERRFILL; + } + oc_log(LOGERR,"DATADDS failure, possible message: '%s'\n", + contents+i); + goto done; + } + } + xxdr_setpos(xdrs,ckp); +done: + return; +} diff --git a/extern/src_netcdf4/ocutil.h b/extern/src_netcdf4/ocutil.h new file mode 100644 index 0000000000000000000000000000000000000000..fa5bd01e317cda43e95dbeeda49892e992161741 --- /dev/null +++ b/extern/src_netcdf4/ocutil.h @@ -0,0 +1,36 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +#ifndef OCUTIL_H +#define OCUTIL_H 1 + +/* Forward */ +struct OCstate; + +#define ocmax(x,y) ((x) > (y) ? (x) : (y)) + +extern char* ocstrndup(const char* s, size_t len); +extern int ocstrncmp(const char* s1, const char* s2, size_t len); + +extern size_t octypesize(OCtype etype); +extern char* octypetostring(OCtype octype); +extern char* octypetoddsstring(OCtype octype); +extern char* ocerrstring(int err); +extern OCerror ocsvcerrordata(struct OCstate*,char**,char**,long*); +extern OCerror octypeprint(OCtype etype, char* buf, size_t bufsize, void* value); +extern size_t xxdrsize(OCtype etype); + +extern size_t totaldimsize(OCnode*); + +extern void makedimlist(OClist* path, OClist* dims); + +extern int findbod(OCbytes* buffer, size_t*, size_t*); + +/* Reclaimers*/ +extern void freeOCnode(OCnode*,int); +extern void ocfreeprojectionclause(OCprojectionclause* clause); + +/* Misc. */ +extern void ocdataddsmsg(struct OCstate*, struct OCtree*); + +#endif /*UTIL_H*/ diff --git a/extern/src_netcdf4/onstack.h b/extern/src_netcdf4/onstack.h new file mode 100644 index 0000000000000000000000000000000000000000..566fb998e81c4b0e5b1a6eee9db3a5c2b00f5532 --- /dev/null +++ b/extern/src_netcdf4/onstack.h @@ -0,0 +1,71 @@ +/* + * Copyright 1997, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: onstack.h,v 2.7 2006/09/15 20:40:39 ed Exp $ */ + +#ifndef _ONSTACK_H_ +#define _ONSTACK_H_ +/** + * This file provides definitions which allow us to + * "allocate" arrays on the stack where possible. + * (Where not possible, malloc and free are used.) + * + * The macro ALLOC_ONSTACK(name, type, nelems) is used to declare + * an array of 'type' named 'name' which is 'nelems' long. + * FREE_ONSTACK(name) is placed at the end of the scope of 'name' + * to call 'free' if necessary. + * + * The macro ALLOC_ONSTACK wraps a call to alloca() on most systems. + */ + +#if HAVE_ALLOCA +/* + * Implementation based on alloca() + */ + +#if defined(__GNUC__) +# if !defined(alloca) +# define alloca __builtin_alloca +# endif +#else +# if HAVE_ALLOCA_H +# include +# elif defined(_AIX) +# pragma alloca +# endif /* HAVE_ALLOCA_H */ +#endif /* __GNUC__ */ + +# if !defined(ALLOCA_ARG_T) +# define ALLOCA_ARG_T int /* the usual type of the alloca argument */ +# endif + +# define ALLOC_ONSTACK(name, type, nelems) \ + type *const name = (type *) alloca((ALLOCA_ARG_T)((nelems) * sizeof(type))) + +# define FREE_ONSTACK(name) + +#elif defined(_CRAYC) && !defined(__crayx1) && !__cplusplus && __STDC__ > 1 +/* + * Cray C allows sizing of arrays with non-constant values. + */ + +# define ALLOC_ONSTACK(name, type, nelems) \ + type name[nelems] + +# define FREE_ONSTACK(name) + +#else +/* + * Default implementation. When all else fails, use malloc/free. + */ + +# define ALLOC_ONSTACK(name, type, nelems) \ + type *const name = (type *) malloc((nelems) * sizeof(type)) + +# define FREE_ONSTACK(name) \ + free(name) + +#endif + +#endif /* _ONSTACK_H_ */ diff --git a/extern/src_netcdf4/posixio.c b/extern/src_netcdf4/posixio.c new file mode 100644 index 0000000000000000000000000000000000000000..bd52bbe9a3323a853310a15579b7a84bf06ad32d --- /dev/null +++ b/extern/src_netcdf4/posixio.c @@ -0,0 +1,1802 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: posixio.c,v 1.89 2010/05/22 21:59:08 dmh Exp $ */ + +/* For MinGW Build */ +#if defined(_WIN32) || defined(_WIN64) +#include +#include +#include +#define fstat64 fstat +#define lseek64 lseek +#endif + +#include +#include +#include +#include +#ifndef ENOERR +#define ENOERR 0 +#endif +#include +#include +#include +#include +#ifdef _MSC_VER /* Microsoft Compilers */ +#include +#else +#include +#endif +#ifndef HAVE_SSIZE_T +#define ssize_t int +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#include "ncio.h" +#include "fbits.h" +#include "rnd.h" + +/* #define INSTRUMENT 1 */ +#if INSTRUMENT /* debugging */ +#undef NDEBUG +#include +/*#include "instr.h"*/ +#endif + +#undef MIN /* system may define MIN somewhere and complain */ +#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn)) + +#if !defined(NDEBUG) && !defined(X_INT_MAX) +#define X_INT_MAX 2147483647 +#endif + +#if 0 /* !defined(NDEBUG) && !defined(X_ALIGN) */ +#define X_ALIGN 4 +#else +#undef X_ALIGN +#endif + +/* These are needed on mingw to get a dll to compile. They really + * should be provided in sys/stats.h, but what the heck. Let's not be + * too picky! */ +#ifndef S_IRGRP +#define S_IRGRP 0000040 +#endif +#ifndef S_IROTH +#define S_IROTH 0000004 +#endif +#ifndef S_IWGRP +#define S_IWGRP 0000020 +#endif +#ifndef S_IWOTH +#define S_IWOTH 0000002 +#endif + +/*Forward*/ +static int ncio_px_filesize(ncio *nciop, off_t *filesizep); +static int ncio_px_pad_length(ncio *nciop, off_t length); +static int ncio_px_close(ncio *nciop, int doUnlink); +static int ncio_spx_close(ncio *nciop, int doUnlink); + + +/* + * Define the following for debugging. + */ +/* #define ALWAYS_NC_SHARE 1 */ + +/* Begin OS */ + +#ifndef POSIXIO_DEFAULT_PAGESIZE +#define POSIXIO_DEFAULT_PAGESIZE 4096 +#endif +/* + * What is the system pagesize? + */ +static size_t +pagesize(void) +{ + size_t pgsz; +#if defined(_WIN32) || defined(_WIN64) + SYSTEM_INFO info; +#endif +/* Hmm, aren't standards great? */ +#if defined(_SC_PAGE_SIZE) && !defined(_SC_PAGESIZE) +#define _SC_PAGESIZE _SC_PAGE_SIZE +#endif + + /* For MinGW Builds */ +#if defined(_WIN32) || defined(_WIN64) + GetSystemInfo(&info); + pgsz = (size_t)info.dwPageSize; +#elif defined(_SC_PAGESIZE) + pgsz = (size_t)sysconf(_SC_PAGESIZE); +#elif defined(HAVE_GETPAGESIZE) + pgsz = (size_t) getpagesize(); +#endif + if(pgsz > 0) + return (size_t) pgsz; + return (size_t)POSIXIO_DEFAULT_PAGESIZE; +} + +/* + * What is the preferred I/O block size? + */ +static size_t +blksize(int fd) +{ +#if defined(HAVE_ST_BLKSIZE) + struct stat sb; + if (fstat(fd, &sb) > -1) + { + if(sb.st_blksize >= 8192) + return (size_t) sb.st_blksize; + return 8192; + } + /* else, silent in the face of error */ +#endif + return (size_t) 2 * pagesize(); +} + + +/* + * Sortof like ftruncate, except won't make the + * file shorter. + */ +static int +fgrow(const int fd, const off_t len) +{ + struct stat sb; + if (fstat(fd, &sb) < 0) + return errno; + if (len < sb.st_size) + return ENOERR; + { + const long dumb = 0; + /* we don't use ftruncate() due to problem with FAT32 file systems */ + /* cache current position */ + const off_t pos = lseek(fd, 0, SEEK_CUR); + if(pos < 0) + return errno; + if (lseek(fd, len-sizeof(dumb), SEEK_SET) < 0) + return errno; + if(write(fd, &dumb, sizeof(dumb)) < 0) + return errno; + if (lseek(fd, pos, SEEK_SET) < 0) + return errno; + } + return ENOERR; +} + + +/* + * Sortof like ftruncate, except won't make the file shorter. Differs + * from fgrow by only writing one byte at designated seek position, if + * needed. + */ +static int +fgrow2(const int fd, const off_t len) +{ + struct stat sb; + if (fstat(fd, &sb) < 0) + return errno; + if (len <= sb.st_size) + return ENOERR; + { + const char dumb = 0; + /* we don't use ftruncate() due to problem with FAT32 file systems */ + /* cache current position */ + const off_t pos = lseek(fd, 0, SEEK_CUR); + if(pos < 0) + return errno; + if (lseek(fd, len-1, SEEK_SET) < 0) + return errno; + if(write(fd, &dumb, sizeof(dumb)) < 0) + return errno; + if (lseek(fd, pos, SEEK_SET) < 0) + return errno; + } + return ENOERR; +} +/* End OS */ +/* Begin px */ + +/* The px_ functions are for posix systems, when NC_SHARE is not in + effect. */ + +/* Write out a "page" of data to the file. The size of the page + (i.e. the extent) varies. + + nciop - pointer to the file metadata. + offset - where in the file should this page be written. + extent - how many bytes should be written. + vp - pointer to the data to write. + posp - pointer to current position in file, updated after write. +*/ +static int +px_pgout(ncio *const nciop, + off_t const offset, const size_t extent, + void *const vp, off_t *posp) +{ + ssize_t partial; + size_t nextent; + char *nvp; +#ifdef X_ALIGN + assert(offset % X_ALIGN == 0); +#endif + + assert(*posp == OFF_NONE || *posp == lseek(nciop->fd, 0, SEEK_CUR)); + + if(*posp != offset) + { + if(lseek(nciop->fd, offset, SEEK_SET) != offset) + { + return errno; + } + *posp = offset; + } + /* Old write, didn't handle partial writes correctly */ + /* if(write(nciop->fd, vp, extent) != (ssize_t) extent) */ + /* { */ + /* return errno; */ + /* } */ + nextent = extent; + nvp = vp; + while((partial = write(nciop->fd, nvp, nextent)) != -1) { + if(partial == nextent) + break; + nvp += partial; + nextent -= partial; + } + if(partial == -1) + return errno; + *posp += extent; + + return ENOERR; +} + +/* Read in a page of data. + + nciop - a pointer to the ncio struct for this file. + offset - byte offset in file where read starts. + extent - the size of the page that will be read. + vp - a pointer to where the data will end up. + nreadp - returned number of bytes actually read (may be less than extent). + posp - pointer to current position in file, updated after read. +*/ +static int +px_pgin(ncio *const nciop, + off_t const offset, const size_t extent, + void *const vp, size_t *nreadp, off_t *posp) +{ + int status; + ssize_t nread; + +#ifdef X_ALIGN + assert(offset % X_ALIGN == 0); + assert(extent % X_ALIGN == 0); +#endif + + assert(*posp == OFF_NONE || *posp == lseek(nciop->fd, 0, SEEK_CUR)); + + if(*posp != offset) + { + if(lseek(nciop->fd, offset, SEEK_SET) != offset) + { + status = errno; + return status; + } + *posp = offset; + } + + errno = 0; + nread = read(nciop->fd, vp, extent); + if(nread != (ssize_t) extent) + { + status = errno; + if(nread == -1 || status != ENOERR) + return status; + /* else it's okay we read less than asked for */ + (void) memset((char *)vp + nread, 0, (ssize_t)extent - nread); + } + *nreadp = nread; + *posp += nread; + + return ENOERR; +} + +/* This struct is for POSIX systems, with NC_SHARE not in effect. If + NC_SHARE is used, see ncio_spx. + + blksz - block size for reads and writes to file. + pos - current read/write position in file. + bf_offset - file offset corresponding to start of memory buffer + bf_extent - number of bytes in I/O request + bf_cnt - number of bytes available in buffer + bf_base - pointer to beginning of buffer. + bf_rflags - buffer region flags (defined in ncio.h) tell the lock + status, read/write permissions, and modification status of regions + of data in the buffer. + bf_refcount - buffer reference count. + slave - used in moves. +*/ +typedef struct ncio_px { + size_t blksz; + off_t pos; + /* buffer */ + off_t bf_offset; + size_t bf_extent; + size_t bf_cnt; + void *bf_base; + int bf_rflags; + int bf_refcount; + /* chain for double buffering in px_move */ + struct ncio_px *slave; +} ncio_px; + + +/*ARGSUSED*/ +/* This function indicates the file region starting at offset may be + released. + + This is for POSIX, without NC_SHARE. If called with RGN_MODIFIED + flag, sets the modified flag in pxp->bf_rflags and decrements the + reference count. + + pxp - pointer to posix non-share ncio_px struct. + + offset - file offset for beginning of to region to be + released. + + rflags - only RGN_MODIFIED is relevent to this function, others ignored +*/ +static int +px_rel(ncio_px *const pxp, off_t offset, int rflags) +{ + assert(pxp->bf_offset <= offset + && offset < pxp->bf_offset + (off_t) pxp->bf_extent); + assert(pIf(fIsSet(rflags, RGN_MODIFIED), + fIsSet(pxp->bf_rflags, RGN_WRITE))); + + if(fIsSet(rflags, RGN_MODIFIED)) + { + fSet(pxp->bf_rflags, RGN_MODIFIED); + } + pxp->bf_refcount--; + + return ENOERR; +} + +/* This function indicates the file region starting at offset may be + released. Each read or write to the file is bracketed by a call to + the "get" region function and a call to the "rel" region function. + If you only read from the memory region, release it with a flag of + 0, if you modify the region, release it with a flag of + RGN_MODIFIED. + + For POSIX system, without NC_SHARE, this becomes the rel function + pointed to by the ncio rel function pointer. It mearly checks for + file write permission, then calls px_rel to do everything. + + nciop - pointer to ncio struct. + offset - num bytes from beginning of buffer to region to be + released. + rflags - only RGN_MODIFIED is relevent to this function, others ignored +*/ +static int +ncio_px_rel(ncio *const nciop, off_t offset, int rflags) +{ + ncio_px *const pxp = (ncio_px *)nciop->pvt; + + if(fIsSet(rflags, RGN_MODIFIED) && !fIsSet(nciop->ioflags, NC_WRITE)) + return EPERM; /* attempt to write readonly file */ + + return px_rel(pxp, offset, rflags); +} + +/* POSIX get. This will "make a region available." Since we're using + buffered IO, this means that if needed, we'll fetch a new page from + the file, otherwise, just return a pointer to what's in memory + already. + + nciop - pointer to ncio struct, containing file info. + pxp - pointer to ncio_px struct, which contains special metadate + for posix files without NC_SHARE. + offset - start byte of region to get. + extent - how many bytes to read. + rflags - One of the RGN_* flags defined in ncio.h. + vpp - pointer to pointer that will recieve data. + + NOTES: + + * For blkoffset round offset down to the nearest pxp->blksz. This + provides the offset (in bytes) to the beginning of the block that + holds the current offset. + + * diff tells how far into the current block we are. + + * For blkextent round up to the number of bytes at the beginning of + the next block, after the one that holds our current position, plus + whatever extra (i.e. the extent) that we are about to grab. + + * The blkextent can't be more than twice the pxp->blksz. That's + because the pxp->blksize is the sizehint, and in ncio_px_init2 the + buffer (pointed to by pxp->bf-base) is allocated with 2 * + *sizehintp. This is checked (unneccesarily) more than once in + asserts. + + * If this is called on a newly opened file, pxp->bf_offset will be + OFF_NONE and we'll jump to label pgin to immediately read in a + page. +*/ +static int +px_get(ncio *const nciop, ncio_px *const pxp, + off_t offset, size_t extent, + int rflags, + void **const vpp) +{ + int status = ENOERR; + + const off_t blkoffset = _RNDDOWN(offset, (off_t)pxp->blksz); + off_t diff = (size_t)(offset - blkoffset); + off_t blkextent = _RNDUP(diff + extent, pxp->blksz); + + assert(extent != 0); + assert(extent < X_INT_MAX); /* sanity check */ + assert(offset >= 0); /* sanity check */ + + if(2 * pxp->blksz < blkextent) + return E2BIG; /* TODO: temporary kludge */ + if(pxp->bf_offset == OFF_NONE) + { + /* Uninitialized */ + if(pxp->bf_base == NULL) + { + assert(pxp->bf_extent == 0); + assert(blkextent <= 2 * pxp->blksz); + pxp->bf_base = malloc(2 * pxp->blksz); + if(pxp->bf_base == NULL) + return ENOMEM; + } + goto pgin; + } + /* else */ + assert(blkextent <= 2 * pxp->blksz); + + if(blkoffset == pxp->bf_offset) + { + /* hit */ + if(blkextent > pxp->bf_extent) + { + /* page in upper */ + void *const middle = + (void *)((char *)pxp->bf_base + pxp->blksz); + assert(pxp->bf_extent == pxp->blksz); + status = px_pgin(nciop, + pxp->bf_offset + (off_t)pxp->blksz, + pxp->blksz, + middle, + &pxp->bf_cnt, + &pxp->pos); + if(status != ENOERR) + return status; + pxp->bf_extent = 2 * pxp->blksz; + pxp->bf_cnt += pxp->blksz; + } + goto done; + } + /* else */ + + if(pxp->bf_extent > pxp->blksz + && blkoffset == pxp->bf_offset + (off_t)pxp->blksz) + { + /* hit in upper half */ + if(blkextent == pxp->blksz) + { + /* all in upper half, no fault needed */ + diff += pxp->blksz; + goto done; + } + /* else */ + if(pxp->bf_cnt > pxp->blksz) + { + /* data in upper half */ + void *const middle = + (void *)((char *)pxp->bf_base + pxp->blksz); + assert(pxp->bf_extent == 2 * pxp->blksz); + if(fIsSet(pxp->bf_rflags, RGN_MODIFIED)) + { + /* page out lower half */ + assert(pxp->bf_refcount <= 0); + status = px_pgout(nciop, + pxp->bf_offset, + pxp->blksz, + pxp->bf_base, + &pxp->pos); + if(status != ENOERR) + return status; + } + pxp->bf_cnt -= pxp->blksz; + /* copy upper half into lower half */ + (void) memcpy(pxp->bf_base, middle, pxp->bf_cnt); + } + else /* added to fix nofill bug */ + { + assert(pxp->bf_extent == 2 * pxp->blksz); + /* still have to page out lower half, if modified */ + if(fIsSet(pxp->bf_rflags, RGN_MODIFIED)) + { + assert(pxp->bf_refcount <= 0); + status = px_pgout(nciop, + pxp->bf_offset, + pxp->blksz, + pxp->bf_base, + &pxp->pos); + if(status != ENOERR) + return status; + } + } + pxp->bf_offset = blkoffset; + /* pxp->bf_extent = pxp->blksz; */ + + assert(blkextent == 2 * pxp->blksz); + { + /* page in upper */ + void *const middle = + (void *)((char *)pxp->bf_base + pxp->blksz); + status = px_pgin(nciop, + pxp->bf_offset + (off_t)pxp->blksz, + pxp->blksz, + middle, + &pxp->bf_cnt, + &pxp->pos); + if(status != ENOERR) + return status; + pxp->bf_extent = 2 * pxp->blksz; + pxp->bf_cnt += pxp->blksz; + } + goto done; + } + /* else */ + + if(blkoffset == pxp->bf_offset - (off_t)pxp->blksz) + { + /* wants the page below */ + void *const middle = + (void *)((char *)pxp->bf_base + pxp->blksz); + size_t upper_cnt = 0; + if(pxp->bf_cnt > pxp->blksz) + { + /* data in upper half */ + assert(pxp->bf_extent == 2 * pxp->blksz); + if(fIsSet(pxp->bf_rflags, RGN_MODIFIED)) + { + /* page out upper half */ + assert(pxp->bf_refcount <= 0); + status = px_pgout(nciop, + pxp->bf_offset + (off_t)pxp->blksz, + pxp->bf_cnt - pxp->blksz, + middle, + &pxp->pos); + if(status != ENOERR) + return status; + } + pxp->bf_cnt = pxp->blksz; + pxp->bf_extent = pxp->blksz; + } + if(pxp->bf_cnt > 0) + { + /* copy lower half into upper half */ + (void) memcpy(middle, pxp->bf_base, pxp->blksz); + upper_cnt = pxp->bf_cnt; + } + /* read page below into lower half */ + status = px_pgin(nciop, + blkoffset, + pxp->blksz, + pxp->bf_base, + &pxp->bf_cnt, + &pxp->pos); + if(status != ENOERR) + return status; + pxp->bf_offset = blkoffset; + if(upper_cnt != 0) + { + pxp->bf_extent = 2 * pxp->blksz; + pxp->bf_cnt = pxp->blksz + upper_cnt; + } + else + { + pxp->bf_extent = pxp->blksz; + } + goto done; + } + /* else */ + + /* no overlap */ + if(fIsSet(pxp->bf_rflags, RGN_MODIFIED)) + { + assert(pxp->bf_refcount <= 0); + status = px_pgout(nciop, + pxp->bf_offset, + pxp->bf_cnt, + pxp->bf_base, + &pxp->pos); + if(status != ENOERR) + return status; + pxp->bf_rflags = 0; + } + +pgin: + status = px_pgin(nciop, + blkoffset, + blkextent, + pxp->bf_base, + &pxp->bf_cnt, + &pxp->pos); + if(status != ENOERR) + return status; + pxp->bf_offset = blkoffset; + pxp->bf_extent = blkextent; + +done: + extent += diff; + if(pxp->bf_cnt < extent) + pxp->bf_cnt = extent; + assert(pxp->bf_cnt <= pxp->bf_extent); + + pxp->bf_rflags |= rflags; + pxp->bf_refcount++; + + *vpp = (char *)pxp->bf_base + diff; + return ENOERR; +} + +/* Request that the region (offset, extent) be made available through + *vpp. + + This function converts a file region specified by an offset and + extent to a memory pointer. The region may be locked until the + corresponding call to rel(). + + For POSIX systems, without NC_SHARE. This function gets a page of + size extent? + + This is a wrapper for the function px_get, which does all the heavy + lifting. + + nciop - pointer to ncio struct for this file. + offset - offset (from beginning of file?) to the data we want to + read. + extent - the number of bytes to read from the file. + rflags - One of the RGN_* flags defined in ncio.h. + vpp - handle to point at data when it's been read. +*/ +static int +ncio_px_get(ncio *const nciop, + off_t offset, size_t extent, + int rflags, + void **const vpp) +{ + ncio_px *const pxp = (ncio_px *)nciop->pvt; + + if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE)) + return EPERM; /* attempt to write readonly file */ + + /* reclaim space used in move */ + if(pxp->slave != NULL) + { + if(pxp->slave->bf_base != NULL) + { + free(pxp->slave->bf_base); + pxp->slave->bf_base = NULL; + pxp->slave->bf_extent = 0; + pxp->slave->bf_offset = OFF_NONE; + } + free(pxp->slave); + pxp->slave = NULL; + } + return px_get(nciop, pxp, offset, extent, rflags, vpp); +} + + +/* ARGSUSED */ +static int +px_double_buffer(ncio *const nciop, off_t to, off_t from, + size_t nbytes, int rflags) +{ + ncio_px *const pxp = (ncio_px *)nciop->pvt; + int status = ENOERR; + void *src; + void *dest; + +#if INSTRUMENT +fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n", + (long)to, (long)from, (long)nbytes); +#endif + status = px_get(nciop, pxp, to, nbytes, RGN_WRITE, + &dest); + if(status != ENOERR) + return status; + + if(pxp->slave == NULL) + { + pxp->slave = (ncio_px *) malloc(sizeof(ncio_px)); + if(pxp->slave == NULL) + return ENOMEM; + + pxp->slave->blksz = pxp->blksz; + /* pos done below */ + pxp->slave->bf_offset = pxp->bf_offset; + pxp->slave->bf_extent = pxp->bf_extent; + pxp->slave->bf_cnt = pxp->bf_cnt; + pxp->slave->bf_base = malloc(2 * pxp->blksz); + if(pxp->slave->bf_base == NULL) + return ENOMEM; + (void) memcpy(pxp->slave->bf_base, pxp->bf_base, + pxp->bf_extent); + pxp->slave->bf_rflags = 0; + pxp->slave->bf_refcount = 0; + pxp->slave->slave = NULL; + } + + pxp->slave->pos = pxp->pos; + status = px_get(nciop, pxp->slave, from, nbytes, 0, + &src); + if(status != ENOERR) + return status; + if(pxp->pos != pxp->slave->pos) + { + /* position changed, sync */ + pxp->pos = pxp->slave->pos; + } + + (void) memcpy(dest, src, nbytes); + + (void)px_rel(pxp->slave, from, 0); + (void)px_rel(pxp, to, RGN_MODIFIED); + + return status; +} + +/* Like memmove(), safely move possibly overlapping data. + + Copy one region to another without making anything available to + higher layers. May be just implemented in terms of get() and rel(), + or may be tricky to be efficient. Only used in by nc_enddef() + after redefinition. + + nciop - pointer to ncio struct with file info. + to - src for move? + from - dest for move? + nbytes - number of bytes to move. + rflags - One of the RGN_* flags defined in ncio.h. The only + reasonable flag value is RGN_NOLOCK. +*/ +static int +ncio_px_move(ncio *const nciop, off_t to, off_t from, + size_t nbytes, int rflags) +{ + ncio_px *const pxp = (ncio_px *)nciop->pvt; + int status = ENOERR; + off_t lower; + off_t upper; + char *base; + size_t diff; + size_t extent; + + if(to == from) + return ENOERR; /* NOOP */ + + if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE)) + return EPERM; /* attempt to write readonly file */ + + rflags &= RGN_NOLOCK; /* filter unwanted flags */ + + if(to > from) + { + /* growing */ + lower = from; + upper = to; + } + else + { + /* shrinking */ + lower = to; + upper = from; + } + diff = (size_t)(upper - lower); + extent = diff + nbytes; + +#if INSTRUMENT +fprintf(stderr, "ncio_px_move %ld %ld %ld %ld %ld\n", + (long)to, (long)from, (long)nbytes, (long)lower, (long)extent); +#endif + if(extent > pxp->blksz) + { + size_t remaining = nbytes; + +if(to > from) +{ + off_t frm = from + nbytes; + off_t toh = to + nbytes; + for(;;) + { + size_t loopextent = MIN(remaining, pxp->blksz); + frm -= loopextent; + toh -= loopextent; + + status = px_double_buffer(nciop, toh, frm, + loopextent, rflags) ; + if(status != ENOERR) + return status; + remaining -= loopextent; + + if(remaining == 0) + break; /* normal loop exit */ + } +} +else +{ + for(;;) + { + size_t loopextent = MIN(remaining, pxp->blksz); + + status = px_double_buffer(nciop, to, from, + loopextent, rflags) ; + if(status != ENOERR) + return status; + remaining -= loopextent; + + if(remaining == 0) + break; /* normal loop exit */ + to += loopextent; + from += loopextent; + } +} + return ENOERR; + } + +#if INSTRUMENT +fprintf(stderr, "\tncio_px_move small\n"); +#endif + status = px_get(nciop, pxp, lower, extent, RGN_WRITE|rflags, + (void **)&base); + + if(status != ENOERR) + return status; + + if(to > from) + (void) memmove(base + diff, base, nbytes); + else + (void) memmove(base, base + diff, nbytes); + + (void) px_rel(pxp, lower, RGN_MODIFIED); + + return status; +} + + +/* Flush any buffers to disk. May be a no-op on if I/O is unbuffered. + This function is used when NC_SHARE is NOT used. +*/ +static int +ncio_px_sync(ncio *const nciop) +{ + ncio_px *const pxp = (ncio_px *)nciop->pvt; + int status = ENOERR; + if(fIsSet(pxp->bf_rflags, RGN_MODIFIED)) + { + assert(pxp->bf_refcount <= 0); + status = px_pgout(nciop, pxp->bf_offset, + pxp->bf_cnt, + pxp->bf_base, &pxp->pos); + if(status != ENOERR) + return status; + pxp->bf_rflags = 0; + } + else if (!fIsSet(pxp->bf_rflags, RGN_WRITE)) + { + /* + * The dataset is readonly. Invalidate the buffers so + * that the next ncio_px_get() will actually read data. + */ + pxp->bf_offset = OFF_NONE; + pxp->bf_cnt = 0; + } + return status; +} + +/* Internal function called at close to + free up anything hanging off pvt. +*/ +static void +ncio_px_freepvt(void *const pvt) +{ + ncio_px *const pxp = (ncio_px *)pvt; + if(pxp == NULL) + return; + + if(pxp->slave != NULL) + { + if(pxp->slave->bf_base != NULL) + { + free(pxp->slave->bf_base); + pxp->slave->bf_base = NULL; + pxp->slave->bf_extent = 0; + pxp->slave->bf_offset = OFF_NONE; + } + free(pxp->slave); + pxp->slave = NULL; + } + + if(pxp->bf_base != NULL) + { + free(pxp->bf_base); + pxp->bf_base = NULL; + pxp->bf_extent = 0; + pxp->bf_offset = OFF_NONE; + } +} + + +/* This is the second half of the ncio initialization. This is called + after the file has actually been opened. + + The most important thing that happens is the allocation of a block + of memory at pxp->bf_base. This is going to be twice the size of + the chunksizehint (rounded up to the nearest sizeof(double)) passed + in from nc__create or nc__open. The rounded chunksizehint (passed + in here in sizehintp) is going to be stored as pxp->blksize. + + According to our "contract" we are not allowed to ask for an extent + larger than this chunksize/sizehint/blksize from the ncio get + function. + + nciop - pointer to the ncio struct + sizehintp - pointer to a size hint that will be rounded up and + passed back to the caller. + isNew - true if this is being called from ncio_create for a new + file. +*/ +static int +ncio_px_init2(ncio *const nciop, size_t *sizehintp, int isNew) +{ + ncio_px *const pxp = (ncio_px *)nciop->pvt; + const size_t bufsz = 2 * *sizehintp; + + assert(nciop->fd >= 0); + + pxp->blksz = *sizehintp; + + assert(pxp->bf_base == NULL); + + /* this is separate allocation because it may grow */ + pxp->bf_base = malloc(bufsz); + if(pxp->bf_base == NULL) + return ENOMEM; + /* else */ + pxp->bf_cnt = 0; + if(isNew) + { + /* save a read */ + pxp->pos = 0; + pxp->bf_offset = 0; + pxp->bf_extent = bufsz; + (void) memset(pxp->bf_base, 0, pxp->bf_extent); + } + return ENOERR; +} + + +/* This is the first of a two-part initialization of the ncio struct. + Here the rel, get, move, sync, and free function pointers are set + to their POSIX non-NC_SHARE functions (ncio_px_*). + + The ncio_px struct is also partially initialized. +*/ +static void +ncio_px_init(ncio *const nciop) +{ + ncio_px *const pxp = (ncio_px *)nciop->pvt; + + *((ncio_relfunc **)&nciop->rel) = ncio_px_rel; /* cast away const */ + *((ncio_getfunc **)&nciop->get) = ncio_px_get; /* cast away const */ + *((ncio_movefunc **)&nciop->move) = ncio_px_move; /* cast away const */ + *((ncio_syncfunc **)&nciop->sync) = ncio_px_sync; /* cast away const */ + *((ncio_filesizefunc **)&nciop->filesize) = ncio_px_filesize; /* cast away const */ + *((ncio_pad_lengthfunc **)&nciop->pad_length) = ncio_px_pad_length; /* cast away const */ + *((ncio_closefunc **)&nciop->close) = ncio_px_close; /* cast away const */ + + pxp->blksz = 0; + pxp->pos = -1; + pxp->bf_offset = OFF_NONE; + pxp->bf_extent = 0; + pxp->bf_rflags = 0; + pxp->bf_refcount = 0; + pxp->bf_base = NULL; + pxp->slave = NULL; + +} + +/* Begin spx */ + +/* This is the struct that gets hung of ncio->pvt(?) when the NC_SHARE + flag is used. +*/ +typedef struct ncio_spx { + off_t pos; + /* buffer */ + off_t bf_offset; + size_t bf_extent; + size_t bf_cnt; + void *bf_base; +} ncio_spx; + + +/*ARGSUSED*/ +/* This function releases the region specified by offset. + + For POSIX system, with NC_SHARE, this becomes the rel function + pointed to by the ncio rel function pointer. It mearly checks for + file write permission, then calls px_rel to do everything. + + nciop - pointer to ncio struct. + + offset - beginning of region. + + rflags - One of the RGN_* flags defined in ncio.h. If set to + RGN_MODIFIED it means that the data in this region were modified, + and it needs to be written out to the disk immediately (since we + are not buffering with NC_SHARE on). + +*/ +static int +ncio_spx_rel(ncio *const nciop, off_t offset, int rflags) +{ + ncio_spx *const pxp = (ncio_spx *)nciop->pvt; + int status = ENOERR; + + assert(pxp->bf_offset <= offset); + assert(pxp->bf_cnt != 0); + assert(pxp->bf_cnt <= pxp->bf_extent); +#ifdef X_ALIGN + assert(offset < pxp->bf_offset + X_ALIGN); + assert(pxp->bf_cnt % X_ALIGN == 0 ); +#endif + + if(fIsSet(rflags, RGN_MODIFIED)) + { + if(!fIsSet(nciop->ioflags, NC_WRITE)) + return EPERM; /* attempt to write readonly file */ + + status = px_pgout(nciop, pxp->bf_offset, + pxp->bf_cnt, + pxp->bf_base, &pxp->pos); + /* if error, invalidate buffer anyway */ + } + pxp->bf_offset = OFF_NONE; + pxp->bf_cnt = 0; + return status; +} + + +/* Request that the region (offset, extent) be made available through + *vpp. + + This function converts a file region specified by an offset and + extent to a memory pointer. The region may be locked until the + corresponding call to rel(). + + For POSIX systems, with NC_SHARE. + + nciop - pointer to ncio struct for this file. + offset - offset (from beginning of file?) to the data we want to + read. + extent - the number of bytes we want. + rflags - One of the RGN_* flags defined in ncio.h. May be RGN_NOLOCK. + vpp - handle to point at data when it's been read. +*/ +static int +ncio_spx_get(ncio *const nciop, + off_t offset, size_t extent, + int rflags, + void **const vpp) +{ + ncio_spx *const pxp = (ncio_spx *)nciop->pvt; + int status = ENOERR; +#ifdef X_ALIGN + size_t rem; +#endif + + if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE)) + return EPERM; /* attempt to write readonly file */ + + assert(extent != 0); + assert(extent < X_INT_MAX); /* sanity check */ + + assert(pxp->bf_cnt == 0); + +#ifdef X_ALIGN + rem = (size_t)(offset % X_ALIGN); + if(rem != 0) + { + offset -= rem; + extent += rem; + } + + { + const size_t rndup = extent % X_ALIGN; + if(rndup != 0) + extent += X_ALIGN - rndup; + } + + assert(offset % X_ALIGN == 0); + assert(extent % X_ALIGN == 0); +#endif + + if(pxp->bf_extent < extent) + { + if(pxp->bf_base != NULL) + { + free(pxp->bf_base); + pxp->bf_base = NULL; + pxp->bf_extent = 0; + } + assert(pxp->bf_extent == 0); + pxp->bf_base = malloc(extent); + if(pxp->bf_base == NULL) + return ENOMEM; + pxp->bf_extent = extent; + } + + status = px_pgin(nciop, offset, + extent, + pxp->bf_base, + &pxp->bf_cnt, &pxp->pos); + if(status != ENOERR) + return status; + + pxp->bf_offset = offset; + + if(pxp->bf_cnt < extent) + pxp->bf_cnt = extent; + +#ifdef X_ALIGN + *vpp = (char *)pxp->bf_base + rem; +#else + *vpp = pxp->bf_base; +#endif + return ENOERR; +} + + +#if 0 +/*ARGSUSED*/ +static int +strategy(ncio *const nciop, off_t to, off_t offset, + size_t extent, int rflags) +{ + static ncio_spx pxp[1]; + int status = ENOERR; +#ifdef X_ALIGN + size_t rem; +#endif + + assert(extent != 0); + assert(extent < X_INT_MAX); /* sanity check */ +#if INSTRUMENT +fprintf(stderr, "strategy %ld at %ld to %ld\n", + (long)extent, (long)offset, (long)to); +#endif + + +#ifdef X_ALIGN + rem = (size_t)(offset % X_ALIGN); + if(rem != 0) + { + offset -= rem; + extent += rem; + } + + { + const size_t rndup = extent % X_ALIGN; + if(rndup != 0) + extent += X_ALIGN - rndup; + } + + assert(offset % X_ALIGN == 0); + assert(extent % X_ALIGN == 0); +#endif + + if(pxp->bf_extent < extent) + { + if(pxp->bf_base != NULL) + { + free(pxp->bf_base); + pxp->bf_base = NULL; + pxp->bf_extent = 0; + } + assert(pxp->bf_extent == 0); + pxp->bf_base = malloc(extent); + if(pxp->bf_base == NULL) + return ENOMEM; + pxp->bf_extent = extent; + } + + status = px_pgin(nciop, offset, + extent, + pxp->bf_base, + &pxp->bf_cnt, &pxp->pos); + if(status != ENOERR) + return status; + + pxp->bf_offset = to; /* TODO: XALIGN */ + + if(pxp->bf_cnt < extent) + pxp->bf_cnt = extent; + + status = px_pgout(nciop, pxp->bf_offset, + pxp->bf_cnt, + pxp->bf_base, &pxp->pos); + /* if error, invalidate buffer anyway */ + pxp->bf_offset = OFF_NONE; + pxp->bf_cnt = 0; + return status; +} +#endif + +/* Copy one region to another without making anything available to + higher layers. May be just implemented in terms of get() and rel(), + or may be tricky to be efficient. Only used in by nc_enddef() + after redefinition. + + nciop - pointer to ncio struct for this file. + to - dest for move? + from - src for move? + nbytes - number of bytes to move. + rflags - One of the RGN_* flags defined in ncio.h. +*/ +static int +ncio_spx_move(ncio *const nciop, off_t to, off_t from, + size_t nbytes, int rflags) +{ + int status = ENOERR; + off_t lower = from; + off_t upper = to; + char *base; + size_t diff; + size_t extent; + + rflags &= RGN_NOLOCK; /* filter unwanted flags */ + + if(to == from) + return ENOERR; /* NOOP */ + + if(to > from) + { + /* growing */ + lower = from; + upper = to; + } + else + { + /* shrinking */ + lower = to; + upper = from; + } + + diff = (size_t)(upper - lower); + extent = diff + nbytes; + + status = ncio_spx_get(nciop, lower, extent, RGN_WRITE|rflags, + (void **)&base); + + if(status != ENOERR) + return status; + + if(to > from) + (void) memmove(base + diff, base, nbytes); + else + (void) memmove(base, base + diff, nbytes); + + (void) ncio_spx_rel(nciop, lower, RGN_MODIFIED); + + return status; +} + + +/*ARGSUSED*/ +/* Flush any buffers to disk. May be a no-op on if I/O is unbuffered. +*/ +static int +ncio_spx_sync(ncio *const nciop) +{ + /* NOOP */ + return ENOERR; +} + +static void +ncio_spx_freepvt(void *const pvt) +{ + ncio_spx *const pxp = (ncio_spx *)pvt; + if(pxp == NULL) + return; + + if(pxp->bf_base != NULL) + { + free(pxp->bf_base); + pxp->bf_base = NULL; + pxp->bf_offset = OFF_NONE; + pxp->bf_extent = 0; + pxp->bf_cnt = 0; + } +} + + +/* This does the second half of the ncio_spx struct initialization for + POSIX systems, with NC_SHARE on. + + nciop - pointer to ncio struct for this file. File has been opened. + sizehintp - pointer to a size which will be rounded up to the + nearest 8-byt boundary and then used as the max size "chunk" (or + page) to read from the file. +*/ +static int +ncio_spx_init2(ncio *const nciop, const size_t *const sizehintp) +{ + ncio_spx *const pxp = (ncio_spx *)nciop->pvt; + + assert(nciop->fd >= 0); + + pxp->bf_extent = *sizehintp; + + assert(pxp->bf_base == NULL); + + /* this is separate allocation because it may grow */ + pxp->bf_base = malloc(pxp->bf_extent); + if(pxp->bf_base == NULL) + { + pxp->bf_extent = 0; + return ENOMEM; + } + /* else */ + return ENOERR; +} + + +/* First half of init for ncio_spx struct, setting the rel, get, move, + snyc, and free function pointers to the NC_SHARE versions of these + functions (i.e. the ncio_spx_* functions). +*/ +static void +ncio_spx_init(ncio *const nciop) +{ + ncio_spx *const pxp = (ncio_spx *)nciop->pvt; + + *((ncio_relfunc **)&nciop->rel) = ncio_spx_rel; /* cast away const */ + *((ncio_getfunc **)&nciop->get) = ncio_spx_get; /* cast away const */ + *((ncio_movefunc **)&nciop->move) = ncio_spx_move; /* cast away const */ + *((ncio_syncfunc **)&nciop->sync) = ncio_spx_sync; /* cast away const */ + /* shared with _px_ */ + *((ncio_filesizefunc **)&nciop->filesize) = ncio_px_filesize; /* cast away const */ + *((ncio_pad_lengthfunc **)&nciop->pad_length) = ncio_px_pad_length; /* cast away const */ + *((ncio_closefunc **)&nciop->close) = ncio_spx_close; /* cast away const */ + + pxp->pos = -1; + pxp->bf_offset = OFF_NONE; + pxp->bf_extent = 0; + pxp->bf_cnt = 0; + pxp->bf_base = NULL; +} + + +/* */ + +/* This will call whatever free function is attached to the free + function pointer in ncio. It's called from ncio_close, and from + ncio_open and ncio_create when an error occurs that the file + metadata must be freed. +*/ +static void +ncio_px_free(ncio *nciop) +{ + if(nciop == NULL) + return; + if(nciop->pvt != NULL) + ncio_px_freepvt(nciop->pvt); + free(nciop); +} + +static void +ncio_spx_free(ncio *nciop) +{ + if(nciop == NULL) + return; + if(nciop->pvt != NULL) + ncio_spx_freepvt(nciop->pvt); + free(nciop); +} + + +/* Create a new ncio struct to hold info about the file. This will + create and init the ncio_px or ncio_spx struct (the latter if + NC_SHARE is used.) +*/ +static ncio * +ncio_px_new(const char *path, int ioflags) +{ + size_t sz_ncio = M_RNDUP(sizeof(ncio)); + size_t sz_path = M_RNDUP(strlen(path) +1); + size_t sz_ncio_pvt; + ncio *nciop; + +#if ALWAYS_NC_SHARE /* DEBUG */ + fSet(ioflags, NC_SHARE); +#endif + + if(fIsSet(ioflags, NC_SHARE)) + sz_ncio_pvt = sizeof(ncio_spx); + else + sz_ncio_pvt = sizeof(ncio_px); + + nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt); + if(nciop == NULL) + return NULL; + + nciop->ioflags = ioflags; + *((int *)&nciop->fd) = -1; /* cast away const */ + + nciop->path = (char *) ((char *)nciop + sz_ncio); + (void) strcpy((char *)nciop->path, path); /* cast away const */ + + /* cast away const */ + *((void **)&nciop->pvt) = (void *)(nciop->path + sz_path); + + if(fIsSet(ioflags, NC_SHARE)) + ncio_spx_init(nciop); + else + ncio_px_init(nciop); + + return nciop; +} + + +/* Public below this point */ +#ifndef NCIO_MINBLOCKSIZE +#define NCIO_MINBLOCKSIZE 256 +#endif +#ifndef NCIO_MAXBLOCKSIZE +#define NCIO_MAXBLOCKSIZE 268435456 /* sanity check, about X_SIZE_T_MAX/8 */ +#endif + +#ifdef S_IRUSR +#define NC_DEFAULT_CREAT_MODE \ + (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) /* 0666 */ + +#else +#define NC_DEFAULT_CREAT_MODE 0666 +#endif + +/* Create a file, and the ncio struct to go with it. This funtion is + only called from nc__create_mp. + + path - path of file to create. + ioflags - flags from nc_create + initialsz - From the netcdf man page: "The argument + Iinitialsize sets the initial size of the file at creation time." + igeto - + igetsz - + sizehintp - this eventually goes into pxp->blksz and is the size of + a page of data for buffered reads and writes. + nciopp - pointer to a pointer that will get location of newly + created and inited ncio struct. + igetvpp - pointer to pointer which will get the location of ? +*/ +int +posixio_create(const char *path, int ioflags, + size_t initialsz, + off_t igeto, size_t igetsz, size_t *sizehintp, + ncio **nciopp, void **const igetvpp) +{ + ncio *nciop; + int oflags = (O_RDWR|O_CREAT); + int fd; + int status; + + if(initialsz < (size_t)igeto + igetsz) + initialsz = (size_t)igeto + igetsz; + + fSet(ioflags, NC_WRITE); + + if(path == NULL || *path == 0) + return EINVAL; + + nciop = ncio_px_new(path, ioflags); + if(nciop == NULL) + return ENOMEM; + + if(fIsSet(ioflags, NC_NOCLOBBER)) + fSet(oflags, O_EXCL); + else + fSet(oflags, O_TRUNC); +#ifdef O_BINARY + fSet(oflags, O_BINARY); +#endif +#ifdef vms + fd = open(path, oflags, NC_DEFAULT_CREAT_MODE, "ctx=stm"); +#else + /* Should we mess with the mode based on NC_SHARE ?? */ + fd = open(path, oflags, NC_DEFAULT_CREAT_MODE); +#endif +#if 0 + (void) fprintf(stderr, "ncio_create(): path=\"%s\"\n", path); + (void) fprintf(stderr, "ncio_create(): oflags=0x%x\n", oflags); +#endif + if(fd < 0) + { + status = errno; + goto unwind_new; + } + *((int *)&nciop->fd) = fd; /* cast away const */ + + if(*sizehintp < NCIO_MINBLOCKSIZE) + { + /* Use default */ + *sizehintp = blksize(fd); + } + else if(*sizehintp >= NCIO_MAXBLOCKSIZE) + { + /* Use maximum allowed value */ + *sizehintp = NCIO_MAXBLOCKSIZE; + } + else + { + *sizehintp = M_RNDUP(*sizehintp); + } + + if(fIsSet(nciop->ioflags, NC_SHARE)) + status = ncio_spx_init2(nciop, sizehintp); + else + status = ncio_px_init2(nciop, sizehintp, 1); + + if(status != ENOERR) + goto unwind_open; + + if(initialsz != 0) + { + status = fgrow(fd, (off_t)initialsz); + if(status != ENOERR) + goto unwind_open; + } + + if(igetsz != 0) + { + status = nciop->get(nciop, + igeto, igetsz, + RGN_WRITE, + igetvpp); + if(status != ENOERR) + goto unwind_open; + } + + *nciopp = nciop; + return ENOERR; + +unwind_open: + (void) close(fd); + /* ?? unlink */ + /*FALLTHRU*/ +unwind_new: + ncio_close(nciop,!fIsSet(ioflags, NC_NOCLOBBER)); + return status; +} + + +/* This function opens the data file. It is only called from nc.c, + from nc__open_mp and nc_delete_mp. + + path - path of data file. + + ioflags - flags passed into nc_open. + + igeto - looks like this function can do an initial page get, and + igeto is going to be the offset for that. But it appears to be + unused + + igetsz - the size in bytes of initial page get (a.k.a. extent). Not + ever used in the library. + + sizehintp - pointer to sizehint parameter from nc__open or + nc__create. This is used to set pxp->blksz. + + Here's what the man page has to say: + + "The argument referenced by chunksize controls a space versus time + tradeoff, memory allocated in the netcdf library versus number of + system calls. + + Because of internal requirements, the value may not be set to + exactly the value requested. The actual value chosen is returned by reference. + + Using the value NC_SIZEHINT_DEFAULT causes the library to choose a + default. How the system choses the default depends on the + system. On many systems, the "preferred I/O block size" is + available from the stat() system call, struct stat member + st_blksize. If this is available it is used. Lacking that, twice + the system pagesize is used. Lacking a call to discover the system + pagesize, we just set default chunksize to 8192. + + The chunksize is a property of a given open netcdf descriptor ncid, + it is not a persistent property of the netcdf dataset." + + nciopp - pointer to pointer that will get address of newly created + and inited ncio struct. + + igetvpp - handle to pass back pointer to data from inital page + read, if this were ever used, which it isn't. +*/ +int +posixio_open(const char *path, + int ioflags, + off_t igeto, size_t igetsz, size_t *sizehintp, + ncio **nciopp, void **const igetvpp) +{ + ncio *nciop; + int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY; + int fd; + int status; + + if(path == NULL || *path == 0) + return EINVAL; + + nciop = ncio_px_new(path, ioflags); + if(nciop == NULL) + return ENOMEM; + +#ifdef O_BINARY + fSet(oflags, O_BINARY); +#endif +#ifdef vms + fd = open(path, oflags, 0, "ctx=stm"); +#else + fd = open(path, oflags, 0); +#endif + if(fd < 0) + { + status = errno; + goto unwind_new; + } + *((int *)&nciop->fd) = fd; /* cast away const */ + + if(*sizehintp < NCIO_MINBLOCKSIZE) + { + /* Use default */ + *sizehintp = blksize(fd); + } + else if(*sizehintp >= NCIO_MAXBLOCKSIZE) + { + /* Use maximum allowed value */ + *sizehintp = NCIO_MAXBLOCKSIZE; + } + else + { + *sizehintp = M_RNDUP(*sizehintp); + } + + if(fIsSet(nciop->ioflags, NC_SHARE)) + status = ncio_spx_init2(nciop, sizehintp); + else + status = ncio_px_init2(nciop, sizehintp, 0); + + if(status != ENOERR) + goto unwind_open; + + if(igetsz != 0) + { + status = nciop->get(nciop, + igeto, igetsz, + 0, + igetvpp); + if(status != ENOERR) + goto unwind_open; + } + + *nciopp = nciop; + return ENOERR; + +unwind_open: + (void) close(fd); + /*FALLTHRU*/ +unwind_new: + ncio_close(nciop,0); + return status; +} + +/* + * Get file size in bytes. + */ +static int +ncio_px_filesize(ncio *nciop, off_t *filesizep) +{ + struct stat sb; + + assert(nciop != NULL); + if (fstat(nciop->fd, &sb) < 0) + return errno; + *filesizep = sb.st_size; + return ENOERR; +} + +/* + * Sync any changes to disk, then truncate or extend file so its size + * is length. This is only intended to be called before close, if the + * file is open for writing and the actual size does not match the + * calculated size, perhaps as the result of having been previously + * written in NOFILL mode. + */ +static int +ncio_px_pad_length(ncio *nciop, off_t length) +{ + int status = ENOERR; + + if(nciop == NULL) + return EINVAL; + + if(!fIsSet(nciop->ioflags, NC_WRITE)) + return EPERM; /* attempt to write readonly file */ + + status = nciop->sync(nciop); + if(status != ENOERR) + return status; + + status = fgrow2(nciop->fd, length); + if(status != ENOERR) + return status; + return ENOERR; +} + + +/* Write out any dirty buffers to disk and + ensure that next read will get data from disk. + + Sync any changes, then close the open file associated with the ncio + struct, and free its memory. + + nciop - pointer to ncio to close. + + doUnlink - if true, unlink file +*/ +static int +ncio_px_close(ncio *nciop, int doUnlink) +{ + int status = ENOERR; + if(nciop == NULL) + return EINVAL; + status = nciop->sync(nciop); + (void) close(nciop->fd); + if(doUnlink) + (void) unlink(nciop->path); + ncio_px_free(nciop); + return status; +} + +static int +ncio_spx_close(ncio *nciop, int doUnlink) +{ + int status = ENOERR; + if(nciop == NULL) + return EINVAL; + status = nciop->sync(nciop); + (void) close(nciop->fd); + if(doUnlink) + (void) unlink(nciop->path); + ncio_spx_free(nciop); + return status; +} diff --git a/extern/src_netcdf4/pstdint.h b/extern/src_netcdf4/pstdint.h new file mode 100644 index 0000000000000000000000000000000000000000..6a334bae984fbb4c728510dff226dc61eda6e94d --- /dev/null +++ b/extern/src_netcdf4/pstdint.h @@ -0,0 +1,799 @@ +/* A portable stdint.h + **************************************************************************** + * BSD License: + **************************************************************************** + * + * Copyright (c) 2005-2007 Paul Hsieh + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 0.1.11 + * + * The ANSI C standard committee, for the C99 standard, specified the + * inclusion of a new standard include file called stdint.h. This is + * a very useful and long desired include file which contains several + * very precise definitions for integer scalar types that is + * critically important for making portable several classes of + * applications including cryptography, hashing, variable length + * integer libraries and so on. But for most developers its likely + * useful just for programming sanity. + * + * The problem is that most compiler vendors have decided not to + * implement the C99 standard, and the next C++ language standard + * (which has a lot more mindshare these days) will be a long time in + * coming and its unknown whether or not it will include stdint.h or + * how much adoption it will have. Either way, it will be a long time + * before all compilers come with a stdint.h and it also does nothing + * for the extremely large number of compilers available today which + * do not include this file, or anything comparable to it. + * + * So that's what this file is all about. Its an attempt to build a + * single universal include file that works on as many platforms as + * possible to deliver what stdint.h is supposed to. A few things + * that should be noted about this file: + * + * 1) It is not guaranteed to be portable and/or present an identical + * interface on all platforms. The extreme variability of the + * ANSI C standard makes this an impossibility right from the + * very get go. Its really only meant to be useful for the vast + * majority of platforms that possess the capability of + * implementing usefully and precisely defined, standard sized + * integer scalars. Systems which are not intrinsically 2s + * complement may produce invalid constants. + * + * 2) There is an unavoidable use of non-reserved symbols. + * + * 3) Other standard include files are invoked. + * + * 4) This file may come in conflict with future platforms that do + * include stdint.h. The hope is that one or the other can be + * used with no real difference. + * + * 5) In the current verison, if your platform can't represent + * int32_t, int16_t and int8_t, it just dumps out with a compiler + * error. + * + * 6) 64 bit integers may or may not be defined. Test for their + * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX. + * Note that this is different from the C99 specification which + * requires the existence of 64 bit support in the compiler. If + * this is not defined for your platform, yet it is capable of + * dealing with 64 bits then it is because this file has not yet + * been extended to cover all of your system's capabilities. + * + * 7) (u)intptr_t may or may not be defined. Test for its presence + * with the test: #ifdef PTRDIFF_MAX. If this is not defined + * for your platform, then it is because this file has not yet + * been extended to cover all of your system's capabilities, not + * because its optional. + * + * 8) The following might not been defined even if your platform is + * capable of defining it: + * + * WCHAR_MIN + * WCHAR_MAX + * (u)int64_t + * PTRDIFF_MIN + * PTRDIFF_MAX + * (u)intptr_t + * + * 9) The following have not been defined: + * + * WINT_MIN + * WINT_MAX + * + * 10) The criteria for defining (u)int_least(*)_t isn't clear, + * except for systems which don't have a type that precisely + * defined 8, 16, or 32 bit types (which this include file does + * not support anyways). Default definitions have been given. + * + * 11) The criteria for defining (u)int_fast(*)_t isn't something I + * would trust to any particular compiler vendor or the ANSI C + * committee. It is well known that "compatible systems" are + * commonly created that have very different performance + * characteristics from the systems they are compatible with, + * especially those whose vendors make both the compiler and the + * system. Default definitions have been given, but its strongly + * recommended that users never use these definitions for any + * reason (they do *NOT* deliver any serious guarantee of + * improved performance -- not in this file, nor any vendor's + * stdint.h). + * + * 12) The following macros: + * + * PRINTF_INTMAX_MODIFIER + * PRINTF_INT64_MODIFIER + * PRINTF_INT32_MODIFIER + * PRINTF_INT16_MODIFIER + * PRINTF_LEAST64_MODIFIER + * PRINTF_LEAST32_MODIFIER + * PRINTF_LEAST16_MODIFIER + * PRINTF_INTPTR_MODIFIER + * + * are strings which have been defined as the modifiers required + * for the "d", "u" and "x" printf formats to correctly output + * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t, + * (u)least32_t, (u)least16_t and (u)intptr_t types respectively. + * PRINTF_INTPTR_MODIFIER is not defined for some systems which + * provide their own stdint.h. PRINTF_INT64_MODIFIER is not + * defined if INT64_MAX is not defined. These are an extension + * beyond what C99 specifies must be in stdint.h. + * + * In addition, the following macros are defined: + * + * PRINTF_INTMAX_HEX_WIDTH + * PRINTF_INT64_HEX_WIDTH + * PRINTF_INT32_HEX_WIDTH + * PRINTF_INT16_HEX_WIDTH + * PRINTF_INT8_HEX_WIDTH + * PRINTF_INTMAX_DEC_WIDTH + * PRINTF_INT64_DEC_WIDTH + * PRINTF_INT32_DEC_WIDTH + * PRINTF_INT16_DEC_WIDTH + * PRINTF_INT8_DEC_WIDTH + * + * Which specifies the maximum number of characters required to + * print the number of that type in either hexadecimal or decimal. + * These are an extension beyond what C99 specifies must be in + * stdint.h. + * + * Compilers tested (all with 0 warnings at their highest respective + * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32 + * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio + * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3 + * + * This file should be considered a work in progress. Suggestions for + * improvements, especially those which increase coverage are strongly + * encouraged. + * + * Acknowledgements + * + * The following people have made significant contributions to the + * development and testing of this file: + * + * Chris Howie + * John Steele Scott + * Dave Thorup + * + */ + +#include +#include +#include + +/* + * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and + * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. + */ + +#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) )) && !defined (_PSTDINT_H_INCLUDED) +#include +#define _PSTDINT_H_INCLUDED +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +# endif +# ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +# endif +# ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +# endif +# ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +# endif +# ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "20" +# endif +# ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +# endif +# ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +# endif +# ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH +# endif + +/* + * Something really weird is going on with Open Watcom. Just pull some of + * these duplicated definitions from Open Watcom's stdint.h file for now. + */ + +# if defined (__WATCOMC__) && __WATCOMC__ >= 1250 +# if !defined (INT64_C) +# define INT64_C(x) (x + (INT64_MAX - INT64_MAX)) +# endif +# if !defined (UINT64_C) +# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) +# endif +# if !defined (INT32_C) +# define INT32_C(x) (x + (INT32_MAX - INT32_MAX)) +# endif +# if !defined (UINT32_C) +# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX)) +# endif +# if !defined (INT16_C) +# define INT16_C(x) (x) +# endif +# if !defined (UINT16_C) +# define UINT16_C(x) (x) +# endif +# if !defined (INT8_C) +# define INT8_C(x) (x) +# endif +# if !defined (UINT8_C) +# define UINT8_C(x) (x) +# endif +# if !defined (UINT64_MAX) +# define UINT64_MAX 18446744073709551615ULL +# endif +# if !defined (INT64_MAX) +# define INT64_MAX 9223372036854775807LL +# endif +# if !defined (UINT32_MAX) +# define UINT32_MAX 4294967295UL +# endif +# if !defined (INT32_MAX) +# define INT32_MAX 2147483647L +# endif +# if !defined (INTMAX_MAX) +# define INTMAX_MAX INT64_MAX +# endif +# if !defined (INTMAX_MIN) +# define INTMAX_MIN INT64_MIN +# endif +# endif +#endif + +#ifndef _PSTDINT_H_INCLUDED +#define _PSTDINT_H_INCLUDED + +#ifndef SIZE_MAX +# define SIZE_MAX (~(size_t)0) +#endif + +/* + * Deduce the type assignments from limits.h under the assumption that + * integer sizes in bits are powers of 2, and follow the ANSI + * definitions. + */ + +#ifndef UINT8_MAX +# define UINT8_MAX 0xff +#endif +#ifndef uint8_t +# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S) + typedef unsigned char uint8_t; +# define UINT8_C(v) ((uint8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef INT8_MAX +# define INT8_MAX 0x7f +#endif +#ifndef INT8_MIN +# define INT8_MIN INT8_C(0x80) +#endif +#ifndef int8_t +# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S) + typedef signed char int8_t; +# define INT8_C(v) ((int8_t) v) +# else +# error "Platform not supported" +# endif +#endif + +#ifndef UINT16_MAX +# define UINT16_MAX 0xffff +#endif +#ifndef uint16_t +#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S) + typedef unsigned int uint16_t; +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +# define UINT16_C(v) ((uint16_t) (v)) +#elif (USHRT_MAX == UINT16_MAX) + typedef unsigned short uint16_t; +# define UINT16_C(v) ((uint16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT16_MAX +# define INT16_MAX 0x7fff +#endif +#ifndef INT16_MIN +# define INT16_MIN INT16_C(0x8000) +#endif +#ifndef int16_t +#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S) + typedef signed int int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "" +# endif +#elif (SHRT_MAX == INT16_MAX) + typedef signed short int16_t; +# define INT16_C(v) ((int16_t) (v)) +# ifndef PRINTF_INT16_MODIFIER +# define PRINTF_INT16_MODIFIER "h" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef UINT32_MAX +# define UINT32_MAX (0xffffffffUL) +#endif +#ifndef uint32_t +#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S) + typedef unsigned long uint32_t; +# define UINT32_C(v) v ## UL +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (UINT_MAX == UINT32_MAX) + typedef unsigned int uint32_t; +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +# define UINT32_C(v) v ## U +#elif (USHRT_MAX == UINT32_MAX) + typedef unsigned short uint32_t; +# define UINT32_C(v) ((unsigned short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +#ifndef INT32_MAX +# define INT32_MAX (0x7fffffffL) +#endif +#ifndef INT32_MIN +# define INT32_MIN INT32_C(0x80000000) +#endif +#ifndef int32_t +#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S) + typedef signed long int32_t; +# define INT32_C(v) v ## L +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "l" +# endif +#elif (INT_MAX == INT32_MAX) + typedef signed int int32_t; +# define INT32_C(v) v +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#elif (SHRT_MAX == INT32_MAX) + typedef signed short int32_t; +# define INT32_C(v) ((short) (v)) +# ifndef PRINTF_INT32_MODIFIER +# define PRINTF_INT32_MODIFIER "" +# endif +#else +#error "Platform not supported" +#endif +#endif + +/* + * The macro stdint_int64_defined is temporarily used to record + * whether or not 64 integer support is available. It must be + * defined for any 64 integer extensions for new platforms that are + * added. + */ + +#undef stdint_int64_defined +#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S) +# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# endif +#endif + +#if !defined (stdint_int64_defined) +# if defined(__GNUC__) +# define stdint_int64_defined + __extension__ typedef long long int64_t; + __extension__ typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S) +# define stdint_int64_defined + typedef long long int64_t; + typedef unsigned long long uint64_t; +# define UINT64_C(v) v ## ULL +# define INT64_C(v) v ## LL +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "ll" +# endif +# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC) +# define stdint_int64_defined + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +# define UINT64_C(v) v ## UI64 +# define INT64_C(v) v ## I64 +# ifndef PRINTF_INT64_MODIFIER +# define PRINTF_INT64_MODIFIER "I64" +# endif +# endif +#endif + +#if !defined (LONG_LONG_MAX) && defined (INT64_C) +# define LONG_LONG_MAX INT64_C (9223372036854775807) +#endif +#ifndef ULONG_LONG_MAX +# define ULONG_LONG_MAX UINT64_C (18446744073709551615) +#endif + +#if !defined (INT64_MAX) && defined (INT64_C) +# define INT64_MAX INT64_C (9223372036854775807) +#endif +#if !defined (INT64_MIN) && defined (INT64_C) +# define INT64_MIN INT64_C (-9223372036854775808) +#endif +#if !defined (UINT64_MAX) && defined (INT64_C) +# define UINT64_MAX UINT64_C (18446744073709551615) +#endif + +/* + * Width of hexadecimal for number field. + */ + +#ifndef PRINTF_INT64_HEX_WIDTH +# define PRINTF_INT64_HEX_WIDTH "16" +#endif +#ifndef PRINTF_INT32_HEX_WIDTH +# define PRINTF_INT32_HEX_WIDTH "8" +#endif +#ifndef PRINTF_INT16_HEX_WIDTH +# define PRINTF_INT16_HEX_WIDTH "4" +#endif +#ifndef PRINTF_INT8_HEX_WIDTH +# define PRINTF_INT8_HEX_WIDTH "2" +#endif + +#ifndef PRINTF_INT64_DEC_WIDTH +# define PRINTF_INT64_DEC_WIDTH "20" +#endif +#ifndef PRINTF_INT32_DEC_WIDTH +# define PRINTF_INT32_DEC_WIDTH "10" +#endif +#ifndef PRINTF_INT16_DEC_WIDTH +# define PRINTF_INT16_DEC_WIDTH "5" +#endif +#ifndef PRINTF_INT8_DEC_WIDTH +# define PRINTF_INT8_DEC_WIDTH "3" +#endif + +/* + * Ok, lets not worry about 128 bit integers for now. Moore's law says + * we don't need to worry about that until about 2040 at which point + * we'll have bigger things to worry about. + */ + +#ifdef stdint_int64_defined + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; +# define INTMAX_MAX INT64_MAX +# define INTMAX_MIN INT64_MIN +# define UINTMAX_MAX UINT64_MAX +# define UINTMAX_C(v) UINT64_C(v) +# define INTMAX_C(v) INT64_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH +# endif +#else + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# define INTMAX_MAX INT32_MAX +# define UINTMAX_MAX UINT32_MAX +# define UINTMAX_C(v) UINT32_C(v) +# define INTMAX_C(v) INT32_C(v) +# ifndef PRINTF_INTMAX_MODIFIER +# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER +# endif +# ifndef PRINTF_INTMAX_HEX_WIDTH +# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH +# endif +# ifndef PRINTF_INTMAX_DEC_WIDTH +# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH +# endif +#endif + +/* + * Because this file currently only supports platforms which have + * precise powers of 2 as bit sizes for the default integers, the + * least definitions are all trivial. Its possible that a future + * version of this file could have different definitions. + */ + +#ifndef stdint_least_defined + typedef int8_t int_least8_t; + typedef uint8_t uint_least8_t; + typedef int16_t int_least16_t; + typedef uint16_t uint_least16_t; + typedef int32_t int_least32_t; + typedef uint32_t uint_least32_t; +# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER +# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER +# define UINT_LEAST8_MAX UINT8_MAX +# define INT_LEAST8_MAX INT8_MAX +# define UINT_LEAST16_MAX UINT16_MAX +# define INT_LEAST16_MAX INT16_MAX +# define UINT_LEAST32_MAX UINT32_MAX +# define INT_LEAST32_MAX INT32_MAX +# define INT_LEAST8_MIN INT8_MIN +# define INT_LEAST16_MIN INT16_MIN +# define INT_LEAST32_MIN INT32_MIN +# ifdef stdint_int64_defined + typedef int64_t int_least64_t; + typedef uint64_t uint_least64_t; +# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER +# define UINT_LEAST64_MAX UINT64_MAX +# define INT_LEAST64_MAX INT64_MAX +# define INT_LEAST64_MIN INT64_MIN +# endif +#endif +#undef stdint_least_defined + +/* + * The ANSI C committee pretending to know or specify anything about + * performance is the epitome of misguided arrogance. The mandate of + * this file is to *ONLY* ever support that absolute minimum + * definition of the fast integer types, for compatibility purposes. + * No extensions, and no attempt to suggest what may or may not be a + * faster integer type will ever be made in this file. Developers are + * warned to stay away from these types when using this or any other + * stdint.h. + */ + +typedef int_least8_t int_fast8_t; +typedef uint_least8_t uint_fast8_t; +typedef int_least16_t int_fast16_t; +typedef uint_least16_t uint_fast16_t; +typedef int_least32_t int_fast32_t; +typedef uint_least32_t uint_fast32_t; +#define UINT_FAST8_MAX UINT_LEAST8_MAX +#define INT_FAST8_MAX INT_LEAST8_MAX +#define UINT_FAST16_MAX UINT_LEAST16_MAX +#define INT_FAST16_MAX INT_LEAST16_MAX +#define UINT_FAST32_MAX UINT_LEAST32_MAX +#define INT_FAST32_MAX INT_LEAST32_MAX +#define INT_FAST8_MIN INT_LEAST8_MIN +#define INT_FAST16_MIN INT_LEAST16_MIN +#define INT_FAST32_MIN INT_LEAST32_MIN +#ifdef stdint_int64_defined + typedef int_least64_t int_fast64_t; + typedef uint_least64_t uint_fast64_t; +# define UINT_FAST64_MAX UINT_LEAST64_MAX +# define INT_FAST64_MAX INT_LEAST64_MAX +# define INT_FAST64_MIN INT_LEAST64_MIN +#endif + +#undef stdint_int64_defined + +/* + * Whatever piecemeal, per compiler thing we can do about the wchar_t + * type limits. + */ + +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) +# include +# ifndef WCHAR_MIN +# define WCHAR_MIN 0 +# endif +# ifndef WCHAR_MAX +# define WCHAR_MAX ((wchar_t)-1) +# endif +#endif + +/* + * Whatever piecemeal, per compiler/platform thing we can do about the + * (u)intptr_t types and limits. + */ + +#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED) +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +#ifndef STDINT_H_UINTPTR_T_DEFINED +# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) +# define stdint_intptr_bits 64 +# elif defined (__WATCOMC__) || defined (__TURBOC__) +# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) +# define stdint_intptr_bits 16 +# else +# define stdint_intptr_bits 32 +# endif +# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) +# define stdint_intptr_bits 32 +# elif defined (__INTEL_COMPILER) +/* TODO -- what will Intel do about x86-64? */ +# endif + +# ifdef stdint_intptr_bits +# define stdint_intptr_glue3_i(a,b,c) a##b##c +# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c) +# ifndef PRINTF_INTPTR_MODIFIER +# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER) +# endif +# ifndef PTRDIFF_MAX +# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef PTRDIFF_MIN +# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef UINTPTR_MAX +# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MAX +# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX) +# endif +# ifndef INTPTR_MIN +# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN) +# endif +# ifndef INTPTR_C +# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x) +# endif +# ifndef UINTPTR_C +# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x) +# endif + typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t; + typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t; +# else +/* TODO -- This following is likely wrong for some platforms, and does + nothing for the definition of uintptr_t. */ + typedef ptrdiff_t intptr_t; +# endif +# define STDINT_H_UINTPTR_T_DEFINED +#endif + +/* + * Assumes sig_atomic_t is signed and we have a 2s complement machine. + */ + +#ifndef SIG_ATOMIC_MAX +# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1) +#endif + +#endif + +#if defined (__TEST_PSTDINT_FOR_CORRECTNESS) + +/* + * Please compile with the maximum warning settings to make sure macros are not + * defined more than once. + */ + +#include +#include +#include + +#define glue3_aux(x,y,z) x ## y ## z +#define glue3(x,y,z) glue3_aux(x,y,z) + +#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,=) glue3(UINT,bits,_C) (0); +#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,=) glue3(INT,bits,_C) (0); + +#define DECL(us,bits) glue3(DECL,us,) (bits) + +#define TESTUMAX(bits) glue3(u,bits,=) glue3(~,u,bits); if (glue3(UINT,bits,_MAX) glue3(!=,u,bits)) printf ("Something wrong with UINT%d_MAX\n", bits) + +int main () { + DECL(I,8) + DECL(U,8) + DECL(I,16) + DECL(U,16) + DECL(I,32) + DECL(U,32) +#ifdef INT64_MAX + DECL(I,64) + DECL(U,64) +#endif + intmax_t imax = INTMAX_C(0); + uintmax_t umax = UINTMAX_C(0); + char str0[256], str1[256]; + + sprintf (str0, "%d %x\n", 0, ~0); + + sprintf (str1, "%d %x\n", i8, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with i8 : %s\n", str1); + sprintf (str1, "%u %x\n", u8, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with u8 : %s\n", str1); + sprintf (str1, "%d %x\n", i16, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with i16 : %s\n", str1); + sprintf (str1, "%u %x\n", u16, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with u16 : %s\n", str1); + sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with i32 : %s\n", str1); + sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with u32 : %s\n", str1); +#ifdef INT64_MAX + sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with i64 : %s\n", str1); +#endif + sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with imax : %s\n", str1); + sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0); + if (0 != strcmp (str0, str1)) printf ("Something wrong with umax : %s\n", str1); + + TESTUMAX(8); + TESTUMAX(16); + TESTUMAX(32); +#ifdef INT64_MAX + TESTUMAX(64); +#endif + + return EXIT_SUCCESS; +} + +#endif diff --git a/extern/src_netcdf4/putget.c b/extern/src_netcdf4/putget.c new file mode 100644 index 0000000000000000000000000000000000000000..4247748384a306850c6b462bc82fac4445b42d1d --- /dev/null +++ b/extern/src_netcdf4/putget.c @@ -0,0 +1,5362 @@ +/* Do not edit this file. It is produced from the corresponding .m4 source */ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: putget.m4,v 2.79 2010/05/29 22:25:01 russ Exp $ */ + +#include "config.h" +#include +#include +#include + +#include "netcdf.h" +#include "nc.h" +#include "ncx.h" +#include "fbits.h" +#include "onstack.h" +#ifdef LOCKNUMREC +# include /* for SGI/Cray SHMEM routines */ +# ifdef LN_TEST +# include +# endif +#endif +#include "nc3dispatch.h" + + +#undef MIN /* system may define MIN somewhere and complain */ +#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn)) + +static int +readNCv(const NC* ncp, const NC_var* varp, const size_t* start, + const size_t nelems, void* value, const nc_type memtype); +static int +writeNCv(NC* ncp, const NC_var* varp, const size_t* start, + const size_t nelems, const void* value, const nc_type memtype); + + +/* #define ODEBUG 1 */ + +#if ODEBUG +#include +/* + * Print the values of an array of size_t + */ +void +arrayp(const char *label, size_t count, const size_t *array) +{ + (void) fprintf(stderr, "%s", label); + (void) fputc('\t',stderr); + for(; count > 0; count--, array++) + (void) fprintf(stderr," %lu", (unsigned long)*array); + (void) fputc('\n',stderr); +} +#endif /* ODEBUG */ + + +/* Begin fill */ +/* + * This is tunable parameter. + * It essentially controls the tradeoff between the number of times + * memcpy() gets called to copy the external data to fill + * a large buffer vs the number of times its called to + * prepare the external data. + */ +#if _SX +/* NEC SX specific optimization */ +#define NFILL 2048 +#else +#define NFILL 16 +#endif + + + +/* + * Next 6 type specific functions + * Fill a some memory with the default special value. + * Formerly +NC_arrayfill() + */ +static int +NC_fill_schar( + void **xpp, + size_t nelems) /* how many */ +{ + schar fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR]; + + assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); + + { + schar *vp = fillp; /* lower bound of area to be filled */ + const schar *const end = vp + nelems; + while(vp < end) + { + *vp++ = NC_FILL_BYTE; + } + } + return ncx_putn_schar_schar(xpp, nelems, fillp); +} + +static int +NC_fill_char( + void **xpp, + size_t nelems) /* how many */ +{ + char fillp[NFILL * sizeof(double)/X_SIZEOF_CHAR]; + + assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); + + { + char *vp = fillp; /* lower bound of area to be filled */ + const char *const end = vp + nelems; + while(vp < end) + { + *vp++ = NC_FILL_CHAR; + } + } + return ncx_putn_char_char(xpp, nelems, fillp); +} + +static int +NC_fill_short( + void **xpp, + size_t nelems) /* how many */ +{ + short fillp[NFILL * sizeof(double)/X_SIZEOF_SHORT]; + + assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); + + { + short *vp = fillp; /* lower bound of area to be filled */ + const short *const end = vp + nelems; + while(vp < end) + { + *vp++ = NC_FILL_SHORT; + } + } + return ncx_putn_short_short(xpp, nelems, fillp); +} + + +#if (SIZEOF_INT >= X_SIZEOF_INT) +static int +NC_fill_int( + void **xpp, + size_t nelems) /* how many */ +{ + int fillp[NFILL * sizeof(double)/X_SIZEOF_INT]; + + assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); + + { + int *vp = fillp; /* lower bound of area to be filled */ + const int *const end = vp + nelems; + while(vp < end) + { + *vp++ = NC_FILL_INT; + } + } + return ncx_putn_int_int(xpp, nelems, fillp); +} + +#elif SIZEOF_LONG == X_SIZEOF_INT +static int +NC_fill_int( + void **xpp, + size_t nelems) /* how many */ +{ + long fillp[NFILL * sizeof(double)/X_SIZEOF_INT]; + + assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); + + { + long *vp = fillp; /* lower bound of area to be filled */ + const long *const end = vp + nelems; + while(vp < end) + { + *vp++ = NC_FILL_INT; + } + } + return ncx_putn_int_long(xpp, nelems, fillp); +} + +#else +#error "NC_fill_int implementation" +#endif + +static int +NC_fill_float( + void **xpp, + size_t nelems) /* how many */ +{ + float fillp[NFILL * sizeof(double)/X_SIZEOF_FLOAT]; + + assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); + + { + float *vp = fillp; /* lower bound of area to be filled */ + const float *const end = vp + nelems; + while(vp < end) + { + *vp++ = NC_FILL_FLOAT; + } + } + return ncx_putn_float_float(xpp, nelems, fillp); +} + +static int +NC_fill_double( + void **xpp, + size_t nelems) /* how many */ +{ + double fillp[NFILL * sizeof(double)/X_SIZEOF_DOUBLE]; + + assert(nelems <= sizeof(fillp)/sizeof(fillp[0])); + + { + double *vp = fillp; /* lower bound of area to be filled */ + const double *const end = vp + nelems; + while(vp < end) + { + *vp++ = NC_FILL_DOUBLE; + } + } + return ncx_putn_double_double(xpp, nelems, fillp); +} + + + + + +/* + * Fill the external space for variable 'varp' values at 'recno' with + * the appropriate value. If 'varp' is not a record variable, fill the + * whole thing. For the special case when 'varp' is the only record + * variable and it is of type byte, char, or short, varsize should be + * ncp->recsize, otherwise it should be varp->len. + * Formerly +xdr_NC_fill() + */ +int +fill_NC_var(NC *ncp, const NC_var *varp, size_t varsize, size_t recno) +{ + char xfillp[NFILL * X_SIZEOF_DOUBLE]; + const size_t step = varp->xsz; + const size_t nelems = sizeof(xfillp)/step; + const size_t xsz = varp->xsz * nelems; + NC_attr **attrpp = NULL; + off_t offset; + size_t remaining = varsize; + + void *xp; + int status = NC_NOERR; + + /* + * Set up fill value + */ + attrpp = NC_findattr(&varp->attrs, _FillValue); + if( attrpp != NULL ) + { + /* User defined fill value */ + if( (*attrpp)->type != varp->type || (*attrpp)->nelems != 1 ) + { + return NC_EBADTYPE; + } + else + { + /* Use the user defined value */ + char *cp = xfillp; + const char *const end = &xfillp[sizeof(xfillp)]; + + assert(step <= (*attrpp)->xsz); + + for( /*NADA*/; cp < end; cp += step) + { + (void) memcpy(cp, (*attrpp)->xvalue, step); + } + } + } + else + { + /* use the default */ + + assert(xsz % X_ALIGN == 0); + assert(xsz <= sizeof(xfillp)); + + xp = xfillp; + + switch(varp->type){ + case NC_BYTE : + status = NC_fill_schar(&xp, nelems); + break; + case NC_CHAR : + status = NC_fill_char(&xp, nelems); + break; + case NC_SHORT : + status = NC_fill_short(&xp, nelems); + break; + case NC_INT : + status = NC_fill_int(&xp, nelems); + break; + case NC_FLOAT : + status = NC_fill_float(&xp, nelems); + break; + case NC_DOUBLE : + status = NC_fill_double(&xp, nelems); + break; + default : + assert("fill_NC_var invalid type" == 0); + status = NC_EBADTYPE; + break; + } + if(status != NC_NOERR) + return status; + + assert(xp == xfillp + xsz); + } + + /* + * copyout: + * xfillp now contains 'nelems' elements of the fill value + * in external representation. + */ + + /* + * Copy it out. + */ + + offset = varp->begin; + if(IS_RECVAR(varp)) + { + offset += (off_t)ncp->recsize * recno; + } + + assert(remaining > 0); + for(;;) + { + const size_t chunksz = MIN(remaining, ncp->chunk); + size_t ii; + + status = ncio_get(ncp->nciop, offset, chunksz, + RGN_WRITE, &xp); + if(status != NC_NOERR) + { + return status; + } + + /* + * fill the chunksz buffer in units of xsz + */ + for(ii = 0; ii < chunksz/xsz; ii++) + { + (void) memcpy(xp, xfillp, xsz); + xp = (char *)xp + xsz; + } + /* + * Deal with any remainder + */ + { + const size_t rem = chunksz % xsz; + if(rem != 0) + { + (void) memcpy(xp, xfillp, rem); + /* xp = (char *)xp + xsz; */ + } + + } + + status = ncio_rel(ncp->nciop, offset, RGN_MODIFIED); + + if(status != NC_NOERR) + { + break; + } + + remaining -= chunksz; + if(remaining == 0) + break; /* normal loop exit */ + offset += chunksz; + + } + + return status; +} +/* End fill */ + + +/* + * Add a record containing the fill values. + */ +static int +NCfillrecord(NC *ncp, const NC_var *const *varpp, size_t recno) +{ + size_t ii = 0; + for(; ii < ncp->vars.nelems; ii++, varpp++) + { + if( !IS_RECVAR(*varpp) ) + { + continue; /* skip non-record variables */ + } + { + const int status = fill_NC_var(ncp, *varpp, (*varpp)->len, recno); + if(status != NC_NOERR) + return status; + } + } + return NC_NOERR; +} + + +/* + * Add a record containing the fill values in the special case when + * there is exactly one record variable, where we don't require each + * record to be four-byte aligned (no record padding). + */ +static int +NCfillspecialrecord(NC *ncp, const NC_var *varp, size_t recno) +{ + int status; + assert(IS_RECVAR(varp)); + status = fill_NC_var(ncp, varp, ncp->recsize, recno); + if(status != NC_NOERR) + return status; + return NC_NOERR; +} + + +/* + * It is advantageous to + * #define TOUCH_LAST + * when using memory mapped io. + */ +#if TOUCH_LAST +/* + * Grow the file to a size which can contain recno + */ +static int +NCtouchlast(NC *ncp, const NC_var *const *varpp, size_t recno) +{ + int status = NC_NOERR; + const NC_var *varp = NULL; + + { + size_t ii = 0; + for(; ii < ncp->vars.nelems; ii++, varpp++) + { + if( !IS_RECVAR(*varpp) ) + { + continue; /* skip non-record variables */ + } + varp = *varpp; + } + } + assert(varp != NULL); + assert( IS_RECVAR(varp) ); + { + const off_t offset = varp->begin + + (off_t)(recno-1) * (off_t)ncp->recsize + + (off_t)(varp->len - varp->xsz); + void *xp; + + + status = ncio_get(ncp->nciop, offset, varp->xsz, + RGN_WRITE, &xp); + if(status != NC_NOERR) + return status; + (void)memset(xp, 0, varp->xsz); + status = ncio_rel(ncp->nciop, offset, RGN_MODIFIED); + } + return status; +} +#endif /* TOUCH_LAST */ + + +/* + * Ensure that the netcdf file has 'numrecs' records, + * add records and fill as neccessary. + */ +static int +NCvnrecs(NC *ncp, size_t numrecs) +{ + int status = NC_NOERR; +#ifdef LOCKNUMREC + ushmem_t myticket = 0, nowserving = 0; + ushmem_t numpe = (ushmem_t) _num_pes(); + + /* get ticket and wait */ + myticket = shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_LOCK, + ncp->lock[LOCKNUMREC_BASEPE]); +#ifdef LN_TEST + fprintf(stderr,"%d of %d : ticket = %hu\n", + _my_pe(), _num_pes(), myticket); +#endif + do { + shmem_short_get((shmem_t *) &nowserving, + (shmem_t *) ncp->lock + LOCKNUMREC_SERVING, 1, + ncp->lock[LOCKNUMREC_BASEPE]); +#ifdef LN_TEST + fprintf(stderr,"%d of %d : serving = %hu\n", + _my_pe(), _num_pes(), nowserving); +#endif + /* work-around for non-unique tickets */ + if (nowserving > myticket && nowserving < myticket + numpe ) { + /* get a new ticket ... you've been bypassed */ + /* and handle the unlikely wrap-around effect */ + myticket = shmem_short_finc( + (shmem_t *) ncp->lock + LOCKNUMREC_LOCK, + ncp->lock[LOCKNUMREC_BASEPE]); +#ifdef LN_TEST + fprintf(stderr,"%d of %d : new ticket = %hu\n", + _my_pe(), _num_pes(), myticket); +#endif + } + } while(nowserving != myticket); + /* now our turn to check & update value */ +#endif + + if(numrecs > NC_get_numrecs(ncp)) + { + + +#if TOUCH_LAST + status = NCtouchlast(ncp, + (const NC_var *const*)ncp->vars.value, + numrecs); + if(status != NC_NOERR) + goto common_return; +#endif /* TOUCH_LAST */ + + set_NC_ndirty(ncp); + + if(!NC_dofill(ncp)) + { + /* Simply set the new numrecs value */ + NC_set_numrecs(ncp, numrecs); + } + else + { + /* Treat two cases differently: + - exactly one record variable (no padding) + - multiple record variables (each record padded + to 4-byte alignment) + */ + NC_var **vpp = (NC_var **)ncp->vars.value; + NC_var *const *const end = &vpp[ncp->vars.nelems]; + NC_var *recvarp = NULL; /* last record var */ + int numrecvars = 0; + size_t cur_nrecs; + + /* determine how many record variables */ + for( /*NADA*/; vpp < end; vpp++) { + if(IS_RECVAR(*vpp)) { + recvarp = *vpp; + numrecvars++; + } + } + + if (numrecvars != 1) { /* usual case */ + /* Fill each record out to numrecs */ + while((cur_nrecs = NC_get_numrecs(ncp)) < numrecs) + { + status = NCfillrecord(ncp, + (const NC_var *const*)ncp->vars.value, + cur_nrecs); + if(status != NC_NOERR) + { + break; + } + NC_increase_numrecs(ncp, cur_nrecs +1); + } + if(status != NC_NOERR) + goto common_return; + } else { /* special case */ + /* Fill each record out to numrecs */ + while((cur_nrecs = NC_get_numrecs(ncp)) < numrecs) + { + status = NCfillspecialrecord(ncp, + recvarp, + cur_nrecs); + if(status != NC_NOERR) + { + break; + } + NC_increase_numrecs(ncp, cur_nrecs +1); + } + if(status != NC_NOERR) + goto common_return; + + } + } + + if(NC_doNsync(ncp)) + { + status = write_numrecs(ncp); + } + + } +common_return: +#ifdef LOCKNUMREC + /* finished with our lock - increment serving number */ + (void) shmem_short_finc((shmem_t *) ncp->lock + LOCKNUMREC_SERVING, + ncp->lock[LOCKNUMREC_BASEPE]); +#endif + return status; +} + + +/* + * Check whether 'coord' values are valid for the variable. + */ +static int +NCcoordck(NC *ncp, const NC_var *varp, const size_t *coord) +{ + const size_t *ip; + size_t *up; + + if(varp->ndims == 0) + return NC_NOERR; /* 'scalar' variable */ + + if(IS_RECVAR(varp)) + { + if(*coord > X_UINT_MAX) /* rkr: bug fix from previous X_INT_MAX */ + return NC_EINVALCOORDS; /* sanity check */ + if(NC_readonly(ncp) && *coord >= NC_get_numrecs(ncp)) + { + if(!NC_doNsync(ncp)) + return NC_EINVALCOORDS; + /* else */ + { + /* Update from disk and check again */ + const int status = read_numrecs(ncp); + if(status != NC_NOERR) + return status; + if(*coord >= NC_get_numrecs(ncp)) + return NC_EINVALCOORDS; + } + } + ip = coord + 1; + up = varp->shape + 1; + } + else + { + ip = coord; + up = varp->shape; + } + +#ifdef CDEBUG +fprintf(stderr," NCcoordck: coord %ld, count %d, ip %ld\n", + coord, varp->ndims, ip ); +#endif /* CDEBUG */ + + for(; ip < coord + varp->ndims; ip++, up++) + { + +#ifdef CDEBUG +fprintf(stderr," NCcoordck: ip %p, *ip %ld, up %p, *up %lu\n", + ip, *ip, up, *up ); +#endif /* CDEBUG */ + + /* cast needed for braindead systems with signed size_t */ + if((unsigned long) *ip >= (unsigned long) *up ) + return NC_EINVALCOORDS; + } + + return NC_NOERR; +} + + +/* + * Check whether 'edges' are valid for the variable and 'start' + */ +/*ARGSUSED*/ +static int +NCedgeck(const NC *ncp, const NC_var *varp, + const size_t *start, const size_t *edges) +{ + const size_t *const end = start + varp->ndims; + const size_t *shp = varp->shape; + + if(varp->ndims == 0) + return NC_NOERR; /* 'scalar' variable */ + + if(IS_RECVAR(varp)) + { + start++; + edges++; + shp++; + } + + for(; start < end; start++, edges++, shp++) + { + /* cast needed for braindead systems with signed size_t */ + if((unsigned long) *edges > *shp || + (unsigned long) *start + (unsigned long) *edges > *shp) + { + return(NC_EEDGE); + } + } + return NC_NOERR; +} + + +/* + * Translate the (variable, coord) pair into a seek index + */ +static off_t +NC_varoffset(const NC *ncp, const NC_var *varp, const size_t *coord) +{ + if(varp->ndims == 0) /* 'scalar' variable */ + return varp->begin; + + if(varp->ndims == 1) + { + if(IS_RECVAR(varp)) + return varp->begin + + (off_t)(*coord) * (off_t)ncp->recsize; + /* else */ + return varp->begin + (off_t)(*coord) * (off_t)varp->xsz; + } + /* else */ + { + off_t lcoord = (off_t)coord[varp->ndims -1]; + + off_t *up = varp->dsizes +1; + const size_t *ip = coord; + const off_t *const end = varp->dsizes + varp->ndims; + + if(IS_RECVAR(varp)) + up++, ip++; + + for(; up < end; up++, ip++) + lcoord += (off_t)(*up) * (off_t)(*ip); + + lcoord *= varp->xsz; + + if(IS_RECVAR(varp)) + lcoord += (off_t)(*coord) * ncp->recsize; + + lcoord += varp->begin; + return lcoord; + } +} + + + +static int +putNCvx_char_char(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const char *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_char_char(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + + +static int +putNCvx_schar_schar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_schar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_schar_uchar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_uchar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_schar_short(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_short(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_schar_int(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_int(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_schar_float(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_float(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_schar_double(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_double(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_schar_longlong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_longlong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + + +static int +putNCvx_short_schar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_schar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_short_uchar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_uchar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_short_short(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_short(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_short_int(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_int(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_short_float(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_float(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_short_double(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_double(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_short_longlong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_longlong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + + +static int +putNCvx_int_schar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_schar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_int_uchar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_uchar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_int_short(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_short(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_int_int(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_int(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_int_float(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_float(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_int_double(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_double(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_int_longlong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_longlong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + + +static int +putNCvx_float_schar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_schar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_float_uchar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_uchar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_float_short(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_short(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_float_int(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_int(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_float_float(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_float(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_float_double(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_double(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_float_longlong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_longlong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + + +static int +putNCvx_double_schar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_schar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_double_uchar(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_uchar(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_double_short(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_short(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_double_int(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_int(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_double_float(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_float(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_double_double(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_double(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_double_longlong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_longlong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + + +#ifdef NOTUSED +static int +putNCvx_schar_uint(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_uint(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_schar_ulonglong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_schar_ulonglong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_short_uint(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_uint(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_short_ulonglong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_short_ulonglong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_int_uint(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_uint(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_int_ulonglong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_int_ulonglong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_float_uint(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_uint(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_float_ulonglong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_float_ulonglong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_double_uint(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_uint(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +static int +putNCvx_double_ulonglong(NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, const ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nput = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + RGN_WRITE, &xp); + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_putn_double_ulonglong(&xp, nput, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + { + /* not fatal to the loop */ + status = lstatus; + } + + (void) ncio_rel(ncp->nciop, offset, + RGN_MODIFIED); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nput; + + } + + return status; +} + +#endif /*NOTUSED*/ + + +static int +getNCvx_char_char(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, char *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_char_char(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + + +static int +getNCvx_schar_schar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_schar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_schar_short(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_short(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_schar_int(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_int(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_schar_float(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_float(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_schar_double(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_double(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_schar_longlong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_longlong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_schar_uint(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_uint(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_schar_ulonglong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_ulonglong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + + +static int +getNCvx_short_schar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_schar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_short_uchar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_uchar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_short_short(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_short(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_short_int(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_int(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_short_float(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_float(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_short_double(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_double(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_short_longlong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_longlong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_short_uint(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_uint(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_short_ulonglong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_short_ulonglong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + + +static int +getNCvx_int_schar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_schar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_int_uchar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_uchar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_int_short(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_short(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_int_int(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_int(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_int_float(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_float(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_int_double(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_double(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_int_longlong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_longlong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_int_uint(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_uint(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_int_ulonglong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_int_ulonglong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + + +static int +getNCvx_float_schar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_schar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_float_uchar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_uchar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_float_short(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_short(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_float_int(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_int(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_float_float(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_float(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_float_double(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_double(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_float_longlong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_longlong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_float_uint(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_uint(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_float_ulonglong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_float_ulonglong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + + +static int +getNCvx_double_schar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, schar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_schar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_double_uchar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_uchar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_double_short(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, short *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_short(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_double_int(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, int *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_int(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_double_float(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, float *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_float(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_double_double(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, double *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_double(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_double_longlong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, longlong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_longlong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_double_uint(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uint *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_uint(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +static int +getNCvx_double_ulonglong(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, ulonglong *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_double_ulonglong(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + + +#ifdef NOTUSED +static int +getNCvx_schar_uchar(const NC *ncp, const NC_var *varp, + const size_t *start, size_t nelems, uchar *value) +{ + off_t offset = NC_varoffset(ncp, varp, start); + size_t remaining = varp->xsz * nelems; + int status = NC_NOERR; + const void *xp; + + if(nelems == 0) + return NC_NOERR; + + assert(value != NULL); + + for(;;) + { + size_t extent = MIN(remaining, ncp->chunk); + size_t nget = ncx_howmany(varp->type, extent); + + int lstatus = ncio_get(ncp->nciop, offset, extent, + 0, (void **)&xp); /* cast away const */ + if(lstatus != NC_NOERR) + return lstatus; + + lstatus = ncx_getn_schar_uchar(&xp, nget, value); + if(lstatus != NC_NOERR && status == NC_NOERR) + status = lstatus; + + (void) ncio_rel(ncp->nciop, offset, 0); + + remaining -= extent; + if(remaining == 0) + break; /* normal loop exit */ + offset += extent; + value += nget; + } + + return status; +} + +#endif /*NOTUSED*/ + +/* + * For ncvar{put,get}, + * find the largest contiguous block from within 'edges'. + * returns the index to the left of this (which may be -1). + * Compute the number of contiguous elements and return + * that in *iocountp. + * The presence of "record" variables makes this routine + * overly subtle. + */ +static int +NCiocount(const NC *const ncp, const NC_var *const varp, + const size_t *const edges, + size_t *const iocountp) +{ + const size_t *edp0 = edges; + const size_t *edp = edges + varp->ndims; + const size_t *shp = varp->shape + varp->ndims; + + if(IS_RECVAR(varp)) + { + if(varp->ndims == 1 && ncp->recsize <= varp->len) + { + /* one dimensional && the only 'record' variable */ + *iocountp = *edges; + return(0); + } + /* else */ + edp0++; + } + + assert(edges != NULL); + + /* find max contiguous */ + while(edp > edp0) + { + shp--; edp--; + if(*edp < *shp ) + { + const size_t *zedp = edp; + while(zedp >= edp0) + { + if(*zedp == 0) + { + *iocountp = 0; + goto done; + } + /* Tip of the hat to segmented architectures */ + if(zedp == edp0) + break; + zedp--; + } + break; + } + assert(*edp == *shp); + } + + /* + * edp, shp reference rightmost index s.t. *(edp +1) == *(shp +1) + * + * Or there is only one dimension. + * If there is only one dimension and it is 'non record' dimension, + * edp is &edges[0] and we will return -1. + * If there is only one dimension and and it is a "record dimension", + * edp is &edges[1] (out of bounds) and we will return 0; + */ + assert(shp >= varp->shape + varp->ndims -1 + || *(edp +1) == *(shp +1)); + + /* now accumulate max count for a single io operation */ + for(*iocountp = 1, edp0 = edp; + edp0 < edges + varp->ndims; + edp0++) + { + *iocountp *= *edp0; + } + +done: + return((int)(edp - edges) - 1); +} + + +/* + * Set the elements of the array 'upp' to + * the sum of the corresponding elements of + * 'stp' and 'edp'. 'end' should be &stp[nelems]. + */ +static void +set_upper(size_t *upp, /* modified on return */ + const size_t *stp, + const size_t *edp, + const size_t *const end) +{ + while(upp < end) { + *upp++ = *stp++ + *edp++; + } +} + + +/* + * The infamous and oft-discussed odometer code. + * + * 'start[]' is the starting coordinate. + * 'upper[]' is the upper bound s.t. start[ii] < upper[ii]. + * 'coord[]' is the register, the current coordinate value. + * For some ii, + * upp == &upper[ii] + * cdp == &coord[ii] + * + * Running this routine increments *cdp. + * + * If after the increment, *cdp is equal to *upp + * (and cdp is not the leftmost dimension), + * *cdp is "zeroed" to the starting value and + * we need to "carry", eg, increment one place to + * the left. + * + * TODO: Some architectures hate recursion? + * Reimplement non-recursively. + */ +static void +odo1(const size_t *const start, const size_t *const upper, + size_t *const coord, /* modified on return */ + const size_t *upp, + size_t *cdp) +{ + assert(coord <= cdp && cdp <= coord + NC_MAX_VAR_DIMS); + assert(upper <= upp && upp <= upper + NC_MAX_VAR_DIMS); + assert(upp - upper == cdp - coord); + + assert(*cdp <= *upp); + + (*cdp)++; + if(cdp != coord && *cdp >= *upp) + { + *cdp = start[cdp - coord]; + odo1(start, upper, coord, upp -1, cdp -1); + } +} +#ifdef _CRAYC +#pragma _CRI noinline odo1 +#endif + + + +/* Define a macro to allow hash on two type values */ +#define CASE(nc1,nc2) (nc1*256+nc2) + +static int +readNCv(const NC* ncp, const NC_var* varp, const size_t* start, + const size_t nelems, void* value, const nc_type memtype) +{ + int status = NC_NOERR; + switch (CASE(varp->type,memtype)) { + case CASE(NC_CHAR,NC_CHAR): + case CASE(NC_CHAR,NC_UBYTE): + status = getNCvx_char_char(ncp,varp,start,nelems,(char*)value); + break; + + case CASE(NC_BYTE,NC_BYTE): + case CASE(NC_BYTE,NC_UBYTE): + status = getNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_BYTE,NC_SHORT): + status = getNCvx_schar_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_BYTE,NC_INT): + status = getNCvx_schar_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_BYTE,NC_FLOAT): + status = getNCvx_schar_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_BYTE,NC_DOUBLE): + status = getNCvx_schar_double(ncp,varp,start,nelems,(double *)value); + break; + case CASE(NC_BYTE,NC_INT64): + status = getNCvx_schar_longlong(ncp,varp,start,nelems,(long long*)value); + break; + case CASE(NC_BYTE,NC_UINT): + status = getNCvx_schar_uint(ncp,varp,start,nelems,(unsigned int*)value); + break; + case CASE(NC_BYTE,NC_UINT64): + status = getNCvx_schar_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value); + break; + + case CASE(NC_SHORT,NC_BYTE): + status = getNCvx_short_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_SHORT,NC_UBYTE): + status = getNCvx_short_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_SHORT,NC_SHORT): + status = getNCvx_short_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_SHORT,NC_INT): + status = getNCvx_short_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_SHORT,NC_FLOAT): + status = getNCvx_short_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_SHORT,NC_DOUBLE): + status = getNCvx_short_double(ncp,varp,start,nelems,(double*)value); + break; + case CASE(NC_SHORT,NC_INT64): + status = getNCvx_short_longlong(ncp,varp,start,nelems,(long long*)value); + break; + case CASE(NC_SHORT,NC_UINT): + status = getNCvx_short_uint(ncp,varp,start,nelems,(unsigned int*)value); + break; + case CASE(NC_SHORT,NC_UINT64): + status = getNCvx_short_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value); + break; + + + case CASE(NC_INT,NC_BYTE): + status = getNCvx_int_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_INT,NC_UBYTE): + status = getNCvx_int_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_INT,NC_SHORT): + status = getNCvx_int_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_INT,NC_INT): + status = getNCvx_int_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_INT,NC_FLOAT): + status = getNCvx_int_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_INT,NC_DOUBLE): + status = getNCvx_int_double(ncp,varp,start,nelems,(double*)value); + break; + case CASE(NC_INT,NC_INT64): + status = getNCvx_int_longlong(ncp,varp,start,nelems,(long long*)value); + break; + case CASE(NC_INT,NC_UINT): + status = getNCvx_int_uint(ncp,varp,start,nelems,(unsigned int*)value); + break; + case CASE(NC_INT,NC_UINT64): + status = getNCvx_int_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value); + break; + + + case CASE(NC_FLOAT,NC_BYTE): + status = getNCvx_float_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_FLOAT,NC_UBYTE): + status = getNCvx_float_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_FLOAT,NC_SHORT): + status = getNCvx_float_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_FLOAT,NC_INT): + status = getNCvx_float_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_FLOAT,NC_FLOAT): + status = getNCvx_float_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_FLOAT,NC_DOUBLE): + status = getNCvx_float_double(ncp,varp,start,nelems,(double*)value); + break; + case CASE(NC_FLOAT,NC_INT64): + status = getNCvx_float_longlong(ncp,varp,start,nelems,(long long*)value); + break; + case CASE(NC_FLOAT,NC_UINT): + status = getNCvx_float_uint(ncp,varp,start,nelems,(unsigned int*)value); + break; + case CASE(NC_FLOAT,NC_UINT64): + status = getNCvx_float_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value); + break; + + + case CASE(NC_DOUBLE,NC_BYTE): + status = getNCvx_double_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_DOUBLE,NC_UBYTE): + status = getNCvx_double_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_DOUBLE,NC_SHORT): + status = getNCvx_double_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_DOUBLE,NC_INT): + status = getNCvx_double_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_DOUBLE,NC_FLOAT): + status = getNCvx_double_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_DOUBLE,NC_DOUBLE): + status = getNCvx_double_double(ncp,varp,start,nelems,(double*)value); + break; + case CASE(NC_DOUBLE,NC_INT64): + status = getNCvx_double_longlong(ncp,varp,start,nelems,(long long*)value); + break; + case CASE(NC_DOUBLE,NC_UINT): + status = getNCvx_double_uint(ncp,varp,start,nelems,(unsigned int*)value); + break; + case CASE(NC_DOUBLE,NC_UINT64): + status = getNCvx_double_ulonglong(ncp,varp,start,nelems,(unsigned long long*)value); + break; + + default: + return NC_EBADTYPE; + } + return status; +} + + +static int +writeNCv(NC* ncp, const NC_var* varp, const size_t* start, + const size_t nelems, const void* value, const nc_type memtype) +{ + int status = NC_NOERR; + switch (CASE(varp->type,memtype)) { + case CASE(NC_CHAR,NC_CHAR): + case CASE(NC_CHAR,NC_UBYTE): + status = putNCvx_char_char(ncp,varp,start,nelems,(char*)value); + break; + + case CASE(NC_BYTE,NC_BYTE): + status = putNCvx_schar_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_BYTE,NC_UBYTE): + status = putNCvx_schar_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_BYTE,NC_SHORT): + status = putNCvx_schar_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_BYTE,NC_INT): + status = putNCvx_schar_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_BYTE,NC_FLOAT): + status = putNCvx_schar_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_BYTE,NC_DOUBLE): + status = putNCvx_schar_double(ncp,varp,start,nelems,(double *)value); + break; + case CASE(NC_BYTE,NC_INT64): + status = putNCvx_schar_longlong(ncp,varp,start,nelems,(long long*)value); + break; + + case CASE(NC_SHORT,NC_BYTE): + status = putNCvx_short_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_SHORT,NC_UBYTE): + status = putNCvx_short_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_SHORT,NC_SHORT): + status = putNCvx_short_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_SHORT,NC_INT): + status = putNCvx_short_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_SHORT,NC_FLOAT): + status = putNCvx_short_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_SHORT,NC_DOUBLE): + status = putNCvx_short_double(ncp,varp,start,nelems,(double*)value); + break; + case CASE(NC_SHORT,NC_INT64): + status = putNCvx_short_longlong(ncp,varp,start,nelems,(long long*)value); + break; + + case CASE(NC_INT,NC_BYTE): + status = putNCvx_int_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_INT,NC_UBYTE): + status = putNCvx_int_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_INT,NC_SHORT): + status = putNCvx_int_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_INT,NC_INT): + status = putNCvx_int_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_INT,NC_FLOAT): + status = putNCvx_int_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_INT,NC_DOUBLE): + status = putNCvx_int_double(ncp,varp,start,nelems,(double*)value); + break; + case CASE(NC_INT,NC_INT64): + status = putNCvx_int_longlong(ncp,varp,start,nelems,(long long*)value); + break; + + case CASE(NC_FLOAT,NC_BYTE): + status = putNCvx_float_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_FLOAT,NC_UBYTE): + status = putNCvx_float_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_FLOAT,NC_SHORT): + status = putNCvx_float_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_FLOAT,NC_INT): + status = putNCvx_float_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_FLOAT,NC_FLOAT): + status = putNCvx_float_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_FLOAT,NC_DOUBLE): + status = putNCvx_float_double(ncp,varp,start,nelems,(double*)value); + break; + case CASE(NC_FLOAT,NC_INT64): + status = putNCvx_float_longlong(ncp,varp,start,nelems,(long long*)value); + break; + + case CASE(NC_DOUBLE,NC_BYTE): + status = putNCvx_double_schar(ncp,varp,start,nelems,(signed char*)value); + break; + case CASE(NC_DOUBLE,NC_UBYTE): + status = putNCvx_double_uchar(ncp,varp,start,nelems,(unsigned char*)value); + break; + case CASE(NC_DOUBLE,NC_SHORT): + status = putNCvx_double_short(ncp,varp,start,nelems,(short*)value); + break; + case CASE(NC_DOUBLE,NC_INT): + status = putNCvx_double_int(ncp,varp,start,nelems,(int*)value); + break; + case CASE(NC_DOUBLE,NC_FLOAT): + status = putNCvx_double_float(ncp,varp,start,nelems,(float*)value); + break; + case CASE(NC_DOUBLE,NC_DOUBLE): + status = putNCvx_double_double(ncp,varp,start,nelems,(double*)value); + break; + case CASE(NC_DOUBLE,NC_INT64): + status = putNCvx_double_longlong(ncp,varp,start,nelems,(long long*)value); + break; + + default: + return NC_EBADTYPE; + } + return status; +} + +/**************************************************/ + +int +NC3_get_vara(int ncid, int varid, + const size_t *start, const size_t *edges0, + void *value0, + nc_type memtype) +{ + int status = NC_NOERR; + NC* ncp; + NC_var *varp; + int ii; + size_t iocount; + size_t memtypelen; + char* value = (char*) value0; /* legally allow ptr arithmetic */ + const size_t* edges = edges0; /* so we can modify for special cases */ + size_t modedges[NC_MAX_VAR_DIMS]; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_indef(ncp)) + return NC_EINDEFINE; + + varp = NC_lookupvar(ncp, varid); + if(varp == NULL) + return NC_ENOTVAR; + + if(memtype == NC_NAT) memtype=varp->type; + + if(memtype == NC_CHAR && varp->type != NC_CHAR) + return NC_ECHAR; + else if(memtype != NC_CHAR && varp->type == NC_CHAR) + return NC_ECHAR; + + /* If edges is NULL, then this was called from nc_get_var() */ + if(edges == NULL && varp->ndims > 0) { + /* If this is a record variable, then we have to + substitute the number of records into dimension 0. */ + if(varp->shape[0] == 0) { + (void*)memcpy((void*)modedges,(void*)varp->shape, + sizeof(size_t)*varp->ndims); + modedges[0] = NC_get_numrecs(ncp); + edges = modedges; + } else + edges = varp->shape; + } + + status = NCcoordck(ncp, varp, start); + if(status != NC_NOERR) + return status; + + status = NCedgeck(ncp, varp, start, edges); + if(status != NC_NOERR) + return status; + + /* Get the size of the memtype */ + memtypelen = nctypelen(memtype); + + if(varp->ndims == 0) /* scalar variable */ + { + return( readNCv(ncp, varp, start, 1, (void*)value, memtype) ); + } + + if(IS_RECVAR(varp)) + { + if(*start + *edges > NC_get_numrecs(ncp)) + return NC_EEDGE; + if(varp->ndims == 1 && ncp->recsize <= varp->len) + { + /* one dimensional && the only record variable */ + return( readNCv(ncp, varp, start, *edges, (void*)value, memtype) ); + } + } + + /* + * find max contiguous + * and accumulate max count for a single io operation + */ + ii = NCiocount(ncp, varp, edges, &iocount); + + if(ii == -1) + { + return( readNCv(ncp, varp, start, iocount, (void*)value, memtype) ); + } + + assert(ii >= 0); + + { /* inline */ + ALLOC_ONSTACK(coord, size_t, varp->ndims); + ALLOC_ONSTACK(upper, size_t, varp->ndims); + const size_t index = ii; + + /* copy in starting indices */ + (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); + + /* set up in maximum indices */ + set_upper(upper, start, edges, &upper[varp->ndims]); + + /* ripple counter */ + while(*coord < *upper) + { + const int lstatus = readNCv(ncp, varp, coord, iocount, (void*)value, memtype); + if(lstatus != NC_NOERR) + { + if(lstatus != NC_ERANGE) + { + status = lstatus; + /* fatal for the loop */ + break; + } + /* else NC_ERANGE, not fatal for the loop */ + if(status == NC_NOERR) + status = lstatus; + } + value += (iocount * memtypelen); + odo1(start, upper, coord, &upper[index], &coord[index]); + } + + FREE_ONSTACK(upper); + FREE_ONSTACK(coord); + } /* end inline */ + + return status; +} + +int +NC3_put_vara(int ncid, int varid, + const size_t *start, const size_t *edges0, + const void *value0, + nc_type memtype) +{ + int status = NC_NOERR; + NC *ncp; + NC_var *varp; + int ii; + size_t iocount; + size_t memtypelen; + char* value = (char*) value0; /* legally allow ptr arithmetic */ + const size_t* edges = edges0; /* so we can modify for special cases */ + size_t modedges[NC_MAX_VAR_DIMS]; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_readonly(ncp)) + return NC_EPERM; + + if(NC_indef(ncp)) + return NC_EINDEFINE; + + varp = NC_lookupvar(ncp, varid); + if(varp == NULL) + return NC_ENOTVAR; /* TODO: lost NC_EGLOBAL */ + + if(memtype == NC_NAT) memtype=varp->type; + + if(memtype == NC_CHAR && varp->type != NC_CHAR) + return NC_ECHAR; + else if(memtype != NC_CHAR && varp->type == NC_CHAR) + return NC_ECHAR; + + /* Get the size of the memtype */ + memtypelen = nctypelen(memtype); + + /* If edges is NULL, then this was called from nc_get_var() */ + if(edges == NULL && varp->ndims > 0) { + /* If this is a record variable, then we have to + substitute the number of records into dimension 0. */ + if(varp->shape[0] == 0) { + (void*)memcpy((void*)modedges,(void*)varp->shape, + sizeof(size_t)*varp->ndims); + modedges[0] = NC_get_numrecs(ncp); + edges = modedges; + } else + edges = varp->shape; + } + + status = NCcoordck(ncp, varp, start); + if(status != NC_NOERR) + return status; + status = NCedgeck(ncp, varp, start, edges); + if(status != NC_NOERR) + return status; + + if(varp->ndims == 0) /* scalar variable */ + { + return( writeNCv(ncp, varp, start, 1, (void*)value, memtype) ); + } + + if(IS_RECVAR(varp)) + { + status = NCvnrecs(ncp, *start + *edges); + if(status != NC_NOERR) + return status; + + if(varp->ndims == 1 + && ncp->recsize <= varp->len) + { + /* one dimensional && the only record variable */ + return( writeNCv(ncp, varp, start, *edges, (void*)value, memtype) ); + } + } + + /* + * find max contiguous + * and accumulate max count for a single io operation + */ + ii = NCiocount(ncp, varp, edges, &iocount); + + if(ii == -1) + { + return( writeNCv(ncp, varp, start, iocount, (void*)value, memtype) ); + } + + assert(ii >= 0); + + { /* inline */ + ALLOC_ONSTACK(coord, size_t, varp->ndims); + ALLOC_ONSTACK(upper, size_t, varp->ndims); + const size_t index = ii; + + /* copy in starting indices */ + (void) memcpy(coord, start, varp->ndims * sizeof(size_t)); + + /* set up in maximum indices */ + set_upper(upper, start, edges, &upper[varp->ndims]); + + /* ripple counter */ + while(*coord < *upper) + { + const int lstatus = writeNCv(ncp, varp, coord, iocount, (void*)value, memtype); + if(lstatus != NC_NOERR) + { + if(lstatus != NC_ERANGE) + { + status = lstatus; + /* fatal for the loop */ + break; + } + /* else NC_ERANGE, not fatal for the loop */ + if(status == NC_NOERR) + status = lstatus; + } + value += (iocount * memtypelen); + odo1(start, upper, coord, &upper[index], &coord[index]); + } + + FREE_ONSTACK(upper); + FREE_ONSTACK(coord); + } /* end inline */ + + return status; +} diff --git a/extern/src_netcdf4/rnd.h b/extern/src_netcdf4/rnd.h new file mode 100644 index 0000000000000000000000000000000000000000..4021a4d32254b42930b6935f022a4bb65b059011 --- /dev/null +++ b/extern/src_netcdf4/rnd.h @@ -0,0 +1,17 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: rnd.h,v 2.13 1996/12/11 05:46:54 davis Exp $ */ +#ifndef _RNDUP + +/* useful for aligning memory */ +#define _RNDUP(x, unit) ((((x) + (unit) - 1) / (unit)) \ + * (unit)) +#define _RNDDOWN(x, unit) ((x) - ((x)%(unit))) + +#define M_RND_UNIT (sizeof(double)) +#define M_RNDUP(x) _RNDUP(x, M_RND_UNIT) +#define M_RNDDOWN(x) __RNDDOWN(x, M_RND_UNIT) + +#endif diff --git a/extern/src_netcdf4/stub.c b/extern/src_netcdf4/stub.c new file mode 100644 index 0000000000000000000000000000000000000000..ab97007a1774e57a8e9ed1922bd6e96185afb850 --- /dev/null +++ b/extern/src_netcdf4/stub.c @@ -0,0 +1,71 @@ +/********************************************************************* + * Copyright 2010, UCAR/Unidata + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + *********************************************************************/ + +#include "config.h" +#include "ncdispatch.h" + +extern int NC3_initialize(void); + +#ifdef USE_NETCDF4 +extern int NC4_initialize(void); +#endif + +#ifdef USE_DAP +extern int NCD3_initialize(void); +#ifdef USE_NETCDF4 +extern int NCD4_initialize(void); +#endif +#endif + +#ifdef USE_CDMREMOTE +extern int NCCR_initialize(void); +#endif + +#ifdef BUILD_RPC +extern int NCRPC_initialize(void); +#endif + +int +NC_initialize(void) +{ + int stat = NC_NOERR; + + /* Allow libdispatch to do initialization */ + if((stat = NCDISPATCH_initialize())) return stat; + + /* Initialize each active protocol */ + + if((stat = NC3_initialize())) return stat; + +#ifdef USE_DAP + if((stat = NCD3_initialize())) return stat; +#endif + +#ifdef USE_NETCDF4 + if((stat = NC4_initialize())) return stat; + + /* if((stat = NCD_initialize())) return stat; */ + +#ifdef USE_DAP +#ifdef NOTUSED + if((stat = NCD4_initialize())) return stat; +#endif +#endif + +#ifdef USE_CDMREMOTE + if((stat = NCCR_initialize())) return stat; +#endif + +#ifdef USE_RPC + if((stat = NCRPC_initialize())) return stat; +#endif + +#endif /* USE_NETCDF4 */ + + + return NC_NOERR; +} + + diff --git a/extern/src_netcdf4/utf8proc.h b/extern/src_netcdf4/utf8proc.h new file mode 100644 index 0000000000000000000000000000000000000000..f99753e5d49852ab54b48b3fcf6603e3fd07929f --- /dev/null +++ b/extern/src_netcdf4/utf8proc.h @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2006-2007 Jan Behrens, FlexiGuided GmbH, Berlin + * + * 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. + */ + + +/* + * File name: utf8proc.h + * Version: 1.1.1 + * Last changed: 2007-07-22 + * Changed 2008-05-16 by rkr to add config.h and replacement for stdbool.h + * for pre-C99 compilers that don't support bool. + * Changed 2008-06-05 by rkr to add utf8proc_check(str, options) function for + * for just checking UTF-8 validity + * Description: + * Header files for libutf8proc, which is a mapping tool for UTF-8 strings + * with following features: + * - decomposing and composing of strings + * - replacing compatibility characters with their equivalents + * - stripping of "default ignorable characters" + * like SOFT-HYPHEN or ZERO-WIDTH-SPACE + * - folding of certain characters for string comparison + * (e.g. HYPHEN U+2010 and MINUS U+2212 to ASCII "-") + * (see "LUMP" option) + * - optional rejection of strings containing non-assigned code points + * - stripping of control characters + * - stripping of character marks (accents, etc.) + * - transformation of LF, CRLF, CR and NEL to line-feed (LF) + * or to the unicode chararacters for paragraph separation (PS) + * or line separation (LS). + * - unicode case folding (for case insensitive string comparisons) + * - rejection of illegal UTF-8 data + * (i.e. UTF-8 encoded UTF-16 surrogates) + * - support for korean hangul characters + * Unicode Version 5.0.0 is supported. + */ + + +#ifndef UTF8PROC_H +#define UTF8PROC_H + + +#include "config.h" + +#include +#ifdef HAVE_STDBOOL_H +#include +#else +# if ! HAVE__BOOL +# ifdef __cplusplus +typedef bool _Bool; +# else +typedef unsigned char _Bool; +# endif +# endif +# define bool _Bool +# define false 0 +# define true 1 +# define __bool_true_false_are_defined 1 +#endif +#include +#ifdef HAVE_INTTYPES_H +#include +#else /* HAVE_INTTYPES_H */ +#include +#endif /* HAVE_INTTYPES_H */ +#include + +#ifndef HAVE_SSIZE_T +#define ssize_t int +#endif + +#ifndef SSIZE_MAX +#define SSIZE_MAX (SIZE_MAX/2) +#endif + +#define UTF8PROC_NULLTERM (1<<0) +#define UTF8PROC_STABLE (1<<1) +#define UTF8PROC_COMPAT (1<<2) +#define UTF8PROC_COMPOSE (1<<3) +#define UTF8PROC_DECOMPOSE (1<<4) +#define UTF8PROC_IGNORE (1<<5) +#define UTF8PROC_REJECTNA (1<<6) +#define UTF8PROC_NLF2LS (1<<7) +#define UTF8PROC_NLF2PS (1<<8) +#define UTF8PROC_NLF2LF (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS) +#define UTF8PROC_STRIPCC (1<<9) +#define UTF8PROC_CASEFOLD (1<<10) +#define UTF8PROC_CHARBOUND (1<<11) +#define UTF8PROC_LUMP (1<<12) +#define UTF8PROC_STRIPMARK (1<<13) +/* + * Flags being regarded by several functions in the library: + * NULLTERM: The given UTF-8 input is NULL terminated. + * STABLE: Unicode Versioning Stability has to be respected. + * COMPAT: Compatiblity decomposition + * (i.e. formatting information is lost) + * COMPOSE: Return a result with composed characters. + * DECOMPOSE: Return a result with decomposed characters. + * IGNORE: Strip "default ignorable characters" + * REJECTNA: Return an error, if the input contains unassigned + * code points. + * NLF2LS: Indicating that NLF-sequences (LF, CRLF, CR, NEL) are + * representing a line break, and should be converted to the + * unicode character for line separation (LS). + * NLF2PS: Indicating that NLF-sequences are representing a paragraph + * break, and should be converted to the unicode character for + * paragraph separation (PS). + * NLF2LF: Indicating that the meaning of NLF-sequences is unknown. + * STRIPCC: Strips and/or convers control characters. + * NLF-sequences are transformed into space, except if one of + * the NLF2LS/PS/LF options is given. + * HorizontalTab (HT) and FormFeed (FF) are treated as a + * NLF-sequence in this case. + * All other control characters are simply removed. + * CASEFOLD: Performs unicode case folding, to be able to do a + * case-insensitive string comparison. + * CHARBOUND: Inserts 0xFF bytes at the beginning of each sequence which + * is representing a single grapheme cluster (see UAX#29). + * LUMP: Lumps certain characters together + * (e.g. HYPHEN U+2010 and MINUS U+2212 to ASCII "-"). + * (See lump.txt for details.) + * If NLF2LF is set, this includes a transformation of + * paragraph and line separators to ASCII line-feed (LF). + * STRIPMARK: Strips all character markings + * (non-spacing, spacing and enclosing) (i.e. accents) + * NOTE: this option works only with COMPOSE or DECOMPOSE + */ + +#define UTF8PROC_ERROR_NOMEM -1 +#define UTF8PROC_ERROR_OVERFLOW -2 +#define UTF8PROC_ERROR_INVALIDUTF8 -3 +#define UTF8PROC_ERROR_NOTASSIGNED -4 +#define UTF8PROC_ERROR_INVALIDOPTS -5 +/* + * Error codes being returned by almost all functions: + * ERROR_NOMEM: Memory could not be allocated. + * ERROR_OVERFLOW: The given string is too long to be processed. + * ERROR_INVALIDUTF8: The given string is not a legal UTF-8 string. + * ERROR_NOTASSIGNED: The REJECTNA flag was set, + * and an unassigned code point was found. + * ERROR_INVALIDOPTS: Invalid options have been used. + */ + +typedef int16_t utf8proc_propval_t; +typedef struct utf8proc_property_struct { + utf8proc_propval_t category; + utf8proc_propval_t combining_class; + utf8proc_propval_t bidi_class; + utf8proc_propval_t decomp_type; + const int32_t *decomp_mapping; + unsigned bidi_mirrored:1; + int32_t uppercase_mapping; + int32_t lowercase_mapping; + int32_t titlecase_mapping; + int32_t comb1st_index; + int32_t comb2nd_index; + unsigned comp_exclusion:1; + unsigned ignorable:1; + unsigned control_boundary:1; + unsigned extend:1; + const int32_t *casefold_mapping; +} utf8proc_property_t; + +#define UTF8PROC_CATEGORY_LU 1 +#define UTF8PROC_CATEGORY_LL 2 +#define UTF8PROC_CATEGORY_LT 3 +#define UTF8PROC_CATEGORY_LM 4 +#define UTF8PROC_CATEGORY_LO 5 +#define UTF8PROC_CATEGORY_MN 6 +#define UTF8PROC_CATEGORY_MC 7 +#define UTF8PROC_CATEGORY_ME 8 +#define UTF8PROC_CATEGORY_ND 9 +#define UTF8PROC_CATEGORY_NL 10 +#define UTF8PROC_CATEGORY_NO 11 +#define UTF8PROC_CATEGORY_PC 12 +#define UTF8PROC_CATEGORY_PD 13 +#define UTF8PROC_CATEGORY_PS 14 +#define UTF8PROC_CATEGORY_PE 15 +#define UTF8PROC_CATEGORY_PI 16 +#define UTF8PROC_CATEGORY_PF 17 +#define UTF8PROC_CATEGORY_PO 18 +#define UTF8PROC_CATEGORY_SM 19 +#define UTF8PROC_CATEGORY_SC 20 +#define UTF8PROC_CATEGORY_SK 21 +#define UTF8PROC_CATEGORY_SO 22 +#define UTF8PROC_CATEGORY_ZS 23 +#define UTF8PROC_CATEGORY_ZL 24 +#define UTF8PROC_CATEGORY_ZP 25 +#define UTF8PROC_CATEGORY_CC 26 +#define UTF8PROC_CATEGORY_CF 27 +#define UTF8PROC_CATEGORY_CS 28 +#define UTF8PROC_CATEGORY_CO 29 +#define UTF8PROC_CATEGORY_CN 30 +#define UTF8PROC_BIDI_CLASS_L 1 +#define UTF8PROC_BIDI_CLASS_LRE 2 +#define UTF8PROC_BIDI_CLASS_LRO 3 +#define UTF8PROC_BIDI_CLASS_R 4 +#define UTF8PROC_BIDI_CLASS_AL 5 +#define UTF8PROC_BIDI_CLASS_RLE 6 +#define UTF8PROC_BIDI_CLASS_RLO 7 +#define UTF8PROC_BIDI_CLASS_PDF 8 +#define UTF8PROC_BIDI_CLASS_EN 9 +#define UTF8PROC_BIDI_CLASS_ES 10 +#define UTF8PROC_BIDI_CLASS_ET 11 +#define UTF8PROC_BIDI_CLASS_AN 12 +#define UTF8PROC_BIDI_CLASS_CS 13 +#define UTF8PROC_BIDI_CLASS_NSM 14 +#define UTF8PROC_BIDI_CLASS_BN 15 +#define UTF8PROC_BIDI_CLASS_B 16 +#define UTF8PROC_BIDI_CLASS_S 17 +#define UTF8PROC_BIDI_CLASS_WS 18 +#define UTF8PROC_BIDI_CLASS_ON 19 +#define UTF8PROC_DECOMP_TYPE_FONT 1 +#define UTF8PROC_DECOMP_TYPE_NOBREAK 2 +#define UTF8PROC_DECOMP_TYPE_INITIAL 3 +#define UTF8PROC_DECOMP_TYPE_MEDIAL 4 +#define UTF8PROC_DECOMP_TYPE_FINAL 5 +#define UTF8PROC_DECOMP_TYPE_ISOLATED 6 +#define UTF8PROC_DECOMP_TYPE_CIRCLE 7 +#define UTF8PROC_DECOMP_TYPE_SUPER 8 +#define UTF8PROC_DECOMP_TYPE_SUB 9 +#define UTF8PROC_DECOMP_TYPE_VERTICAL 10 +#define UTF8PROC_DECOMP_TYPE_WIDE 11 +#define UTF8PROC_DECOMP_TYPE_NARROW 12 +#define UTF8PROC_DECOMP_TYPE_SMALL 13 +#define UTF8PROC_DECOMP_TYPE_SQUARE 14 +#define UTF8PROC_DECOMP_TYPE_FRACTION 15 +#define UTF8PROC_DECOMP_TYPE_COMPAT 16 + +extern const int8_t utf8proc_utf8class[256]; + +const char *utf8proc_errmsg(ssize_t errcode); +/* + * Returns a static error string for the given error code. + */ + +ssize_t utf8proc_iterate(const uint8_t *str, ssize_t strlen, int32_t *dst); +/* + * Reads a single char from the UTF-8 sequence being pointed to by 'str'. + * The maximum number of bytes read is 'strlen', unless 'strlen' is + * negative. + * If a valid unicode char could be read, it is stored in the variable + * being pointed to by 'dst', otherwise that variable will be set to -1. + * In case of success the number of bytes read is returned, otherwise a + * negative error code is returned. + */ + +bool utf8proc_codepoint_valid(int32_t uc); +/* + * Returns 1, if the given unicode code-point is valid, otherwise 0. + */ + +ssize_t utf8proc_encode_char(int32_t uc, uint8_t *dst); +/* + * Encodes the unicode char with the code point 'uc' as an UTF-8 string in + * the byte array being pointed to by 'dst'. This array has to be at least + * 4 bytes long. + * In case of success the number of bytes written is returned, + * otherwise 0. + * This function does not check if 'uc' is a valid unicode code point. + */ + +const utf8proc_property_t *utf8proc_get_property(int32_t uc); +/* + * Returns a pointer to a (constant) struct containing information about + * the unicode char with the given code point 'uc'. + * If the character is not existent a pointer to a special struct is + * returned, where 'category' is a NULL pointer. + * WARNING: The parameter 'uc' has to be in the range of 0x0000 to + * 0x10FFFF, otherwise the program might crash! + */ + +ssize_t utf8proc_decompose_char( + int32_t uc, int32_t *dst, ssize_t bufsize, + int options, int *last_boundclass +); +/* + * Writes a decomposition of the unicode char 'uc' into the array being + * pointed to by 'dst'. + * Following flags in the 'options' field are regarded: + * REJECTNA: an unassigned unicode code point leads to an error + * IGNORE: "default ignorable" chars are stripped + * CASEFOLD: unicode casefolding is applied + * COMPAT: replace certain characters with their + * compatibility decomposition + * CHARBOUND: Inserts 0xFF bytes before each grapheme cluster + * LUMP: lumps certain different characters together + * STRIPMARK: removes all character marks + * The pointer 'last_boundclass' has to point to an integer variable which + * is storing the last character boundary class, if the CHARBOUND option + * is used. + * In case of success the number of chars written is returned, + * in case of an error, a negative error code is returned. + * If the number of written chars would be bigger than 'bufsize', + * the buffer (up to 'bufsize') has inpredictable data, and the needed + * buffer size is returned. + * WARNING: The parameter 'uc' has to be in the range of 0x0000 to + * 0x10FFFF, otherwise the program might crash! + */ + +ssize_t utf8proc_decompose( + const uint8_t *str, ssize_t strlen, + int32_t *buffer, ssize_t bufsize, int options +); +/* + * Does the same as 'utf8proc_decompose_char', but acts on a whole UTF-8 + * string, and orders the decomposed sequences correctly. + * If the NULLTERM flag in 'options' is set, processing will be stopped, + * when a NULL byte is encounted, otherwise 'strlen' bytes are processed. + * The result in form of unicode code points is written into the buffer + * being pointed to by 'buffer', having the length of 'bufsize' entries. + * In case of success the number of chars written is returned, + * in case of an error, a negative error code is returned. + * If the number of written chars would be bigger than 'bufsize', + * the buffer (up to 'bufsize') has inpredictable data, and the needed + * buffer size is returned. + */ + +ssize_t utf8proc_reencode(int32_t *buffer, ssize_t length, int options); +/* + * Reencodes the sequence of unicode characters given by the pointer + * 'buffer' and 'length' as UTF-8. + * The result is stored in the same memory area where the data is read. + * Following flags in the 'options' field are regarded: + * NLF2LS: converts LF, CRLF, CR and NEL into LS + * NLF2PS: converts LF, CRLF, CR and NEL into PS + * NLF2LF: converts LF, CRLF, CR and NEL into LF + * STRIPCC: strips or converts all non-affected control characters + * COMPOSE: tries to combine decomposed characters into composite + * characters + * STABLE: prohibits combining characters which would violate + * the unicode versioning stability + * In case of success the length of the resulting UTF-8 string is + * returned, otherwise a negative error code is returned. + * WARNING: The amount of free space being pointed to by 'buffer', has to + * exceed the amount of the input data by one byte, and the + * entries of the array pointed to by 'str' have to be in the + * range of 0x0000 to 0x10FFFF, otherwise the program might + * crash! + */ + +ssize_t utf8proc_map( + const uint8_t *str, ssize_t strlen, uint8_t **dstptr, int options +); +/* + * Maps the given UTF-8 string being pointed to by 'str' to a new UTF-8 + * string, which is allocated dynamically, and afterwards pointed to by + * the pointer being pointed to by 'dstptr'. + * If the NULLTERM flag in the 'options' field is set, the length is + * determined by a NULL terminator, otherwise the parameter 'strlen' is + * evaluated to determine the string length, but in any case the result + * will be NULL terminated (though it might contain NULL characters + * before). Other flags in the 'options' field are passed to the functions + * defined above, and regarded as described. + * In case of success the length of the new string is returned, + * otherwise a negative error code is returned. + * NOTICE: The memory of the new UTF-8 string will have been allocated with + * 'malloc', and has theirfore to be freed with 'free'. + */ + +uint8_t *utf8proc_NFD(const uint8_t *str); +uint8_t *utf8proc_NFC(const uint8_t *str); +uint8_t *utf8proc_NFKD(const uint8_t *str); +uint8_t *utf8proc_NFKC(const uint8_t *str); +/* + * Returns a pointer to newly allocated memory of a NFD, NFC, NFKD or NFKC + * normalized version of the null-terminated string 'str'. + */ + +ssize_t utf8proc_check(const uint8_t *str); +/* + * Just checks UTF-8 string for validity, returns 0 if valid or one of + * the negative UTF8PROC_ERROR_* codes if invalid or memory exhausted + * checking. Assumes null-terminated string str and UTF8PROC_STABLE + * option. + */ + +#endif + diff --git a/extern/src_netcdf4/utf8proc_data.h b/extern/src_netcdf4/utf8proc_data.h new file mode 100644 index 0000000000000000000000000000000000000000..1426b76e03cf07909ac78c6d2f80cc01e510c091 --- /dev/null +++ b/extern/src_netcdf4/utf8proc_data.h @@ -0,0 +1,13383 @@ +/* + * This file contains derived data from a modified version of the + * Unicode data files. + * + * The original data files are available at + * http://www.unicode.org/Public/UNIDATA/ + * + * + * COPYRIGHT AND PERMISSION NOTICE + * + * Copyright (c) 1991-2007 Unicode, Inc. All rights reserved. Distributed + * under the Terms of Use in http://www.unicode.org/copyright.html. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of the Unicode data files and any associated documentation (the "Data + * Files") or Unicode software and any associated documentation (the + * "Software") to deal in the Data Files or Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Data Files or Software, and + * to permit persons to whom the Data Files or Software are furnished to do + * so, provided that (a) the above copyright notice(s) and this permission + * notice appear with all copies of the Data Files or Software, (b) both the + * above copyright notice(s) and this permission notice appear in associated + * documentation, and (c) there is clear notice in each modified Data File or + * in the Software as well as in the documentation associated with the Data + * File(s) or Software that the data or software has been modified. + * + * THE DATA FILES AND SOFTWARE ARE 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 OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR + * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THE DATA FILES OR SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in these Data Files or Software without prior written + * authorization of the copyright holder. + */ + + +const int32_t utf8proc_sequences[] = { + 97, -1, 98, -1, 99, -1, 100, + -1, 101, -1, 102, -1, 103, -1, 104, + -1, 105, -1, 106, -1, 107, -1, 108, + -1, 109, -1, 110, -1, 111, -1, 112, + -1, 113, -1, 114, -1, 115, -1, 116, + -1, 117, -1, 118, -1, 119, -1, 120, + -1, 121, -1, 122, -1, 32, -1, 32, + 776, -1, 32, 772, -1, 50, -1, 51, + -1, 32, 769, -1, 956, -1, 32, 807, + -1, 49, -1, 49, 8260, 52, -1, 49, + 8260, 50, -1, 51, 8260, 52, -1, 65, + 768, -1, 224, -1, 65, 769, -1, 225, + -1, 65, 770, -1, 226, -1, 65, 771, + -1, 227, -1, 65, 776, -1, 228, -1, + 65, 778, -1, 229, -1, 230, -1, 67, + 807, -1, 231, -1, 69, 768, -1, 232, + -1, 69, 769, -1, 233, -1, 69, 770, + -1, 234, -1, 69, 776, -1, 235, -1, + 73, 768, -1, 236, -1, 73, 769, -1, + 237, -1, 73, 770, -1, 238, -1, 73, + 776, -1, 239, -1, 240, -1, 78, 771, + -1, 241, -1, 79, 768, -1, 242, -1, + 79, 769, -1, 243, -1, 79, 770, -1, + 244, -1, 79, 771, -1, 245, -1, 79, + 776, -1, 246, -1, 248, -1, 85, 768, + -1, 249, -1, 85, 769, -1, 250, -1, + 85, 770, -1, 251, -1, 85, 776, -1, + 252, -1, 89, 769, -1, 253, -1, 254, + -1, 115, 115, -1, 97, 768, -1, 97, + 769, -1, 97, 770, -1, 97, 771, -1, + 97, 776, -1, 97, 778, -1, 99, 807, + -1, 101, 768, -1, 101, 769, -1, 101, + 770, -1, 101, 776, -1, 105, 768, -1, + 105, 769, -1, 105, 770, -1, 105, 776, + -1, 110, 771, -1, 111, 768, -1, 111, + 769, -1, 111, 770, -1, 111, 771, -1, + 111, 776, -1, 117, 768, -1, 117, 769, + -1, 117, 770, -1, 117, 776, -1, 121, + 769, -1, 121, 776, -1, 65, 772, -1, + 257, -1, 97, 772, -1, 65, 774, -1, + 259, -1, 97, 774, -1, 65, 808, -1, + 261, -1, 97, 808, -1, 67, 769, -1, + 263, -1, 99, 769, -1, 67, 770, -1, + 265, -1, 99, 770, -1, 67, 775, -1, + 267, -1, 99, 775, -1, 67, 780, -1, + 269, -1, 99, 780, -1, 68, 780, -1, + 271, -1, 100, 780, -1, 273, -1, 69, + 772, -1, 275, -1, 101, 772, -1, 69, + 774, -1, 277, -1, 101, 774, -1, 69, + 775, -1, 279, -1, 101, 775, -1, 69, + 808, -1, 281, -1, 101, 808, -1, 69, + 780, -1, 283, -1, 101, 780, -1, 71, + 770, -1, 285, -1, 103, 770, -1, 71, + 774, -1, 287, -1, 103, 774, -1, 71, + 775, -1, 289, -1, 103, 775, -1, 71, + 807, -1, 291, -1, 103, 807, -1, 72, + 770, -1, 293, -1, 104, 770, -1, 295, + -1, 73, 771, -1, 297, -1, 105, 771, + -1, 73, 772, -1, 299, -1, 105, 772, + -1, 73, 774, -1, 301, -1, 105, 774, + -1, 73, 808, -1, 303, -1, 105, 808, + -1, 73, 775, -1, 105, 775, -1, 73, + 74, -1, 307, -1, 105, 106, -1, 74, + 770, -1, 309, -1, 106, 770, -1, 75, + 807, -1, 311, -1, 107, 807, -1, 76, + 769, -1, 314, -1, 108, 769, -1, 76, + 807, -1, 316, -1, 108, 807, -1, 76, + 780, -1, 318, -1, 108, 780, -1, 76, + 183, -1, 320, -1, 108, 183, -1, 322, + -1, 78, 769, -1, 324, -1, 110, 769, + -1, 78, 807, -1, 326, -1, 110, 807, + -1, 78, 780, -1, 328, -1, 110, 780, + -1, 700, 110, -1, 331, -1, 79, 772, + -1, 333, -1, 111, 772, -1, 79, 774, + -1, 335, -1, 111, 774, -1, 79, 779, + -1, 337, -1, 111, 779, -1, 339, -1, + 82, 769, -1, 341, -1, 114, 769, -1, + 82, 807, -1, 343, -1, 114, 807, -1, + 82, 780, -1, 345, -1, 114, 780, -1, + 83, 769, -1, 347, -1, 115, 769, -1, + 83, 770, -1, 349, -1, 115, 770, -1, + 83, 807, -1, 351, -1, 115, 807, -1, + 83, 780, -1, 353, -1, 115, 780, -1, + 84, 807, -1, 355, -1, 116, 807, -1, + 84, 780, -1, 357, -1, 116, 780, -1, + 359, -1, 85, 771, -1, 361, -1, 117, + 771, -1, 85, 772, -1, 363, -1, 117, + 772, -1, 85, 774, -1, 365, -1, 117, + 774, -1, 85, 778, -1, 367, -1, 117, + 778, -1, 85, 779, -1, 369, -1, 117, + 779, -1, 85, 808, -1, 371, -1, 117, + 808, -1, 87, 770, -1, 373, -1, 119, + 770, -1, 89, 770, -1, 375, -1, 121, + 770, -1, 89, 776, -1, 255, -1, 90, + 769, -1, 378, -1, 122, 769, -1, 90, + 775, -1, 380, -1, 122, 775, -1, 90, + 780, -1, 382, -1, 122, 780, -1, 595, + -1, 387, -1, 389, -1, 596, -1, 392, + -1, 598, -1, 599, -1, 396, -1, 477, + -1, 601, -1, 603, -1, 402, -1, 608, + -1, 611, -1, 617, -1, 616, -1, 409, + -1, 623, -1, 626, -1, 629, -1, 79, + 795, -1, 417, -1, 111, 795, -1, 419, + -1, 421, -1, 640, -1, 424, -1, 643, + -1, 429, -1, 648, -1, 85, 795, -1, + 432, -1, 117, 795, -1, 650, -1, 651, + -1, 436, -1, 438, -1, 658, -1, 441, + -1, 445, -1, 68, 381, -1, 454, -1, + 68, 382, -1, 100, 382, -1, 76, 74, + -1, 457, -1, 76, 106, -1, 108, 106, + -1, 78, 74, -1, 460, -1, 78, 106, + -1, 110, 106, -1, 65, 780, -1, 462, + -1, 97, 780, -1, 73, 780, -1, 464, + -1, 105, 780, -1, 79, 780, -1, 466, + -1, 111, 780, -1, 85, 780, -1, 468, + -1, 117, 780, -1, 220, 772, -1, 470, + -1, 252, 772, -1, 220, 769, -1, 472, + -1, 252, 769, -1, 220, 780, -1, 474, + -1, 252, 780, -1, 220, 768, -1, 476, + -1, 252, 768, -1, 196, 772, -1, 479, + -1, 228, 772, -1, 550, 772, -1, 481, + -1, 551, 772, -1, 198, 772, -1, 483, + -1, 230, 772, -1, 485, -1, 71, 780, + -1, 487, -1, 103, 780, -1, 75, 780, + -1, 489, -1, 107, 780, -1, 79, 808, + -1, 491, -1, 111, 808, -1, 490, 772, + -1, 493, -1, 491, 772, -1, 439, 780, + -1, 495, -1, 658, 780, -1, 106, 780, + -1, 68, 90, -1, 499, -1, 68, 122, + -1, 100, 122, -1, 71, 769, -1, 501, + -1, 103, 769, -1, 405, -1, 447, -1, + 78, 768, -1, 505, -1, 110, 768, -1, + 197, 769, -1, 507, -1, 229, 769, -1, + 198, 769, -1, 509, -1, 230, 769, -1, + 216, 769, -1, 511, -1, 248, 769, -1, + 65, 783, -1, 513, -1, 97, 783, -1, + 65, 785, -1, 515, -1, 97, 785, -1, + 69, 783, -1, 517, -1, 101, 783, -1, + 69, 785, -1, 519, -1, 101, 785, -1, + 73, 783, -1, 521, -1, 105, 783, -1, + 73, 785, -1, 523, -1, 105, 785, -1, + 79, 783, -1, 525, -1, 111, 783, -1, + 79, 785, -1, 527, -1, 111, 785, -1, + 82, 783, -1, 529, -1, 114, 783, -1, + 82, 785, -1, 531, -1, 114, 785, -1, + 85, 783, -1, 533, -1, 117, 783, -1, + 85, 785, -1, 535, -1, 117, 785, -1, + 83, 806, -1, 537, -1, 115, 806, -1, + 84, 806, -1, 539, -1, 116, 806, -1, + 541, -1, 72, 780, -1, 543, -1, 104, + 780, -1, 414, -1, 547, -1, 549, -1, + 65, 775, -1, 551, -1, 97, 775, -1, + 69, 807, -1, 553, -1, 101, 807, -1, + 214, 772, -1, 555, -1, 246, 772, -1, + 213, 772, -1, 557, -1, 245, 772, -1, + 79, 775, -1, 559, -1, 111, 775, -1, + 558, 772, -1, 561, -1, 559, 772, -1, + 89, 772, -1, 563, -1, 121, 772, -1, + 11365, -1, 572, -1, 410, -1, 11366, -1, + 578, -1, 384, -1, 649, -1, 652, -1, + 583, -1, 585, -1, 587, -1, 589, -1, + 591, -1, 614, -1, 633, -1, 635, -1, + 641, -1, 32, 774, -1, 32, 775, -1, + 32, 778, -1, 32, 808, -1, 32, 771, + -1, 32, 779, -1, 661, -1, 768, -1, + 769, -1, 787, -1, 776, 769, -1, 953, + -1, 697, -1, 32, 837, -1, 59, -1, + 168, 769, -1, 913, 769, -1, 940, -1, + 183, -1, 917, 769, -1, 941, -1, 919, + 769, -1, 942, -1, 921, 769, -1, 943, + -1, 927, 769, -1, 972, -1, 933, 769, + -1, 973, -1, 937, 769, -1, 974, -1, + 970, 769, -1, 953, 776, 769, -1, 945, + -1, 946, -1, 947, -1, 948, -1, 949, + -1, 950, -1, 951, -1, 952, -1, 954, + -1, 955, -1, 957, -1, 958, -1, 959, + -1, 960, -1, 961, -1, 963, -1, 964, + -1, 965, -1, 966, -1, 967, -1, 968, + -1, 969, -1, 921, 776, -1, 970, -1, + 933, 776, -1, 971, -1, 945, 769, -1, + 949, 769, -1, 951, 769, -1, 953, 769, + -1, 971, 769, -1, 965, 776, 769, -1, + 953, 776, -1, 965, 776, -1, 959, 769, + -1, 965, 769, -1, 969, 769, -1, 933, + -1, 978, 769, -1, 978, 776, -1, 985, + -1, 987, -1, 989, -1, 991, -1, 993, + -1, 995, -1, 997, -1, 999, -1, 1001, + -1, 1003, -1, 1005, -1, 1007, -1, 962, + -1, 920, -1, 1016, -1, 931, -1, 1010, + -1, 1019, -1, 891, -1, 892, -1, 893, + -1, 1045, 768, -1, 1104, -1, 1045, 776, + -1, 1105, -1, 1106, -1, 1043, 769, -1, + 1107, -1, 1108, -1, 1109, -1, 1110, -1, + 1030, 776, -1, 1111, -1, 1112, -1, 1113, + -1, 1114, -1, 1115, -1, 1050, 769, -1, + 1116, -1, 1048, 768, -1, 1117, -1, 1059, + 774, -1, 1118, -1, 1119, -1, 1072, -1, + 1073, -1, 1074, -1, 1075, -1, 1076, -1, + 1077, -1, 1078, -1, 1079, -1, 1080, -1, + 1048, 774, -1, 1081, -1, 1082, -1, 1083, + -1, 1084, -1, 1085, -1, 1086, -1, 1087, + -1, 1088, -1, 1089, -1, 1090, -1, 1091, + -1, 1092, -1, 1093, -1, 1094, -1, 1095, + -1, 1096, -1, 1097, -1, 1098, -1, 1099, + -1, 1100, -1, 1101, -1, 1102, -1, 1103, + -1, 1080, 774, -1, 1077, 768, -1, 1077, + 776, -1, 1075, 769, -1, 1110, 776, -1, + 1082, 769, -1, 1080, 768, -1, 1091, 774, + -1, 1121, -1, 1123, -1, 1125, -1, 1127, + -1, 1129, -1, 1131, -1, 1133, -1, 1135, + -1, 1137, -1, 1139, -1, 1141, -1, 1140, + 783, -1, 1143, -1, 1141, 783, -1, 1145, + -1, 1147, -1, 1149, -1, 1151, -1, 1153, + -1, 1163, -1, 1165, -1, 1167, -1, 1169, + -1, 1171, -1, 1173, -1, 1175, -1, 1177, + -1, 1179, -1, 1181, -1, 1183, -1, 1185, + -1, 1187, -1, 1189, -1, 1191, -1, 1193, + -1, 1195, -1, 1197, -1, 1199, -1, 1201, + -1, 1203, -1, 1205, -1, 1207, -1, 1209, + -1, 1211, -1, 1213, -1, 1215, -1, 1231, + -1, 1046, 774, -1, 1218, -1, 1078, 774, + -1, 1220, -1, 1222, -1, 1224, -1, 1226, + -1, 1228, -1, 1230, -1, 1040, 774, -1, + 1233, -1, 1072, 774, -1, 1040, 776, -1, + 1235, -1, 1072, 776, -1, 1237, -1, 1045, + 774, -1, 1239, -1, 1077, 774, -1, 1241, + -1, 1240, 776, -1, 1243, -1, 1241, 776, + -1, 1046, 776, -1, 1245, -1, 1078, 776, + -1, 1047, 776, -1, 1247, -1, 1079, 776, + -1, 1249, -1, 1048, 772, -1, 1251, -1, + 1080, 772, -1, 1048, 776, -1, 1253, -1, + 1080, 776, -1, 1054, 776, -1, 1255, -1, + 1086, 776, -1, 1257, -1, 1256, 776, -1, + 1259, -1, 1257, 776, -1, 1069, 776, -1, + 1261, -1, 1101, 776, -1, 1059, 772, -1, + 1263, -1, 1091, 772, -1, 1059, 776, -1, + 1265, -1, 1091, 776, -1, 1059, 779, -1, + 1267, -1, 1091, 779, -1, 1063, 776, -1, + 1269, -1, 1095, 776, -1, 1271, -1, 1067, + 776, -1, 1273, -1, 1099, 776, -1, 1275, + -1, 1277, -1, 1279, -1, 1281, -1, 1283, + -1, 1285, -1, 1287, -1, 1289, -1, 1291, + -1, 1293, -1, 1295, -1, 1297, -1, 1299, + -1, 1377, -1, 1378, -1, 1379, -1, 1380, + -1, 1381, -1, 1382, -1, 1383, -1, 1384, + -1, 1385, -1, 1386, -1, 1387, -1, 1388, + -1, 1389, -1, 1390, -1, 1391, -1, 1392, + -1, 1393, -1, 1394, -1, 1395, -1, 1396, + -1, 1397, -1, 1398, -1, 1399, -1, 1400, + -1, 1401, -1, 1402, -1, 1403, -1, 1404, + -1, 1405, -1, 1406, -1, 1407, -1, 1408, + -1, 1409, -1, 1410, -1, 1411, -1, 1412, + -1, 1413, -1, 1414, -1, 1381, 1410, -1, + 1575, 1619, -1, 1575, 1620, -1, 1608, 1620, + -1, 1575, 1621, -1, 1610, 1620, -1, 1575, + 1652, -1, 1608, 1652, -1, 1735, 1652, -1, + 1610, 1652, -1, 1749, 1620, -1, 1729, 1620, + -1, 1746, 1620, -1, 2344, 2364, -1, 2352, + 2364, -1, 2355, 2364, -1, 2325, 2364, -1, + 2326, 2364, -1, 2327, 2364, -1, 2332, 2364, + -1, 2337, 2364, -1, 2338, 2364, -1, 2347, + 2364, -1, 2351, 2364, -1, 2503, 2494, -1, + 2503, 2519, -1, 2465, 2492, -1, 2466, 2492, + -1, 2479, 2492, -1, 2610, 2620, -1, 2616, + 2620, -1, 2582, 2620, -1, 2583, 2620, -1, + 2588, 2620, -1, 2603, 2620, -1, 2887, 2902, + -1, 2887, 2878, -1, 2887, 2903, -1, 2849, + 2876, -1, 2850, 2876, -1, 2962, 3031, -1, + 3014, 3006, -1, 3015, 3006, -1, 3014, 3031, + -1, 3142, 3158, -1, 3263, 3285, -1, 3270, + 3285, -1, 3270, 3286, -1, 3270, 3266, -1, + 3274, 3285, -1, 3398, 3390, -1, 3399, 3390, + -1, 3398, 3415, -1, 3545, 3530, -1, 3545, + 3535, -1, 3548, 3530, -1, 3545, 3551, -1, + 3661, 3634, -1, 3789, 3762, -1, 3755, 3737, + -1, 3755, 3745, -1, 3851, -1, 3906, 4023, + -1, 3916, 4023, -1, 3921, 4023, -1, 3926, + 4023, -1, 3931, 4023, -1, 3904, 4021, -1, + 3953, 3954, -1, 3953, 3956, -1, 4018, 3968, + -1, 4018, 3969, -1, 4019, 3968, -1, 4019, + 3969, -1, 3953, 3968, -1, 3986, 4023, -1, + 3996, 4023, -1, 4001, 4023, -1, 4006, 4023, + -1, 4011, 4023, -1, 3984, 4021, -1, 4133, + 4142, -1, 11520, -1, 11521, -1, 11522, -1, + 11523, -1, 11524, -1, 11525, -1, 11526, -1, + 11527, -1, 11528, -1, 11529, -1, 11530, -1, + 11531, -1, 11532, -1, 11533, -1, 11534, -1, + 11535, -1, 11536, -1, 11537, -1, 11538, -1, + 11539, -1, 11540, -1, 11541, -1, 11542, -1, + 11543, -1, 11544, -1, 11545, -1, 11546, -1, + 11547, -1, 11548, -1, 11549, -1, 11550, -1, + 11551, -1, 11552, -1, 11553, -1, 11554, -1, + 11555, -1, 11556, -1, 11557, -1, 4316, -1, + 6917, 6965, -1, 6919, 6965, -1, 6921, 6965, + -1, 6923, 6965, -1, 6925, 6965, -1, 6929, + 6965, -1, 6970, 6965, -1, 6972, 6965, -1, + 6974, 6965, -1, 6975, 6965, -1, 6978, 6965, + -1, 65, -1, 198, -1, 66, -1, 68, + -1, 69, -1, 398, -1, 71, -1, 72, + -1, 73, -1, 74, -1, 75, -1, 76, + -1, 77, -1, 78, -1, 79, -1, 546, + -1, 80, -1, 82, -1, 84, -1, 85, + -1, 87, -1, 592, -1, 593, -1, 7426, + -1, 604, -1, 7446, -1, 7447, -1, 7453, + -1, 7461, -1, 594, -1, 597, -1, 607, + -1, 609, -1, 613, -1, 618, -1, 7547, + -1, 669, -1, 621, -1, 7557, -1, 671, + -1, 625, -1, 624, -1, 627, -1, 628, + -1, 632, -1, 642, -1, 427, -1, 7452, + -1, 656, -1, 657, -1, 65, 805, -1, + 7681, -1, 97, 805, -1, 66, 775, -1, + 7683, -1, 98, 775, -1, 66, 803, -1, + 7685, -1, 98, 803, -1, 66, 817, -1, + 7687, -1, 98, 817, -1, 199, 769, -1, + 7689, -1, 231, 769, -1, 68, 775, -1, + 7691, -1, 100, 775, -1, 68, 803, -1, + 7693, -1, 100, 803, -1, 68, 817, -1, + 7695, -1, 100, 817, -1, 68, 807, -1, + 7697, -1, 100, 807, -1, 68, 813, -1, + 7699, -1, 100, 813, -1, 274, 768, -1, + 7701, -1, 275, 768, -1, 274, 769, -1, + 7703, -1, 275, 769, -1, 69, 813, -1, + 7705, -1, 101, 813, -1, 69, 816, -1, + 7707, -1, 101, 816, -1, 552, 774, -1, + 7709, -1, 553, 774, -1, 70, 775, -1, + 7711, -1, 102, 775, -1, 71, 772, -1, + 7713, -1, 103, 772, -1, 72, 775, -1, + 7715, -1, 104, 775, -1, 72, 803, -1, + 7717, -1, 104, 803, -1, 72, 776, -1, + 7719, -1, 104, 776, -1, 72, 807, -1, + 7721, -1, 104, 807, -1, 72, 814, -1, + 7723, -1, 104, 814, -1, 73, 816, -1, + 7725, -1, 105, 816, -1, 207, 769, -1, + 7727, -1, 239, 769, -1, 75, 769, -1, + 7729, -1, 107, 769, -1, 75, 803, -1, + 7731, -1, 107, 803, -1, 75, 817, -1, + 7733, -1, 107, 817, -1, 76, 803, -1, + 7735, -1, 108, 803, -1, 7734, 772, -1, + 7737, -1, 7735, 772, -1, 76, 817, -1, + 7739, -1, 108, 817, -1, 76, 813, -1, + 7741, -1, 108, 813, -1, 77, 769, -1, + 7743, -1, 109, 769, -1, 77, 775, -1, + 7745, -1, 109, 775, -1, 77, 803, -1, + 7747, -1, 109, 803, -1, 78, 775, -1, + 7749, -1, 110, 775, -1, 78, 803, -1, + 7751, -1, 110, 803, -1, 78, 817, -1, + 7753, -1, 110, 817, -1, 78, 813, -1, + 7755, -1, 110, 813, -1, 213, 769, -1, + 7757, -1, 245, 769, -1, 213, 776, -1, + 7759, -1, 245, 776, -1, 332, 768, -1, + 7761, -1, 333, 768, -1, 332, 769, -1, + 7763, -1, 333, 769, -1, 80, 769, -1, + 7765, -1, 112, 769, -1, 80, 775, -1, + 7767, -1, 112, 775, -1, 82, 775, -1, + 7769, -1, 114, 775, -1, 82, 803, -1, + 7771, -1, 114, 803, -1, 7770, 772, -1, + 7773, -1, 7771, 772, -1, 82, 817, -1, + 7775, -1, 114, 817, -1, 83, 775, -1, + 7777, -1, 115, 775, -1, 83, 803, -1, + 7779, -1, 115, 803, -1, 346, 775, -1, + 7781, -1, 347, 775, -1, 352, 775, -1, + 7783, -1, 353, 775, -1, 7778, 775, -1, + 7785, -1, 7779, 775, -1, 84, 775, -1, + 7787, -1, 116, 775, -1, 84, 803, -1, + 7789, -1, 116, 803, -1, 84, 817, -1, + 7791, -1, 116, 817, -1, 84, 813, -1, + 7793, -1, 116, 813, -1, 85, 804, -1, + 7795, -1, 117, 804, -1, 85, 816, -1, + 7797, -1, 117, 816, -1, 85, 813, -1, + 7799, -1, 117, 813, -1, 360, 769, -1, + 7801, -1, 361, 769, -1, 362, 776, -1, + 7803, -1, 363, 776, -1, 86, 771, -1, + 7805, -1, 118, 771, -1, 86, 803, -1, + 7807, -1, 118, 803, -1, 87, 768, -1, + 7809, -1, 119, 768, -1, 87, 769, -1, + 7811, -1, 119, 769, -1, 87, 776, -1, + 7813, -1, 119, 776, -1, 87, 775, -1, + 7815, -1, 119, 775, -1, 87, 803, -1, + 7817, -1, 119, 803, -1, 88, 775, -1, + 7819, -1, 120, 775, -1, 88, 776, -1, + 7821, -1, 120, 776, -1, 89, 775, -1, + 7823, -1, 121, 775, -1, 90, 770, -1, + 7825, -1, 122, 770, -1, 90, 803, -1, + 7827, -1, 122, 803, -1, 90, 817, -1, + 7829, -1, 122, 817, -1, 104, 817, -1, + 116, 776, -1, 119, 778, -1, 121, 778, + -1, 97, 702, -1, 383, 775, -1, 65, + 803, -1, 7841, -1, 97, 803, -1, 65, + 777, -1, 7843, -1, 97, 777, -1, 194, + 769, -1, 7845, -1, 226, 769, -1, 194, + 768, -1, 7847, -1, 226, 768, -1, 194, + 777, -1, 7849, -1, 226, 777, -1, 194, + 771, -1, 7851, -1, 226, 771, -1, 7840, + 770, -1, 7853, -1, 7841, 770, -1, 258, + 769, -1, 7855, -1, 259, 769, -1, 258, + 768, -1, 7857, -1, 259, 768, -1, 258, + 777, -1, 7859, -1, 259, 777, -1, 258, + 771, -1, 7861, -1, 259, 771, -1, 7840, + 774, -1, 7863, -1, 7841, 774, -1, 69, + 803, -1, 7865, -1, 101, 803, -1, 69, + 777, -1, 7867, -1, 101, 777, -1, 69, + 771, -1, 7869, -1, 101, 771, -1, 202, + 769, -1, 7871, -1, 234, 769, -1, 202, + 768, -1, 7873, -1, 234, 768, -1, 202, + 777, -1, 7875, -1, 234, 777, -1, 202, + 771, -1, 7877, -1, 234, 771, -1, 7864, + 770, -1, 7879, -1, 7865, 770, -1, 73, + 777, -1, 7881, -1, 105, 777, -1, 73, + 803, -1, 7883, -1, 105, 803, -1, 79, + 803, -1, 7885, -1, 111, 803, -1, 79, + 777, -1, 7887, -1, 111, 777, -1, 212, + 769, -1, 7889, -1, 244, 769, -1, 212, + 768, -1, 7891, -1, 244, 768, -1, 212, + 777, -1, 7893, -1, 244, 777, -1, 212, + 771, -1, 7895, -1, 244, 771, -1, 7884, + 770, -1, 7897, -1, 7885, 770, -1, 416, + 769, -1, 7899, -1, 417, 769, -1, 416, + 768, -1, 7901, -1, 417, 768, -1, 416, + 777, -1, 7903, -1, 417, 777, -1, 416, + 771, -1, 7905, -1, 417, 771, -1, 416, + 803, -1, 7907, -1, 417, 803, -1, 85, + 803, -1, 7909, -1, 117, 803, -1, 85, + 777, -1, 7911, -1, 117, 777, -1, 431, + 769, -1, 7913, -1, 432, 769, -1, 431, + 768, -1, 7915, -1, 432, 768, -1, 431, + 777, -1, 7917, -1, 432, 777, -1, 431, + 771, -1, 7919, -1, 432, 771, -1, 431, + 803, -1, 7921, -1, 432, 803, -1, 89, + 768, -1, 7923, -1, 121, 768, -1, 89, + 803, -1, 7925, -1, 121, 803, -1, 89, + 777, -1, 7927, -1, 121, 777, -1, 89, + 771, -1, 7929, -1, 121, 771, -1, 945, + 787, -1, 945, 788, -1, 7936, 768, -1, + 7937, 768, -1, 7936, 769, -1, 7937, 769, + -1, 7936, 834, -1, 7937, 834, -1, 913, + 787, -1, 7936, -1, 913, 788, -1, 7937, + -1, 7944, 768, -1, 7938, -1, 7945, 768, + -1, 7939, -1, 7944, 769, -1, 7940, -1, + 7945, 769, -1, 7941, -1, 7944, 834, -1, + 7942, -1, 7945, 834, -1, 7943, -1, 949, + 787, -1, 949, 788, -1, 7952, 768, -1, + 7953, 768, -1, 7952, 769, -1, 7953, 769, + -1, 917, 787, -1, 7952, -1, 917, 788, + -1, 7953, -1, 7960, 768, -1, 7954, -1, + 7961, 768, -1, 7955, -1, 7960, 769, -1, + 7956, -1, 7961, 769, -1, 7957, -1, 951, + 787, -1, 951, 788, -1, 7968, 768, -1, + 7969, 768, -1, 7968, 769, -1, 7969, 769, + -1, 7968, 834, -1, 7969, 834, -1, 919, + 787, -1, 7968, -1, 919, 788, -1, 7969, + -1, 7976, 768, -1, 7970, -1, 7977, 768, + -1, 7971, -1, 7976, 769, -1, 7972, -1, + 7977, 769, -1, 7973, -1, 7976, 834, -1, + 7974, -1, 7977, 834, -1, 7975, -1, 953, + 787, -1, 953, 788, -1, 7984, 768, -1, + 7985, 768, -1, 7984, 769, -1, 7985, 769, + -1, 7984, 834, -1, 7985, 834, -1, 921, + 787, -1, 7984, -1, 921, 788, -1, 7985, + -1, 7992, 768, -1, 7986, -1, 7993, 768, + -1, 7987, -1, 7992, 769, -1, 7988, -1, + 7993, 769, -1, 7989, -1, 7992, 834, -1, + 7990, -1, 7993, 834, -1, 7991, -1, 959, + 787, -1, 959, 788, -1, 8000, 768, -1, + 8001, 768, -1, 8000, 769, -1, 8001, 769, + -1, 927, 787, -1, 8000, -1, 927, 788, + -1, 8001, -1, 8008, 768, -1, 8002, -1, + 8009, 768, -1, 8003, -1, 8008, 769, -1, + 8004, -1, 8009, 769, -1, 8005, -1, 965, + 787, -1, 965, 788, -1, 8016, 768, -1, + 965, 787, 768, -1, 8017, 768, -1, 8016, + 769, -1, 965, 787, 769, -1, 8017, 769, + -1, 8016, 834, -1, 965, 787, 834, -1, + 8017, 834, -1, 933, 788, -1, 8017, -1, + 8025, 768, -1, 8019, -1, 8025, 769, -1, + 8021, -1, 8025, 834, -1, 8023, -1, 969, + 787, -1, 969, 788, -1, 8032, 768, -1, + 8033, 768, -1, 8032, 769, -1, 8033, 769, + -1, 8032, 834, -1, 8033, 834, -1, 937, + 787, -1, 8032, -1, 937, 788, -1, 8033, + -1, 8040, 768, -1, 8034, -1, 8041, 768, + -1, 8035, -1, 8040, 769, -1, 8036, -1, + 8041, 769, -1, 8037, -1, 8040, 834, -1, + 8038, -1, 8041, 834, -1, 8039, -1, 945, + 768, -1, 949, 768, -1, 951, 768, -1, + 953, 768, -1, 959, 768, -1, 965, 768, + -1, 969, 768, -1, 7936, 837, -1, 7936, + 953, -1, 7937, 837, -1, 7937, 953, -1, + 7938, 837, -1, 7938, 953, -1, 7939, 837, + -1, 7939, 953, -1, 7940, 837, -1, 7940, + 953, -1, 7941, 837, -1, 7941, 953, -1, + 7942, 837, -1, 7942, 953, -1, 7943, 837, + -1, 7943, 953, -1, 7944, 837, -1, 8064, + -1, 7945, 837, -1, 8065, -1, 7946, 837, + -1, 8066, -1, 7947, 837, -1, 8067, -1, + 7948, 837, -1, 8068, -1, 7949, 837, -1, + 8069, -1, 7950, 837, -1, 8070, -1, 7951, + 837, -1, 8071, -1, 7968, 837, -1, 7968, + 953, -1, 7969, 837, -1, 7969, 953, -1, + 7970, 837, -1, 7970, 953, -1, 7971, 837, + -1, 7971, 953, -1, 7972, 837, -1, 7972, + 953, -1, 7973, 837, -1, 7973, 953, -1, + 7974, 837, -1, 7974, 953, -1, 7975, 837, + -1, 7975, 953, -1, 7976, 837, -1, 8080, + -1, 7977, 837, -1, 8081, -1, 7978, 837, + -1, 8082, -1, 7979, 837, -1, 8083, -1, + 7980, 837, -1, 8084, -1, 7981, 837, -1, + 8085, -1, 7982, 837, -1, 8086, -1, 7983, + 837, -1, 8087, -1, 8032, 837, -1, 8032, + 953, -1, 8033, 837, -1, 8033, 953, -1, + 8034, 837, -1, 8034, 953, -1, 8035, 837, + -1, 8035, 953, -1, 8036, 837, -1, 8036, + 953, -1, 8037, 837, -1, 8037, 953, -1, + 8038, 837, -1, 8038, 953, -1, 8039, 837, + -1, 8039, 953, -1, 8040, 837, -1, 8096, + -1, 8041, 837, -1, 8097, -1, 8042, 837, + -1, 8098, -1, 8043, 837, -1, 8099, -1, + 8044, 837, -1, 8100, -1, 8045, 837, -1, + 8101, -1, 8046, 837, -1, 8102, -1, 8047, + 837, -1, 8103, -1, 945, 774, -1, 945, + 772, -1, 8048, 837, -1, 8048, 953, -1, + 945, 837, -1, 945, 953, -1, 940, 837, + -1, 940, 953, -1, 945, 834, -1, 8118, + 837, -1, 945, 834, 953, -1, 913, 774, + -1, 8112, -1, 913, 772, -1, 8113, -1, + 913, 768, -1, 8048, -1, 902, -1, 8049, + -1, 913, 837, -1, 8115, -1, 32, 787, + -1, 32, 834, -1, 168, 834, -1, 8052, + 837, -1, 8052, 953, -1, 951, 837, -1, + 951, 953, -1, 942, 837, -1, 942, 953, + -1, 951, 834, -1, 8134, 837, -1, 951, + 834, 953, -1, 917, 768, -1, 8050, -1, + 904, -1, 8051, -1, 919, 768, -1, 8052, + -1, 905, -1, 8053, -1, 919, 837, -1, + 8131, -1, 8127, 768, -1, 8127, 769, -1, + 8127, 834, -1, 953, 774, -1, 953, 772, + -1, 970, 768, -1, 953, 776, 768, -1, + 912, -1, 953, 834, -1, 970, 834, -1, + 953, 776, 834, -1, 921, 774, -1, 8144, + -1, 921, 772, -1, 8145, -1, 921, 768, + -1, 8054, -1, 906, -1, 8055, -1, 8190, + 768, -1, 8190, 769, -1, 8190, 834, -1, + 965, 774, -1, 965, 772, -1, 971, 768, + -1, 965, 776, 768, -1, 944, -1, 961, + 787, -1, 961, 788, -1, 965, 834, -1, + 971, 834, -1, 965, 776, 834, -1, 933, + 774, -1, 8160, -1, 933, 772, -1, 8161, + -1, 933, 768, -1, 8058, -1, 910, -1, + 8059, -1, 929, 788, -1, 8165, -1, 168, + 768, -1, 901, -1, 96, -1, 8060, 837, + -1, 8060, 953, -1, 969, 837, -1, 969, + 953, -1, 974, 837, -1, 974, 953, -1, + 969, 834, -1, 8182, 837, -1, 969, 834, + 953, -1, 927, 768, -1, 8056, -1, 908, + -1, 8057, -1, 937, 768, -1, 8060, -1, + 911, -1, 8061, -1, 937, 837, -1, 8179, + -1, 180, -1, 32, 788, -1, 8194, -1, + 8195, -1, 8208, -1, 32, 819, -1, 46, + -1, 46, 46, -1, 46, 46, 46, -1, + 8242, 8242, -1, 8242, 8242, 8242, -1, 8245, + 8245, -1, 8245, 8245, 8245, -1, 33, 33, + -1, 32, 773, -1, 63, 63, -1, 63, + 33, -1, 33, 63, -1, 8242, 8242, 8242, + 8242, -1, 48, -1, 52, -1, 53, -1, + 54, -1, 55, -1, 56, -1, 57, -1, + 43, -1, 8722, -1, 61, -1, 40, -1, + 41, -1, 82, 115, -1, 97, 47, 99, + -1, 97, 47, 115, -1, 67, -1, 176, + 67, -1, 99, 47, 111, -1, 99, 47, + 117, -1, 400, -1, 176, 70, -1, 78, + 111, -1, 81, -1, 83, 77, -1, 84, + 69, 76, -1, 84, 77, -1, 90, -1, + 937, -1, 197, -1, 70, -1, 8526, -1, + 1488, -1, 1489, -1, 1490, -1, 1491, -1, + 70, 65, 88, -1, 915, -1, 928, -1, + 8721, -1, 49, 8260, 51, -1, 50, 8260, + 51, -1, 49, 8260, 53, -1, 50, 8260, + 53, -1, 51, 8260, 53, -1, 52, 8260, + 53, -1, 49, 8260, 54, -1, 53, 8260, + 54, -1, 49, 8260, 56, -1, 51, 8260, + 56, -1, 53, 8260, 56, -1, 55, 8260, + 56, -1, 49, 8260, -1, 8560, -1, 73, + 73, -1, 8561, -1, 73, 73, 73, -1, + 8562, -1, 73, 86, -1, 8563, -1, 86, + -1, 8564, -1, 86, 73, -1, 8565, -1, + 86, 73, 73, -1, 8566, -1, 86, 73, + 73, 73, -1, 8567, -1, 73, 88, -1, + 8568, -1, 88, -1, 8569, -1, 88, 73, + -1, 8570, -1, 88, 73, 73, -1, 8571, + -1, 8572, -1, 8573, -1, 8574, -1, 8575, + -1, 105, 105, -1, 105, 105, 105, -1, + 105, 118, -1, 118, 105, -1, 118, 105, + 105, -1, 118, 105, 105, 105, -1, 105, + 120, -1, 120, 105, -1, 120, 105, 105, + -1, 8580, -1, 8592, 824, -1, 8594, 824, + -1, 8596, 824, -1, 8656, 824, -1, 8660, + 824, -1, 8658, 824, -1, 8707, 824, -1, + 8712, 824, -1, 8715, 824, -1, 8739, 824, + -1, 8741, 824, -1, 8747, 8747, -1, 8747, + 8747, 8747, -1, 8750, 8750, -1, 8750, 8750, + 8750, -1, 8764, 824, -1, 8771, 824, -1, + 8773, 824, -1, 8776, 824, -1, 61, 824, + -1, 8801, 824, -1, 8781, 824, -1, 60, + 824, -1, 62, 824, -1, 8804, 824, -1, + 8805, 824, -1, 8818, 824, -1, 8819, 824, + -1, 8822, 824, -1, 8823, 824, -1, 8826, + 824, -1, 8827, 824, -1, 8834, 824, -1, + 8835, 824, -1, 8838, 824, -1, 8839, 824, + -1, 8866, 824, -1, 8872, 824, -1, 8873, + 824, -1, 8875, 824, -1, 8828, 824, -1, + 8829, 824, -1, 8849, 824, -1, 8850, 824, + -1, 8882, 824, -1, 8883, 824, -1, 8884, + 824, -1, 8885, 824, -1, 12296, -1, 12297, + -1, 49, 48, -1, 49, 49, -1, 49, + 50, -1, 49, 51, -1, 49, 52, -1, + 49, 53, -1, 49, 54, -1, 49, 55, + -1, 49, 56, -1, 49, 57, -1, 50, + 48, -1, 40, 49, 41, -1, 40, 50, + 41, -1, 40, 51, 41, -1, 40, 52, + 41, -1, 40, 53, 41, -1, 40, 54, + 41, -1, 40, 55, 41, -1, 40, 56, + 41, -1, 40, 57, 41, -1, 40, 49, + 48, 41, -1, 40, 49, 49, 41, -1, + 40, 49, 50, 41, -1, 40, 49, 51, + 41, -1, 40, 49, 52, 41, -1, 40, + 49, 53, 41, -1, 40, 49, 54, 41, + -1, 40, 49, 55, 41, -1, 40, 49, + 56, 41, -1, 40, 49, 57, 41, -1, + 40, 50, 48, 41, -1, 49, 46, -1, + 50, 46, -1, 51, 46, -1, 52, 46, + -1, 53, 46, -1, 54, 46, -1, 55, + 46, -1, 56, 46, -1, 57, 46, -1, + 49, 48, 46, -1, 49, 49, 46, -1, + 49, 50, 46, -1, 49, 51, 46, -1, + 49, 52, 46, -1, 49, 53, 46, -1, + 49, 54, 46, -1, 49, 55, 46, -1, + 49, 56, 46, -1, 49, 57, 46, -1, + 50, 48, 46, -1, 40, 97, 41, -1, + 40, 98, 41, -1, 40, 99, 41, -1, + 40, 100, 41, -1, 40, 101, 41, -1, + 40, 102, 41, -1, 40, 103, 41, -1, + 40, 104, 41, -1, 40, 105, 41, -1, + 40, 106, 41, -1, 40, 107, 41, -1, + 40, 108, 41, -1, 40, 109, 41, -1, + 40, 110, 41, -1, 40, 111, 41, -1, + 40, 112, 41, -1, 40, 113, 41, -1, + 40, 114, 41, -1, 40, 115, 41, -1, + 40, 116, 41, -1, 40, 117, 41, -1, + 40, 118, 41, -1, 40, 119, 41, -1, + 40, 120, 41, -1, 40, 121, 41, -1, + 40, 122, 41, -1, 9424, -1, 9425, -1, + 9426, -1, 9427, -1, 9428, -1, 9429, -1, + 9430, -1, 9431, -1, 9432, -1, 9433, -1, + 9434, -1, 9435, -1, 9436, -1, 9437, -1, + 9438, -1, 9439, -1, 9440, -1, 9441, -1, + 83, -1, 9442, -1, 9443, -1, 9444, -1, + 9445, -1, 9446, -1, 9447, -1, 89, -1, + 9448, -1, 9449, -1, 8747, 8747, 8747, 8747, + -1, 58, 58, 61, -1, 61, 61, -1, + 61, 61, 61, -1, 10973, 824, -1, 11312, + -1, 11313, -1, 11314, -1, 11315, -1, 11316, + -1, 11317, -1, 11318, -1, 11319, -1, 11320, + -1, 11321, -1, 11322, -1, 11323, -1, 11324, + -1, 11325, -1, 11326, -1, 11327, -1, 11328, + -1, 11329, -1, 11330, -1, 11331, -1, 11332, + -1, 11333, -1, 11334, -1, 11335, -1, 11336, + -1, 11337, -1, 11338, -1, 11339, -1, 11340, + -1, 11341, -1, 11342, -1, 11343, -1, 11344, + -1, 11345, -1, 11346, -1, 11347, -1, 11348, + -1, 11349, -1, 11350, -1, 11351, -1, 11352, + -1, 11353, -1, 11354, -1, 11355, -1, 11356, + -1, 11357, -1, 11358, -1, 11361, -1, 619, + -1, 7549, -1, 637, -1, 11368, -1, 11370, + -1, 11372, -1, 11382, -1, 11393, -1, 11395, + -1, 11397, -1, 11399, -1, 11401, -1, 11403, + -1, 11405, -1, 11407, -1, 11409, -1, 11411, + -1, 11413, -1, 11415, -1, 11417, -1, 11419, + -1, 11421, -1, 11423, -1, 11425, -1, 11427, + -1, 11429, -1, 11431, -1, 11433, -1, 11435, + -1, 11437, -1, 11439, -1, 11441, -1, 11443, + -1, 11445, -1, 11447, -1, 11449, -1, 11451, + -1, 11453, -1, 11455, -1, 11457, -1, 11459, + -1, 11461, -1, 11463, -1, 11465, -1, 11467, + -1, 11469, -1, 11471, -1, 11473, -1, 11475, + -1, 11477, -1, 11479, -1, 11481, -1, 11483, + -1, 11485, -1, 11487, -1, 11489, -1, 11491, + -1, 11617, -1, 27597, -1, 40863, -1, 19968, + -1, 20008, -1, 20022, -1, 20031, -1, 20057, + -1, 20101, -1, 20108, -1, 20128, -1, 20154, + -1, 20799, -1, 20837, -1, 20843, -1, 20866, + -1, 20886, -1, 20907, -1, 20960, -1, 20981, + -1, 20992, -1, 21147, -1, 21241, -1, 21269, + -1, 21274, -1, 21304, -1, 21313, -1, 21340, + -1, 21353, -1, 21378, -1, 21430, -1, 21448, + -1, 21475, -1, 22231, -1, 22303, -1, 22763, + -1, 22786, -1, 22794, -1, 22805, -1, 22823, + -1, 22899, -1, 23376, -1, 23424, -1, 23544, + -1, 23567, -1, 23586, -1, 23608, -1, 23662, + -1, 23665, -1, 24027, -1, 24037, -1, 24049, + -1, 24062, -1, 24178, -1, 24186, -1, 24191, + -1, 24308, -1, 24318, -1, 24331, -1, 24339, + -1, 24400, -1, 24417, -1, 24435, -1, 24515, + -1, 25096, -1, 25142, -1, 25163, -1, 25903, + -1, 25908, -1, 25991, -1, 26007, -1, 26020, + -1, 26041, -1, 26080, -1, 26085, -1, 26352, + -1, 26376, -1, 26408, -1, 27424, -1, 27490, + -1, 27513, -1, 27571, -1, 27595, -1, 27604, + -1, 27611, -1, 27663, -1, 27668, -1, 27700, + -1, 28779, -1, 29226, -1, 29238, -1, 29243, + -1, 29247, -1, 29255, -1, 29273, -1, 29275, + -1, 29356, -1, 29572, -1, 29577, -1, 29916, + -1, 29926, -1, 29976, -1, 29983, -1, 29992, + -1, 30000, -1, 30091, -1, 30098, -1, 30326, + -1, 30333, -1, 30382, -1, 30399, -1, 30446, + -1, 30683, -1, 30690, -1, 30707, -1, 31034, + -1, 31160, -1, 31166, -1, 31348, -1, 31435, + -1, 31481, -1, 31859, -1, 31992, -1, 32566, + -1, 32593, -1, 32650, -1, 32701, -1, 32769, + -1, 32780, -1, 32786, -1, 32819, -1, 32895, + -1, 32905, -1, 33251, -1, 33258, -1, 33267, + -1, 33276, -1, 33292, -1, 33307, -1, 33311, + -1, 33390, -1, 33394, -1, 33400, -1, 34381, + -1, 34411, -1, 34880, -1, 34892, -1, 34915, + -1, 35198, -1, 35211, -1, 35282, -1, 35328, + -1, 35895, -1, 35910, -1, 35925, -1, 35960, + -1, 35997, -1, 36196, -1, 36208, -1, 36275, + -1, 36523, -1, 36554, -1, 36763, -1, 36784, + -1, 36789, -1, 37009, -1, 37193, -1, 37318, + -1, 37324, -1, 37329, -1, 38263, -1, 38272, + -1, 38428, -1, 38582, -1, 38585, -1, 38632, + -1, 38737, -1, 38750, -1, 38754, -1, 38761, + -1, 38859, -1, 38893, -1, 38899, -1, 38913, + -1, 39080, -1, 39131, -1, 39135, -1, 39318, + -1, 39321, -1, 39340, -1, 39592, -1, 39640, + -1, 39647, -1, 39717, -1, 39727, -1, 39730, + -1, 39740, -1, 39770, -1, 40165, -1, 40565, + -1, 40575, -1, 40613, -1, 40635, -1, 40643, + -1, 40653, -1, 40657, -1, 40697, -1, 40701, + -1, 40718, -1, 40723, -1, 40736, -1, 40763, + -1, 40778, -1, 40786, -1, 40845, -1, 40860, + -1, 40864, -1, 12306, -1, 21316, -1, 21317, + -1, 12363, 12441, -1, 12365, 12441, -1, 12367, + 12441, -1, 12369, 12441, -1, 12371, 12441, -1, + 12373, 12441, -1, 12375, 12441, -1, 12377, 12441, + -1, 12379, 12441, -1, 12381, 12441, -1, 12383, + 12441, -1, 12385, 12441, -1, 12388, 12441, -1, + 12390, 12441, -1, 12392, 12441, -1, 12399, 12441, + -1, 12399, 12442, -1, 12402, 12441, -1, 12402, + 12442, -1, 12405, 12441, -1, 12405, 12442, -1, + 12408, 12441, -1, 12408, 12442, -1, 12411, 12441, + -1, 12411, 12442, -1, 12358, 12441, -1, 32, + 12441, -1, 32, 12442, -1, 12445, 12441, -1, + 12424, 12426, -1, 12459, 12441, -1, 12461, 12441, + -1, 12463, 12441, -1, 12465, 12441, -1, 12467, + 12441, -1, 12469, 12441, -1, 12471, 12441, -1, + 12473, 12441, -1, 12475, 12441, -1, 12477, 12441, + -1, 12479, 12441, -1, 12481, 12441, -1, 12484, + 12441, -1, 12486, 12441, -1, 12488, 12441, -1, + 12495, 12441, -1, 12495, 12442, -1, 12498, 12441, + -1, 12498, 12442, -1, 12501, 12441, -1, 12501, + 12442, -1, 12504, 12441, -1, 12504, 12442, -1, + 12507, 12441, -1, 12507, 12442, -1, 12454, 12441, + -1, 12527, 12441, -1, 12528, 12441, -1, 12529, + 12441, -1, 12530, 12441, -1, 12541, 12441, -1, + 12467, 12488, -1, 4352, -1, 4353, -1, 4522, + -1, 4354, -1, 4524, -1, 4525, -1, 4355, + -1, 4356, -1, 4357, -1, 4528, -1, 4529, + -1, 4530, -1, 4531, -1, 4532, -1, 4533, + -1, 4378, -1, 4358, -1, 4359, -1, 4360, + -1, 4385, -1, 4361, -1, 4362, -1, 4363, + -1, 4364, -1, 4365, -1, 4366, -1, 4367, + -1, 4368, -1, 4369, -1, 4370, -1, 4449, + -1, 4450, -1, 4451, -1, 4452, -1, 4453, + -1, 4454, -1, 4455, -1, 4456, -1, 4457, + -1, 4458, -1, 4459, -1, 4460, -1, 4461, + -1, 4462, -1, 4463, -1, 4464, -1, 4465, + -1, 4466, -1, 4467, -1, 4468, -1, 4469, + -1, 4448, -1, 4372, -1, 4373, -1, 4551, + -1, 4552, -1, 4556, -1, 4558, -1, 4563, + -1, 4567, -1, 4569, -1, 4380, -1, 4573, + -1, 4575, -1, 4381, -1, 4382, -1, 4384, + -1, 4386, -1, 4387, -1, 4391, -1, 4393, + -1, 4395, -1, 4396, -1, 4397, -1, 4398, + -1, 4399, -1, 4402, -1, 4406, -1, 4416, + -1, 4423, -1, 4428, -1, 4593, -1, 4594, + -1, 4439, -1, 4440, -1, 4441, -1, 4484, + -1, 4485, -1, 4488, -1, 4497, -1, 4498, + -1, 4500, -1, 4510, -1, 4513, -1, 19977, + -1, 22235, -1, 19978, -1, 20013, -1, 19979, + -1, 30002, -1, 19993, -1, 19969, -1, 22825, + -1, 22320, -1, 40, 4352, 41, -1, 40, + 4354, 41, -1, 40, 4355, 41, -1, 40, + 4357, 41, -1, 40, 4358, 41, -1, 40, + 4359, 41, -1, 40, 4361, 41, -1, 40, + 4363, 41, -1, 40, 4364, 41, -1, 40, + 4366, 41, -1, 40, 4367, 41, -1, 40, + 4368, 41, -1, 40, 4369, 41, -1, 40, + 4370, 41, -1, 40, 4352, 4449, 41, -1, + 40, 4354, 4449, 41, -1, 40, 4355, 4449, + 41, -1, 40, 4357, 4449, 41, -1, 40, + 4358, 4449, 41, -1, 40, 4359, 4449, 41, + -1, 40, 4361, 4449, 41, -1, 40, 4363, + 4449, 41, -1, 40, 4364, 4449, 41, -1, + 40, 4366, 4449, 41, -1, 40, 4367, 4449, + 41, -1, 40, 4368, 4449, 41, -1, 40, + 4369, 4449, 41, -1, 40, 4370, 4449, 41, + -1, 40, 4364, 4462, 41, -1, 40, 4363, + 4457, 4364, 4453, 4523, 41, -1, 40, 4363, + 4457, 4370, 4462, 41, -1, 40, 19968, 41, + -1, 40, 20108, 41, -1, 40, 19977, 41, + -1, 40, 22235, 41, -1, 40, 20116, 41, + -1, 40, 20845, 41, -1, 40, 19971, 41, + -1, 40, 20843, 41, -1, 40, 20061, 41, + -1, 40, 21313, 41, -1, 40, 26376, 41, + -1, 40, 28779, 41, -1, 40, 27700, 41, + -1, 40, 26408, 41, -1, 40, 37329, 41, + -1, 40, 22303, 41, -1, 40, 26085, 41, + -1, 40, 26666, 41, -1, 40, 26377, 41, + -1, 40, 31038, 41, -1, 40, 21517, 41, + -1, 40, 29305, 41, -1, 40, 36001, 41, + -1, 40, 31069, 41, -1, 40, 21172, 41, + -1, 40, 20195, 41, -1, 40, 21628, 41, + -1, 40, 23398, 41, -1, 40, 30435, 41, + -1, 40, 20225, 41, -1, 40, 36039, 41, + -1, 40, 21332, 41, -1, 40, 31085, 41, + -1, 40, 20241, 41, -1, 40, 33258, 41, + -1, 40, 33267, 41, -1, 80, 84, 69, + -1, 50, 49, -1, 50, 50, -1, 50, + 51, -1, 50, 52, -1, 50, 53, -1, + 50, 54, -1, 50, 55, -1, 50, 56, + -1, 50, 57, -1, 51, 48, -1, 51, + 49, -1, 51, 50, -1, 51, 51, -1, + 51, 52, -1, 51, 53, -1, 4352, 4449, + -1, 4354, 4449, -1, 4355, 4449, -1, 4357, + 4449, -1, 4358, 4449, -1, 4359, 4449, -1, + 4361, 4449, -1, 4363, 4449, -1, 4364, 4449, + -1, 4366, 4449, -1, 4367, 4449, -1, 4368, + 4449, -1, 4369, 4449, -1, 4370, 4449, -1, + 4366, 4449, 4535, 4352, 4457, -1, 4364, 4462, + 4363, 4468, -1, 4363, 4462, -1, 20116, -1, + 20845, -1, 19971, -1, 20061, -1, 26666, -1, + 26377, -1, 31038, -1, 21517, -1, 29305, -1, + 36001, -1, 31069, -1, 21172, -1, 31192, -1, + 30007, -1, 36969, -1, 20778, -1, 21360, -1, + 27880, -1, 38917, -1, 20241, -1, 20889, -1, + 27491, -1, 24038, -1, 21491, -1, 21307, -1, + 23447, -1, 23398, -1, 30435, -1, 20225, -1, + 36039, -1, 21332, -1, 22812, -1, 51, 54, + -1, 51, 55, -1, 51, 56, -1, 51, + 57, -1, 52, 48, -1, 52, 49, -1, + 52, 50, -1, 52, 51, -1, 52, 52, + -1, 52, 53, -1, 52, 54, -1, 52, + 55, -1, 52, 56, -1, 52, 57, -1, + 53, 48, -1, 49, 26376, -1, 50, 26376, + -1, 51, 26376, -1, 52, 26376, -1, 53, + 26376, -1, 54, 26376, -1, 55, 26376, -1, + 56, 26376, -1, 57, 26376, -1, 49, 48, + 26376, -1, 49, 49, 26376, -1, 49, 50, + 26376, -1, 72, 103, -1, 101, 114, 103, + -1, 101, 86, -1, 76, 84, 68, -1, + 12450, -1, 12452, -1, 12454, -1, 12456, -1, + 12458, -1, 12459, -1, 12461, -1, 12463, -1, + 12465, -1, 12467, -1, 12469, -1, 12471, -1, + 12473, -1, 12475, -1, 12477, -1, 12479, -1, + 12481, -1, 12484, -1, 12486, -1, 12488, -1, + 12490, -1, 12491, -1, 12492, -1, 12493, -1, + 12494, -1, 12495, -1, 12498, -1, 12501, -1, + 12504, -1, 12507, -1, 12510, -1, 12511, -1, + 12512, -1, 12513, -1, 12514, -1, 12516, -1, + 12518, -1, 12520, -1, 12521, -1, 12522, -1, + 12523, -1, 12524, -1, 12525, -1, 12527, -1, + 12528, -1, 12529, -1, 12530, -1, 12450, 12497, + 12540, 12488, -1, 12450, 12523, 12501, 12449, -1, + 12450, 12531, 12506, 12450, -1, 12450, 12540, 12523, + -1, 12452, 12491, 12531, 12464, -1, 12452, 12531, + 12481, -1, 12454, 12457, 12531, -1, 12456, 12473, + 12463, 12540, 12489, -1, 12456, 12540, 12459, 12540, + -1, 12458, 12531, 12473, -1, 12458, 12540, 12512, + -1, 12459, 12452, 12522, -1, 12459, 12521, 12483, + 12488, -1, 12459, 12525, 12522, 12540, -1, 12460, + 12525, 12531, -1, 12460, 12531, 12510, -1, 12462, + 12460, -1, 12462, 12491, 12540, -1, 12461, 12517, + 12522, 12540, -1, 12462, 12523, 12480, 12540, -1, + 12461, 12525, -1, 12461, 12525, 12464, 12521, 12512, + -1, 12461, 12525, 12513, 12540, 12488, 12523, -1, + 12461, 12525, 12527, 12483, 12488, -1, 12464, 12521, + 12512, -1, 12464, 12521, 12512, 12488, 12531, -1, + 12463, 12523, 12476, 12452, 12525, -1, 12463, 12525, + 12540, 12493, -1, 12465, 12540, 12473, -1, 12467, + 12523, 12490, -1, 12467, 12540, 12509, -1, 12469, + 12452, 12463, 12523, -1, 12469, 12531, 12481, 12540, + 12512, -1, 12471, 12522, 12531, 12464, -1, 12475, + 12531, 12481, -1, 12475, 12531, 12488, -1, 12480, + 12540, 12473, -1, 12487, 12471, -1, 12489, 12523, + -1, 12488, 12531, -1, 12490, 12494, -1, 12494, + 12483, 12488, -1, 12495, 12452, 12484, -1, 12497, + 12540, 12475, 12531, 12488, -1, 12497, 12540, 12484, + -1, 12496, 12540, 12524, 12523, -1, 12500, 12450, + 12473, 12488, 12523, -1, 12500, 12463, 12523, -1, + 12500, 12467, -1, 12499, 12523, -1, 12501, 12449, + 12521, 12483, 12489, -1, 12501, 12451, 12540, 12488, + -1, 12502, 12483, 12471, 12455, 12523, -1, 12501, + 12521, 12531, -1, 12504, 12463, 12479, 12540, 12523, + -1, 12506, 12477, -1, 12506, 12491, 12498, -1, + 12504, 12523, 12484, -1, 12506, 12531, 12473, -1, + 12506, 12540, 12472, -1, 12505, 12540, 12479, -1, + 12509, 12452, 12531, 12488, -1, 12508, 12523, 12488, + -1, 12507, 12531, -1, 12509, 12531, 12489, -1, + 12507, 12540, 12523, -1, 12507, 12540, 12531, -1, + 12510, 12452, 12463, 12525, -1, 12510, 12452, 12523, + -1, 12510, 12483, 12495, -1, 12510, 12523, 12463, + -1, 12510, 12531, 12471, 12519, 12531, -1, 12511, + 12463, 12525, 12531, -1, 12511, 12522, -1, 12511, + 12522, 12496, 12540, 12523, -1, 12513, 12460, -1, + 12513, 12460, 12488, 12531, -1, 12513, 12540, 12488, + 12523, -1, 12516, 12540, 12489, -1, 12516, 12540, + 12523, -1, 12518, 12450, 12531, -1, 12522, 12483, + 12488, 12523, -1, 12522, 12521, -1, 12523, 12500, + 12540, -1, 12523, 12540, 12502, 12523, -1, 12524, + 12512, -1, 12524, 12531, 12488, 12466, 12531, -1, + 12527, 12483, 12488, -1, 48, 28857, -1, 49, + 28857, -1, 50, 28857, -1, 51, 28857, -1, + 52, 28857, -1, 53, 28857, -1, 54, 28857, + -1, 55, 28857, -1, 56, 28857, -1, 57, + 28857, -1, 49, 48, 28857, -1, 49, 49, + 28857, -1, 49, 50, 28857, -1, 49, 51, + 28857, -1, 49, 52, 28857, -1, 49, 53, + 28857, -1, 49, 54, 28857, -1, 49, 55, + 28857, -1, 49, 56, 28857, -1, 49, 57, + 28857, -1, 50, 48, 28857, -1, 50, 49, + 28857, -1, 50, 50, 28857, -1, 50, 51, + 28857, -1, 50, 52, 28857, -1, 104, 80, + 97, -1, 100, 97, -1, 65, 85, -1, + 98, 97, 114, -1, 111, 86, -1, 112, + 99, -1, 100, 109, -1, 100, 109, 178, + -1, 100, 109, 179, -1, 73, 85, -1, + 24179, 25104, -1, 26157, 21644, -1, 22823, 27491, + -1, 26126, 27835, -1, 26666, 24335, 20250, 31038, + -1, 112, 65, -1, 110, 65, -1, 956, + 65, -1, 109, 65, -1, 107, 65, -1, + 75, 66, -1, 77, 66, -1, 71, 66, + -1, 99, 97, 108, -1, 107, 99, 97, + 108, -1, 112, 70, -1, 110, 70, -1, + 956, 70, -1, 956, 103, -1, 109, 103, + -1, 107, 103, -1, 72, 122, -1, 107, + 72, 122, -1, 77, 72, 122, -1, 71, + 72, 122, -1, 84, 72, 122, -1, 956, + 8467, -1, 109, 8467, -1, 100, 8467, -1, + 107, 8467, -1, 102, 109, -1, 110, 109, + -1, 956, 109, -1, 109, 109, -1, 99, + 109, -1, 107, 109, -1, 109, 109, 178, + -1, 99, 109, 178, -1, 109, 178, -1, + 107, 109, 178, -1, 109, 109, 179, -1, + 99, 109, 179, -1, 109, 179, -1, 107, + 109, 179, -1, 109, 8725, 115, -1, 109, + 8725, 115, 178, -1, 80, 97, -1, 107, + 80, 97, -1, 77, 80, 97, -1, 71, + 80, 97, -1, 114, 97, 100, -1, 114, + 97, 100, 8725, 115, -1, 114, 97, 100, + 8725, 115, 178, -1, 112, 115, -1, 110, + 115, -1, 956, 115, -1, 109, 115, -1, + 112, 86, -1, 110, 86, -1, 956, 86, + -1, 109, 86, -1, 107, 86, -1, 77, + 86, -1, 112, 87, -1, 110, 87, -1, + 956, 87, -1, 109, 87, -1, 107, 87, + -1, 77, 87, -1, 107, 937, -1, 77, + 937, -1, 97, 46, 109, 46, -1, 66, + 113, -1, 99, 99, -1, 99, 100, -1, + 67, 8725, 107, 103, -1, 67, 111, 46, + -1, 100, 66, -1, 71, 121, -1, 104, + 97, -1, 72, 80, -1, 105, 110, -1, + 75, 75, -1, 75, 77, -1, 107, 116, + -1, 108, 109, -1, 108, 110, -1, 108, + 111, 103, -1, 108, 120, -1, 109, 98, + -1, 109, 105, 108, -1, 109, 111, 108, + -1, 80, 72, -1, 112, 46, 109, 46, + -1, 80, 80, 77, -1, 80, 82, -1, + 115, 114, -1, 83, 118, -1, 87, 98, + -1, 86, 8725, 109, -1, 65, 8725, 109, + -1, 49, 26085, -1, 50, 26085, -1, 51, + 26085, -1, 52, 26085, -1, 53, 26085, -1, + 54, 26085, -1, 55, 26085, -1, 56, 26085, + -1, 57, 26085, -1, 49, 48, 26085, -1, + 49, 49, 26085, -1, 49, 50, 26085, -1, + 49, 51, 26085, -1, 49, 52, 26085, -1, + 49, 53, 26085, -1, 49, 54, 26085, -1, + 49, 55, 26085, -1, 49, 56, 26085, -1, + 49, 57, 26085, -1, 50, 48, 26085, -1, + 50, 49, 26085, -1, 50, 50, 26085, -1, + 50, 51, 26085, -1, 50, 52, 26085, -1, + 50, 53, 26085, -1, 50, 54, 26085, -1, + 50, 55, 26085, -1, 50, 56, 26085, -1, + 50, 57, 26085, -1, 51, 48, 26085, -1, + 51, 49, 26085, -1, 103, 97, 108, -1, + 35912, -1, 26356, -1, 36040, -1, 28369, -1, + 20018, -1, 21477, -1, 22865, -1, 21895, -1, + 22856, -1, 25078, -1, 30313, -1, 32645, -1, + 34367, -1, 34746, -1, 35064, -1, 37007, -1, + 27138, -1, 27931, -1, 28889, -1, 29662, -1, + 33853, -1, 37226, -1, 39409, -1, 20098, -1, + 21365, -1, 27396, -1, 29211, -1, 34349, -1, + 40478, -1, 23888, -1, 28651, -1, 34253, -1, + 35172, -1, 25289, -1, 33240, -1, 34847, -1, + 24266, -1, 26391, -1, 28010, -1, 29436, -1, + 37070, -1, 20358, -1, 20919, -1, 21214, -1, + 25796, -1, 27347, -1, 29200, -1, 30439, -1, + 34310, -1, 34396, -1, 36335, -1, 38706, -1, + 39791, -1, 40442, -1, 30860, -1, 31103, -1, + 32160, -1, 33737, -1, 37636, -1, 35542, -1, + 22751, -1, 24324, -1, 31840, -1, 32894, -1, + 29282, -1, 30922, -1, 36034, -1, 38647, -1, + 22744, -1, 23650, -1, 27155, -1, 28122, -1, + 28431, -1, 32047, -1, 32311, -1, 38475, -1, + 21202, -1, 32907, -1, 20956, -1, 20940, -1, + 31260, -1, 32190, -1, 33777, -1, 38517, -1, + 35712, -1, 25295, -1, 35582, -1, 20025, -1, + 23527, -1, 24594, -1, 29575, -1, 30064, -1, + 21271, -1, 30971, -1, 20415, -1, 24489, -1, + 19981, -1, 27852, -1, 25976, -1, 32034, -1, + 21443, -1, 22622, -1, 30465, -1, 33865, -1, + 35498, -1, 27578, -1, 27784, -1, 25342, -1, + 33509, -1, 25504, -1, 30053, -1, 20142, -1, + 20841, -1, 20937, -1, 26753, -1, 31975, -1, + 33391, -1, 35538, -1, 37327, -1, 21237, -1, + 21570, -1, 24300, -1, 26053, -1, 28670, -1, + 31018, -1, 38317, -1, 39530, -1, 40599, -1, + 40654, -1, 26310, -1, 27511, -1, 36706, -1, + 24180, -1, 24976, -1, 25088, -1, 25754, -1, + 28451, -1, 29001, -1, 29833, -1, 31178, -1, + 32244, -1, 32879, -1, 36646, -1, 34030, -1, + 36899, -1, 37706, -1, 21015, -1, 21155, -1, + 21693, -1, 28872, -1, 35010, -1, 24265, -1, + 24565, -1, 25467, -1, 27566, -1, 31806, -1, + 29557, -1, 20196, -1, 22265, -1, 23994, -1, + 24604, -1, 29618, -1, 29801, -1, 32666, -1, + 32838, -1, 37428, -1, 38646, -1, 38728, -1, + 38936, -1, 20363, -1, 31150, -1, 37300, -1, + 38584, -1, 24801, -1, 20102, -1, 20698, -1, + 23534, -1, 23615, -1, 26009, -1, 29134, -1, + 30274, -1, 34044, -1, 36988, -1, 26248, -1, + 38446, -1, 21129, -1, 26491, -1, 26611, -1, + 27969, -1, 28316, -1, 29705, -1, 30041, -1, + 30827, -1, 32016, -1, 39006, -1, 25134, -1, + 38520, -1, 20523, -1, 23833, -1, 28138, -1, + 36650, -1, 24459, -1, 24900, -1, 26647, -1, + 38534, -1, 21033, -1, 21519, -1, 23653, -1, + 26131, -1, 26446, -1, 26792, -1, 27877, -1, + 29702, -1, 30178, -1, 32633, -1, 35023, -1, + 35041, -1, 38626, -1, 21311, -1, 28346, -1, + 21533, -1, 29136, -1, 29848, -1, 34298, -1, + 38563, -1, 40023, -1, 40607, -1, 26519, -1, + 28107, -1, 33256, -1, 31520, -1, 31890, -1, + 29376, -1, 28825, -1, 35672, -1, 20160, -1, + 33590, -1, 21050, -1, 20999, -1, 24230, -1, + 25299, -1, 31958, -1, 23429, -1, 27934, -1, + 26292, -1, 36667, -1, 38477, -1, 24275, -1, + 20800, -1, 21952, -1, 22618, -1, 26228, -1, + 20958, -1, 29482, -1, 30410, -1, 31036, -1, + 31070, -1, 31077, -1, 31119, -1, 38742, -1, + 31934, -1, 34322, -1, 35576, -1, 36920, -1, + 37117, -1, 39151, -1, 39164, -1, 39208, -1, + 40372, -1, 20398, -1, 20711, -1, 20813, -1, + 21193, -1, 21220, -1, 21329, -1, 21917, -1, + 22022, -1, 22120, -1, 22592, -1, 22696, -1, + 23652, -1, 24724, -1, 24936, -1, 24974, -1, + 25074, -1, 25935, -1, 26082, -1, 26257, -1, + 26757, -1, 28023, -1, 28186, -1, 28450, -1, + 29038, -1, 29227, -1, 29730, -1, 30865, -1, + 31049, -1, 31048, -1, 31056, -1, 31062, -1, + 31117, -1, 31118, -1, 31296, -1, 31361, -1, + 31680, -1, 32265, -1, 32321, -1, 32626, -1, + 32773, -1, 33261, -1, 33401, -1, 33879, -1, + 35088, -1, 35222, -1, 35585, -1, 35641, -1, + 36051, -1, 36104, -1, 36790, -1, 38627, -1, + 38911, -1, 38971, -1, 20006, -1, 20917, -1, + 20840, -1, 20352, -1, 20805, -1, 20864, -1, + 21191, -1, 21242, -1, 21845, -1, 21913, -1, + 21986, -1, 22707, -1, 22852, -1, 22868, -1, + 23138, -1, 23336, -1, 24274, -1, 24281, -1, + 24425, -1, 24493, -1, 24792, -1, 24910, -1, + 24840, -1, 24928, -1, 25140, -1, 25540, -1, + 25628, -1, 25682, -1, 25942, -1, 26395, -1, + 26454, -1, 28379, -1, 28363, -1, 28702, -1, + 30631, -1, 29237, -1, 29359, -1, 29809, -1, + 29958, -1, 30011, -1, 30237, -1, 30239, -1, + 30427, -1, 30452, -1, 30538, -1, 30528, -1, + 30924, -1, 31409, -1, 31867, -1, 32091, -1, + 32574, -1, 33618, -1, 33775, -1, 34681, -1, + 35137, -1, 35206, -1, 35519, -1, 35531, -1, + 35565, -1, 35722, -1, 36664, -1, 36978, -1, + 37273, -1, 37494, -1, 38524, -1, 38875, -1, + 38923, -1, 39698, -1, 141386, -1, 141380, -1, + 144341, -1, 15261, -1, 16408, -1, 16441, -1, + 152137, -1, 154832, -1, 163539, -1, 40771, -1, + 40846, -1, 102, 102, -1, 102, 105, -1, + 102, 108, -1, 102, 102, 105, -1, 102, + 102, 108, -1, 383, 116, -1, 115, 116, + -1, 1396, 1398, -1, 1396, 1381, -1, 1396, + 1387, -1, 1406, 1398, -1, 1396, 1389, -1, + 1497, 1460, -1, 1522, 1463, -1, 1506, -1, + 1492, -1, 1499, -1, 1500, -1, 1501, -1, + 1512, -1, 1514, -1, 1513, 1473, -1, 1513, + 1474, -1, 64329, 1473, -1, 64329, 1474, -1, + 1488, 1463, -1, 1488, 1464, -1, 1488, 1468, + -1, 1489, 1468, -1, 1490, 1468, -1, 1491, + 1468, -1, 1492, 1468, -1, 1493, 1468, -1, + 1494, 1468, -1, 1496, 1468, -1, 1497, 1468, + -1, 1498, 1468, -1, 1499, 1468, -1, 1500, + 1468, -1, 1502, 1468, -1, 1504, 1468, -1, + 1505, 1468, -1, 1507, 1468, -1, 1508, 1468, + -1, 1510, 1468, -1, 1511, 1468, -1, 1512, + 1468, -1, 1513, 1468, -1, 1514, 1468, -1, + 1493, 1465, -1, 1489, 1471, -1, 1499, 1471, + -1, 1508, 1471, -1, 1488, 1500, -1, 1649, + -1, 1659, -1, 1662, -1, 1664, -1, 1658, + -1, 1663, -1, 1657, -1, 1700, -1, 1702, + -1, 1668, -1, 1667, -1, 1670, -1, 1671, + -1, 1677, -1, 1676, -1, 1678, -1, 1672, + -1, 1688, -1, 1681, -1, 1705, -1, 1711, + -1, 1715, -1, 1713, -1, 1722, -1, 1723, + -1, 1728, -1, 1729, -1, 1726, -1, 1746, + -1, 1747, -1, 1709, -1, 1735, -1, 1734, + -1, 1736, -1, 1655, -1, 1739, -1, 1733, + -1, 1737, -1, 1744, -1, 1609, -1, 1574, + 1575, -1, 1574, 1749, -1, 1574, 1608, -1, + 1574, 1735, -1, 1574, 1734, -1, 1574, 1736, + -1, 1574, 1744, -1, 1574, 1609, -1, 1740, + -1, 1574, 1580, -1, 1574, 1581, -1, 1574, + 1605, -1, 1574, 1610, -1, 1576, 1580, -1, + 1576, 1581, -1, 1576, 1582, -1, 1576, 1605, + -1, 1576, 1609, -1, 1576, 1610, -1, 1578, + 1580, -1, 1578, 1581, -1, 1578, 1582, -1, + 1578, 1605, -1, 1578, 1609, -1, 1578, 1610, + -1, 1579, 1580, -1, 1579, 1605, -1, 1579, + 1609, -1, 1579, 1610, -1, 1580, 1581, -1, + 1580, 1605, -1, 1581, 1580, -1, 1581, 1605, + -1, 1582, 1580, -1, 1582, 1581, -1, 1582, + 1605, -1, 1587, 1580, -1, 1587, 1581, -1, + 1587, 1582, -1, 1587, 1605, -1, 1589, 1581, + -1, 1589, 1605, -1, 1590, 1580, -1, 1590, + 1581, -1, 1590, 1582, -1, 1590, 1605, -1, + 1591, 1581, -1, 1591, 1605, -1, 1592, 1605, + -1, 1593, 1580, -1, 1593, 1605, -1, 1594, + 1580, -1, 1594, 1605, -1, 1601, 1580, -1, + 1601, 1581, -1, 1601, 1582, -1, 1601, 1605, + -1, 1601, 1609, -1, 1601, 1610, -1, 1602, + 1581, -1, 1602, 1605, -1, 1602, 1609, -1, + 1602, 1610, -1, 1603, 1575, -1, 1603, 1580, + -1, 1603, 1581, -1, 1603, 1582, -1, 1603, + 1604, -1, 1603, 1605, -1, 1603, 1609, -1, + 1603, 1610, -1, 1604, 1580, -1, 1604, 1581, + -1, 1604, 1582, -1, 1604, 1605, -1, 1604, + 1609, -1, 1604, 1610, -1, 1605, 1580, -1, + 1605, 1581, -1, 1605, 1582, -1, 1605, 1605, + -1, 1605, 1609, -1, 1605, 1610, -1, 1606, + 1580, -1, 1606, 1581, -1, 1606, 1582, -1, + 1606, 1605, -1, 1606, 1609, -1, 1606, 1610, + -1, 1607, 1580, -1, 1607, 1605, -1, 1607, + 1609, -1, 1607, 1610, -1, 1610, 1580, -1, + 1610, 1581, -1, 1610, 1582, -1, 1610, 1605, + -1, 1610, 1609, -1, 1610, 1610, -1, 1584, + 1648, -1, 1585, 1648, -1, 1609, 1648, -1, + 32, 1612, 1617, -1, 32, 1613, 1617, -1, + 32, 1614, 1617, -1, 32, 1615, 1617, -1, + 32, 1616, 1617, -1, 32, 1617, 1648, -1, + 1574, 1585, -1, 1574, 1586, -1, 1574, 1606, + -1, 1576, 1585, -1, 1576, 1586, -1, 1576, + 1606, -1, 1578, 1585, -1, 1578, 1586, -1, + 1578, 1606, -1, 1579, 1585, -1, 1579, 1586, + -1, 1579, 1606, -1, 1605, 1575, -1, 1606, + 1585, -1, 1606, 1586, -1, 1606, 1606, -1, + 1610, 1585, -1, 1610, 1586, -1, 1610, 1606, + -1, 1574, 1582, -1, 1574, 1607, -1, 1576, + 1607, -1, 1578, 1607, -1, 1589, 1582, -1, + 1604, 1607, -1, 1606, 1607, -1, 1607, 1648, + -1, 1610, 1607, -1, 1579, 1607, -1, 1587, + 1607, -1, 1588, 1605, -1, 1588, 1607, -1, + 1600, 1614, 1617, -1, 1600, 1615, 1617, -1, + 1600, 1616, 1617, -1, 1591, 1609, -1, 1591, + 1610, -1, 1593, 1609, -1, 1593, 1610, -1, + 1594, 1609, -1, 1594, 1610, -1, 1587, 1609, + -1, 1587, 1610, -1, 1588, 1609, -1, 1588, + 1610, -1, 1581, 1609, -1, 1581, 1610, -1, + 1580, 1609, -1, 1580, 1610, -1, 1582, 1609, + -1, 1582, 1610, -1, 1589, 1609, -1, 1589, + 1610, -1, 1590, 1609, -1, 1590, 1610, -1, + 1588, 1580, -1, 1588, 1581, -1, 1588, 1582, + -1, 1588, 1585, -1, 1587, 1585, -1, 1589, + 1585, -1, 1590, 1585, -1, 1575, 1611, -1, + 1578, 1580, 1605, -1, 1578, 1581, 1580, -1, + 1578, 1581, 1605, -1, 1578, 1582, 1605, -1, + 1578, 1605, 1580, -1, 1578, 1605, 1581, -1, + 1578, 1605, 1582, -1, 1580, 1605, 1581, -1, + 1581, 1605, 1610, -1, 1581, 1605, 1609, -1, + 1587, 1581, 1580, -1, 1587, 1580, 1581, -1, + 1587, 1580, 1609, -1, 1587, 1605, 1581, -1, + 1587, 1605, 1580, -1, 1587, 1605, 1605, -1, + 1589, 1581, 1581, -1, 1589, 1605, 1605, -1, + 1588, 1581, 1605, -1, 1588, 1580, 1610, -1, + 1588, 1605, 1582, -1, 1588, 1605, 1605, -1, + 1590, 1581, 1609, -1, 1590, 1582, 1605, -1, + 1591, 1605, 1581, -1, 1591, 1605, 1605, -1, + 1591, 1605, 1610, -1, 1593, 1580, 1605, -1, + 1593, 1605, 1605, -1, 1593, 1605, 1609, -1, + 1594, 1605, 1605, -1, 1594, 1605, 1610, -1, + 1594, 1605, 1609, -1, 1601, 1582, 1605, -1, + 1602, 1605, 1581, -1, 1602, 1605, 1605, -1, + 1604, 1581, 1605, -1, 1604, 1581, 1610, -1, + 1604, 1581, 1609, -1, 1604, 1580, 1580, -1, + 1604, 1582, 1605, -1, 1604, 1605, 1581, -1, + 1605, 1581, 1580, -1, 1605, 1581, 1605, -1, + 1605, 1581, 1610, -1, 1605, 1580, 1581, -1, + 1605, 1580, 1605, -1, 1605, 1582, 1580, -1, + 1605, 1582, 1605, -1, 1605, 1580, 1582, -1, + 1607, 1605, 1580, -1, 1607, 1605, 1605, -1, + 1606, 1581, 1605, -1, 1606, 1581, 1609, -1, + 1606, 1580, 1605, -1, 1606, 1580, 1609, -1, + 1606, 1605, 1610, -1, 1606, 1605, 1609, -1, + 1610, 1605, 1605, -1, 1576, 1582, 1610, -1, + 1578, 1580, 1610, -1, 1578, 1580, 1609, -1, + 1578, 1582, 1610, -1, 1578, 1582, 1609, -1, + 1578, 1605, 1610, -1, 1578, 1605, 1609, -1, + 1580, 1605, 1610, -1, 1580, 1581, 1609, -1, + 1580, 1605, 1609, -1, 1587, 1582, 1609, -1, + 1589, 1581, 1610, -1, 1588, 1581, 1610, -1, + 1590, 1581, 1610, -1, 1604, 1580, 1610, -1, + 1604, 1605, 1610, -1, 1610, 1581, 1610, -1, + 1610, 1580, 1610, -1, 1610, 1605, 1610, -1, + 1605, 1605, 1610, -1, 1602, 1605, 1610, -1, + 1606, 1581, 1610, -1, 1593, 1605, 1610, -1, + 1603, 1605, 1610, -1, 1606, 1580, 1581, -1, + 1605, 1582, 1610, -1, 1604, 1580, 1605, -1, + 1603, 1605, 1605, -1, 1580, 1581, 1610, -1, + 1581, 1580, 1610, -1, 1605, 1580, 1610, -1, + 1601, 1605, 1610, -1, 1576, 1581, 1610, -1, + 1587, 1582, 1610, -1, 1606, 1580, 1610, -1, + 1589, 1604, 1746, -1, 1602, 1604, 1746, -1, + 1575, 1604, 1604, 1607, -1, 1575, 1603, 1576, + 1585, -1, 1605, 1581, 1605, 1583, -1, 1589, + 1604, 1593, 1605, -1, 1585, 1587, 1608, 1604, + -1, 1593, 1604, 1610, 1607, -1, 1608, 1587, + 1604, 1605, -1, 1589, 1604, 1609, -1, 1589, + 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, + 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, + 1605, -1, 1580, 1604, 32, 1580, 1604, 1575, + 1604, 1607, -1, 1585, 1740, 1575, 1604, -1, + 44, -1, 12289, -1, 12290, -1, 58, -1, + 33, -1, 63, -1, 12310, -1, 12311, -1, + 8230, -1, 8229, -1, 8212, -1, 8211, -1, + 95, -1, 123, -1, 125, -1, 12308, -1, + 12309, -1, 12304, -1, 12305, -1, 12298, -1, + 12299, -1, 12300, -1, 12301, -1, 12302, -1, + 12303, -1, 91, -1, 93, -1, 8254, -1, + 35, -1, 38, -1, 42, -1, 45, -1, + 60, -1, 62, -1, 92, -1, 36, -1, + 37, -1, 64, -1, 32, 1611, -1, 1600, + 1611, -1, 32, 1612, -1, 32, 1613, -1, + 32, 1614, -1, 1600, 1614, -1, 32, 1615, + -1, 1600, 1615, -1, 32, 1616, -1, 1600, + 1616, -1, 32, 1617, -1, 1600, 1617, -1, + 32, 1618, -1, 1600, 1618, -1, 1569, -1, + 1570, -1, 1571, -1, 1572, -1, 1573, -1, + 1574, -1, 1575, -1, 1576, -1, 1577, -1, + 1578, -1, 1579, -1, 1580, -1, 1581, -1, + 1582, -1, 1583, -1, 1584, -1, 1585, -1, + 1586, -1, 1587, -1, 1588, -1, 1589, -1, + 1590, -1, 1591, -1, 1592, -1, 1593, -1, + 1594, -1, 1601, -1, 1602, -1, 1603, -1, + 1604, -1, 1605, -1, 1606, -1, 1607, -1, + 1608, -1, 1610, -1, 1604, 1570, -1, 1604, + 1571, -1, 1604, 1573, -1, 1604, 1575, -1, + 34, -1, 39, -1, 47, -1, 65345, -1, + 65346, -1, 65347, -1, 65348, -1, 65349, -1, + 65350, -1, 65351, -1, 65352, -1, 65353, -1, + 65354, -1, 65355, -1, 65356, -1, 65357, -1, + 65358, -1, 65359, -1, 65360, -1, 65361, -1, + 65362, -1, 65363, -1, 65364, -1, 65365, -1, + 65366, -1, 65367, -1, 65368, -1, 65369, -1, + 65370, -1, 94, -1, 124, -1, 126, -1, + 10629, -1, 10630, -1, 12539, -1, 12449, -1, + 12451, -1, 12453, -1, 12455, -1, 12457, -1, + 12515, -1, 12517, -1, 12519, -1, 12483, -1, + 12540, -1, 12531, -1, 12441, -1, 12442, -1, + 12644, -1, 12593, -1, 12594, -1, 12595, -1, + 12596, -1, 12597, -1, 12598, -1, 12599, -1, + 12600, -1, 12601, -1, 12602, -1, 12603, -1, + 12604, -1, 12605, -1, 12606, -1, 12607, -1, + 12608, -1, 12609, -1, 12610, -1, 12611, -1, + 12612, -1, 12613, -1, 12614, -1, 12615, -1, + 12616, -1, 12617, -1, 12618, -1, 12619, -1, + 12620, -1, 12621, -1, 12622, -1, 12623, -1, + 12624, -1, 12625, -1, 12626, -1, 12627, -1, + 12628, -1, 12629, -1, 12630, -1, 12631, -1, + 12632, -1, 12633, -1, 12634, -1, 12635, -1, + 12636, -1, 12637, -1, 12638, -1, 12639, -1, + 12640, -1, 12641, -1, 12642, -1, 12643, -1, + 162, -1, 163, -1, 172, -1, 175, -1, + 166, -1, 165, -1, 8361, -1, 9474, -1, + 8592, -1, 8593, -1, 8594, -1, 8595, -1, + 9632, -1, 9675, -1, 66600, -1, 66601, -1, + 66602, -1, 66603, -1, 66604, -1, 66605, -1, + 66606, -1, 66607, -1, 66608, -1, 66609, -1, + 66610, -1, 66611, -1, 66612, -1, 66613, -1, + 66614, -1, 66615, -1, 66616, -1, 66617, -1, + 66618, -1, 66619, -1, 66620, -1, 66621, -1, + 66622, -1, 66623, -1, 66624, -1, 66625, -1, + 66626, -1, 66627, -1, 66628, -1, 66629, -1, + 66630, -1, 66631, -1, 66632, -1, 66633, -1, + 66634, -1, 66635, -1, 66636, -1, 66637, -1, + 66638, -1, 66639, -1, 119127, 119141, -1, 119128, + 119141, -1, 119135, 119150, -1, 119135, 119151, -1, + 119135, 119152, -1, 119135, 119153, -1, 119135, 119154, + -1, 119225, 119141, -1, 119226, 119141, -1, 119227, + 119150, -1, 119228, 119150, -1, 119227, 119151, -1, + 119228, 119151, -1, 305, -1, 567, -1, 913, + -1, 914, -1, 916, -1, 917, -1, 918, + -1, 919, -1, 921, -1, 922, -1, 923, + -1, 924, -1, 925, -1, 926, -1, 927, + -1, 929, -1, 1012, -1, 932, -1, 934, + -1, 935, -1, 936, -1, 8711, -1, 8706, + -1, 1013, -1, 977, -1, 1008, -1, 981, + -1, 1009, -1, 982, -1, 988, -1, 20029, + -1, 20024, -1, 20033, -1, 131362, -1, 20320, + -1, 20411, -1, 20482, -1, 20602, -1, 20633, + -1, 20687, -1, 13470, -1, 132666, -1, 20820, + -1, 20836, -1, 20855, -1, 132380, -1, 13497, + -1, 20839, -1, 20877, -1, 132427, -1, 20887, + -1, 20900, -1, 20172, -1, 20908, -1, 168415, + -1, 20995, -1, 13535, -1, 21051, -1, 21062, + -1, 21106, -1, 21111, -1, 13589, -1, 21253, + -1, 21254, -1, 21321, -1, 21338, -1, 21363, + -1, 21373, -1, 21375, -1, 133676, -1, 28784, + -1, 21450, -1, 21471, -1, 133987, -1, 21483, + -1, 21489, -1, 21510, -1, 21662, -1, 21560, + -1, 21576, -1, 21608, -1, 21666, -1, 21750, + -1, 21776, -1, 21843, -1, 21859, -1, 21892, + -1, 21931, -1, 21939, -1, 21954, -1, 22294, + -1, 22295, -1, 22097, -1, 22132, -1, 22766, + -1, 22478, -1, 22516, -1, 22541, -1, 22411, + -1, 22578, -1, 22577, -1, 22700, -1, 136420, + -1, 22770, -1, 22775, -1, 22790, -1, 22810, + -1, 22818, -1, 22882, -1, 136872, -1, 136938, + -1, 23020, -1, 23067, -1, 23079, -1, 23000, + -1, 23142, -1, 14062, -1, 14076, -1, 23304, + -1, 23358, -1, 137672, -1, 23491, -1, 23512, + -1, 23539, -1, 138008, -1, 23551, -1, 23558, + -1, 24403, -1, 14209, -1, 23648, -1, 23744, + -1, 23693, -1, 138724, -1, 23875, -1, 138726, + -1, 23918, -1, 23915, -1, 23932, -1, 24033, + -1, 24034, -1, 14383, -1, 24061, -1, 24104, + -1, 24125, -1, 24169, -1, 14434, -1, 139651, + -1, 14460, -1, 24240, -1, 24243, -1, 24246, + -1, 172946, -1, 140081, -1, 33281, -1, 24354, + -1, 14535, -1, 144056, -1, 156122, -1, 24418, + -1, 24427, -1, 14563, -1, 24474, -1, 24525, + -1, 24535, -1, 24569, -1, 24705, -1, 14650, + -1, 14620, -1, 141012, -1, 24775, -1, 24904, + -1, 24908, -1, 24954, -1, 25010, -1, 24996, + -1, 25007, -1, 25054, -1, 25104, -1, 25115, + -1, 25181, -1, 25265, -1, 25300, -1, 25424, + -1, 142092, -1, 25405, -1, 25340, -1, 25448, + -1, 25475, -1, 25572, -1, 142321, -1, 25634, + -1, 25541, -1, 25513, -1, 14894, -1, 25705, + -1, 25726, -1, 25757, -1, 25719, -1, 14956, + -1, 25964, -1, 143370, -1, 26083, -1, 26360, + -1, 26185, -1, 15129, -1, 15112, -1, 15076, + -1, 20882, -1, 20885, -1, 26368, -1, 26268, + -1, 32941, -1, 17369, -1, 26401, -1, 26462, + -1, 26451, -1, 144323, -1, 15177, -1, 26618, + -1, 26501, -1, 26706, -1, 144493, -1, 26766, + -1, 26655, -1, 26900, -1, 26946, -1, 27043, + -1, 27114, -1, 27304, -1, 145059, -1, 27355, + -1, 15384, -1, 27425, -1, 145575, -1, 27476, + -1, 15438, -1, 27506, -1, 27551, -1, 27579, + -1, 146061, -1, 138507, -1, 146170, -1, 27726, + -1, 146620, -1, 27839, -1, 27853, -1, 27751, + -1, 27926, -1, 27966, -1, 28009, -1, 28024, + -1, 28037, -1, 146718, -1, 27956, -1, 28207, + -1, 28270, -1, 15667, -1, 28359, -1, 147153, + -1, 28153, -1, 28526, -1, 147294, -1, 147342, + -1, 28614, -1, 28729, -1, 28699, -1, 15766, + -1, 28746, -1, 28797, -1, 28791, -1, 28845, + -1, 132389, -1, 28997, -1, 148067, -1, 29084, + -1, 148395, -1, 29224, -1, 29264, -1, 149000, + -1, 29312, -1, 29333, -1, 149301, -1, 149524, + -1, 29562, -1, 29579, -1, 16044, -1, 29605, + -1, 16056, -1, 29767, -1, 29788, -1, 29829, + -1, 29898, -1, 16155, -1, 29988, -1, 150582, + -1, 30014, -1, 150674, -1, 139679, -1, 30224, + -1, 151457, -1, 151480, -1, 151620, -1, 16380, + -1, 16392, -1, 151795, -1, 151794, -1, 151833, + -1, 151859, -1, 30494, -1, 30495, -1, 30603, + -1, 16454, -1, 16534, -1, 152605, -1, 30798, + -1, 16611, -1, 153126, -1, 153242, -1, 153285, + -1, 31211, -1, 16687, -1, 31306, -1, 31311, + -1, 153980, -1, 154279, -1, 31470, -1, 16898, + -1, 154539, -1, 31686, -1, 31689, -1, 16935, + -1, 154752, -1, 31954, -1, 17056, -1, 31976, + -1, 31971, -1, 32000, -1, 155526, -1, 32099, + -1, 17153, -1, 32199, -1, 32258, -1, 32325, + -1, 17204, -1, 156200, -1, 156231, -1, 17241, + -1, 156377, -1, 32634, -1, 156478, -1, 32661, + -1, 32762, -1, 156890, -1, 156963, -1, 32864, + -1, 157096, -1, 32880, -1, 144223, -1, 17365, + -1, 32946, -1, 33027, -1, 17419, -1, 33086, + -1, 23221, -1, 157607, -1, 157621, -1, 144275, + -1, 144284, -1, 33284, -1, 36766, -1, 17515, + -1, 33425, -1, 33419, -1, 33437, -1, 21171, + -1, 33457, -1, 33459, -1, 33469, -1, 33510, + -1, 158524, -1, 33565, -1, 33635, -1, 33709, + -1, 33571, -1, 33725, -1, 33767, -1, 33619, + -1, 33738, -1, 33740, -1, 33756, -1, 158774, + -1, 159083, -1, 158933, -1, 17707, -1, 34033, + -1, 34035, -1, 34070, -1, 160714, -1, 34148, + -1, 159532, -1, 17757, -1, 17761, -1, 159665, + -1, 159954, -1, 17771, -1, 34384, -1, 34407, + -1, 34409, -1, 34473, -1, 34440, -1, 34574, + -1, 34530, -1, 34600, -1, 34667, -1, 34694, + -1, 17879, -1, 34785, -1, 34817, -1, 17913, + -1, 34912, -1, 161383, -1, 35031, -1, 35038, + -1, 17973, -1, 35066, -1, 13499, -1, 161966, + -1, 162150, -1, 18110, -1, 18119, -1, 35488, + -1, 162984, -1, 36011, -1, 36033, -1, 36123, + -1, 36215, -1, 163631, -1, 133124, -1, 36299, + -1, 36284, -1, 36336, -1, 133342, -1, 36564, + -1, 165330, -1, 165357, -1, 37012, -1, 37105, + -1, 37137, -1, 165678, -1, 37147, -1, 37432, + -1, 37591, -1, 37592, -1, 37500, -1, 37881, + -1, 37909, -1, 166906, -1, 38283, -1, 18837, + -1, 38327, -1, 167287, -1, 18918, -1, 38595, + -1, 23986, -1, 38691, -1, 168261, -1, 168474, + -1, 19054, -1, 19062, -1, 38880, -1, 168970, + -1, 19122, -1, 169110, -1, 38953, -1, 169398, + -1, 39138, -1, 19251, -1, 39209, -1, 39335, + -1, 39362, -1, 39422, -1, 19406, -1, 170800, + -1, 40000, -1, 40189, -1, 19662, -1, 19693, + -1, 40295, -1, 172238, -1, 19704, -1, 172293, + -1, 172558, -1, 172689, -1, 19798, -1, 40702, + -1, 40709, -1, 40719, -1, 40726, -1, 173568, + -1, }; + +const uint16_t utf8proc_stage1table[] = { + 0, 256, 512, 768, 1024, 1280, 1536, + 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, + 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632, + 5888, 6144, 6400, 6656, 6912, 2048, 7168, 7424, + 7680, 7936, 8192, 8448, 8704, 8960, 9216, 9472, + 9728, 9984, 10240, 10496, 10752, 11008, 11264, 11520, + 11776, 12032, 12288, 12544, 12800, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 13056, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 13312, 13568, 5376, 5376, 5376, 13824, 2048, 2048, + 14080, 14336, 2048, 2048, 2048, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 14592, 14848, 14848, 14848, 14848, 14848, 14848, 14848, + 14848, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15360, 15616, 15872, 16128, 16384, 16640, + 16896, 17152, 17408, 2048, 17664, 17920, 2048, 2048, + 2048, 18176, 18432, 18688, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 5376, 5376, 5376, 18944, 19200, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 19456, 19712, 19968, 20224, 20480, 20736, 20992, + 21248, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376, + 5376, 5376, 5376, 5376, 5376, 5376, 5376, 21504, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 21760, 22016, 22272, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 22528, 22784, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 23040, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104, + 23040, }; + +const uint16_t utf8proc_stage2table[] = { + 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 3, 2, 4, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 5, 5, 5, + 6, 7, 8, 8, 9, 10, 9, 8, + 8, 11, 12, 8, 13, 14, 15, 14, + 14, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 14, 8, 17, 18, 19, + 8, 8, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 11, 8, 12, 46, + 47, 46, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 11, 74, 12, 74, + 1, 1, 1, 1, 1, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 75, 8, 10, 10, 10, 10, 76, + 76, 77, 76, 78, 79, 74, 80, 76, + 81, 82, 83, 84, 85, 86, 87, 76, + 8, 88, 89, 90, 91, 92, 93, 94, + 8, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, + 74, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, + 74, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 213, 298, + 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 213, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 213, 213, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, + 336, 337, 338, 213, 339, 340, 341, 213, + 342, 339, 339, 339, 339, 343, 344, 345, + 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 433, + 434, 435, 213, 436, 437, 438, 439, 440, + 441, 442, 443, 444, 445, 446, 447, 448, + 449, 450, 451, 452, 453, 213, 213, 213, + 213, 213, 213, 454, 455, 456, 457, 458, + 213, 213, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, + 473, 213, 213, 213, 474, 475, 213, 476, + 477, 213, 478, 213, 479, 213, 213, 213, + 213, 480, 213, 213, 481, 213, 213, 213, + 213, 482, 483, 213, 484, 213, 213, 213, + 485, 213, 213, 486, 213, 213, 487, 213, + 213, 213, 213, 213, 213, 213, 488, 213, + 213, 489, 213, 213, 490, 213, 213, 213, + 213, 491, 492, 493, 494, 495, 213, 213, + 213, 213, 213, 496, 213, 339, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 497, 498, 499, 500, 501, 502, 503, + 504, 505, 506, 506, 507, 507, 507, 507, + 507, 507, 507, 46, 46, 46, 46, 506, + 506, 506, 506, 506, 506, 506, 506, 506, + 506, 507, 507, 46, 46, 46, 46, 46, + 46, 508, 509, 510, 511, 512, 513, 46, + 46, 514, 515, 516, 517, 518, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 507, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 519, 520, 521, 522, 523, 524, 525, + 526, 527, 528, 529, 530, 531, 524, 524, + 532, 524, 533, 524, 534, 535, 536, 537, + 537, 537, 537, 536, 538, 537, 537, 537, + 537, 537, 539, 539, 540, 541, 542, 543, + 544, 545, 537, 537, 537, 537, 546, 547, + 537, 548, 549, 537, 537, 550, 550, 550, + 550, 551, 537, 537, 537, 537, 524, 524, + 524, 552, 553, 554, 555, 556, 557, 524, + 537, 537, 537, 524, 524, 524, 537, 537, + 558, 524, 524, 524, 537, 537, 537, 537, + 524, 536, 537, 537, 524, 559, 560, 560, + 559, 560, 560, 559, 524, 524, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, + 524, 0, 0, 0, 0, 561, 46, 0, + 0, 0, 0, 562, 563, 564, 565, 566, + 0, 0, 0, 0, 0, 86, 567, 568, + 569, 570, 571, 572, 0, 573, 0, 574, + 575, 576, 577, 578, 579, 580, 581, 582, + 583, 584, 585, 586, 587, 588, 589, 590, + 591, 592, 593, 0, 594, 595, 596, 597, + 598, 599, 600, 601, 602, 603, 604, 605, + 606, 607, 608, 609, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 619, 620, 621, + 622, 623, 624, 625, 626, 627, 628, 629, + 630, 631, 632, 633, 634, 635, 636, 637, + 0, 638, 639, 640, 641, 642, 643, 644, + 213, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 659, + 660, 661, 662, 663, 664, 665, 666, 667, + 668, 669, 670, 671, 213, 672, 673, 74, + 674, 675, 676, 677, 678, 213, 679, 680, + 681, 682, 683, 684, 685, 686, 687, 688, + 689, 690, 691, 692, 693, 694, 695, 696, + 697, 698, 699, 700, 701, 702, 703, 704, + 705, 706, 707, 708, 709, 710, 711, 712, + 713, 714, 715, 716, 717, 718, 719, 720, + 721, 722, 723, 724, 725, 726, 727, 728, + 729, 730, 731, 732, 733, 734, 735, 736, + 737, 738, 739, 740, 741, 742, 743, 744, + 745, 746, 747, 748, 749, 750, 751, 752, + 753, 754, 755, 756, 757, 758, 759, 760, + 761, 762, 763, 764, 765, 766, 767, 768, + 769, 770, 771, 772, 773, 774, 775, 776, + 777, 778, 779, 780, 781, 782, 783, 784, + 785, 786, 787, 788, 789, 790, 791, 792, + 793, 794, 795, 796, 797, 798, 799, 800, + 801, 802, 803, 804, 805, 806, 807, 808, + 809, 810, 811, 812, 524, 524, 524, 524, + 0, 813, 813, 814, 815, 816, 817, 818, + 819, 820, 821, 822, 823, 824, 825, 826, + 827, 828, 829, 830, 831, 832, 833, 834, + 835, 836, 837, 838, 839, 840, 841, 842, + 843, 844, 845, 846, 847, 848, 849, 850, + 851, 852, 853, 854, 855, 856, 857, 858, + 859, 860, 861, 862, 863, 864, 865, 866, + 867, 868, 869, 870, 871, 872, 873, 874, + 875, 876, 877, 878, 879, 880, 881, 882, + 883, 884, 885, 886, 887, 888, 889, 890, + 891, 892, 893, 894, 895, 896, 897, 898, + 899, 900, 901, 902, 903, 904, 905, 906, + 907, 908, 909, 910, 911, 912, 913, 914, + 915, 916, 917, 918, 919, 920, 921, 922, + 923, 924, 925, 926, 927, 928, 929, 930, + 931, 932, 933, 934, 935, 936, 937, 938, + 939, 940, 941, 942, 943, 944, 945, 946, + 947, 948, 949, 950, 951, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 952, 953, 954, 955, 956, 957, + 958, 959, 960, 961, 962, 963, 964, 965, + 966, 967, 968, 969, 970, 971, 972, 973, + 974, 975, 976, 977, 978, 979, 980, 981, + 982, 983, 984, 985, 986, 987, 988, 989, + 0, 0, 507, 990, 990, 990, 990, 990, + 990, 0, 991, 992, 993, 994, 995, 996, + 997, 998, 999, 1000, 1001, 1002, 1003, 1004, + 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, + 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, + 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 0, 990, 1030, 0, 0, 0, 0, + 0, 0, 537, 524, 524, 524, 524, 537, + 524, 524, 524, 1031, 537, 524, 524, 524, + 524, 524, 524, 537, 537, 537, 537, 537, + 537, 524, 524, 537, 524, 524, 1031, 1032, + 524, 1033, 1034, 1035, 1036, 1037, 1038, 1039, + 1040, 1041, 1042, 1042, 1043, 1044, 1045, 1046, + 1047, 1046, 1048, 1049, 1046, 524, 537, 1046, + 1041, 0, 0, 0, 0, 0, 0, 0, + 0, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 0, 0, 0, 0, + 0, 1050, 1050, 1050, 1046, 1046, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1051, 1051, 1051, 1051, 0, 0, 0, + 0, 0, 0, 0, 1052, 14, 1053, 76, + 76, 524, 524, 524, 524, 524, 524, 0, + 0, 0, 0, 0, 1053, 0, 0, 1053, + 1053, 0, 1054, 1055, 1056, 1057, 1058, 1059, + 1060, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 0, 0, 0, 0, + 0, 1061, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1062, 1054, 1063, 1064, 1065, 1066, 1067, + 1068, 1069, 1070, 1071, 1072, 1073, 1074, 537, + 524, 524, 524, 524, 524, 537, 524, 524, + 0, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075, 1075, 9, 1076, 1076, 1053, 1054, + 1054, 1077, 1054, 1054, 1054, 1054, 1078, 1079, + 1080, 1081, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1082, 1083, 1084, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1085, 1086, 1053, 1087, 524, + 524, 524, 524, 524, 524, 524, 1051, 813, + 524, 524, 524, 524, 537, 524, 1061, 1061, + 524, 524, 76, 537, 524, 524, 537, 1054, + 1054, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 1054, 1054, 1054, 1088, 1088, + 1054, 1053, 1053, 1053, 1053, 1053, 1053, 1053, + 1053, 1053, 1053, 1053, 1053, 1053, 1053, 0, + 80, 1054, 1089, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 524, 537, 524, 524, 537, 524, 524, + 537, 537, 537, 524, 537, 537, 524, 537, + 524, 524, 524, 537, 524, 537, 524, 537, + 524, 537, 524, 524, 0, 0, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, + 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1090, + 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, + 1090, 1090, 1054, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091, 1091, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 524, 524, 524, 524, + 524, 524, 524, 537, 524, 1092, 1092, 76, + 8, 8, 8, 1092, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1090, 1090, 1093, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 1094, 1095, 339, 339, 339, 339, 339, + 339, 1096, 1097, 339, 1098, 1099, 339, 339, + 339, 339, 339, 0, 0, 1100, 339, 1093, + 1093, 1093, 1090, 1090, 1090, 1090, 1090, 1090, + 1090, 1090, 1093, 1093, 1093, 1093, 1101, 0, + 0, 339, 524, 537, 524, 524, 0, 0, + 0, 1102, 1103, 1104, 1105, 1106, 1107, 1108, + 1109, 339, 339, 1090, 1090, 990, 990, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 990, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 339, 339, 339, 339, + 339, 0, 1090, 1093, 1093, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 0, + 339, 339, 0, 0, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 0, 0, 0, 339, + 339, 339, 339, 0, 0, 1111, 339, 1112, + 1093, 1093, 1090, 1090, 1090, 1090, 0, 0, + 1113, 1093, 0, 0, 1114, 1115, 1101, 339, + 0, 0, 0, 0, 0, 0, 0, 0, + 1116, 0, 0, 0, 0, 1117, 1118, 0, + 1119, 339, 339, 1090, 1090, 0, 0, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 339, 339, 10, 10, 1120, 1120, 1120, + 1120, 1120, 1120, 812, 0, 0, 0, 0, + 0, 0, 1090, 1090, 1093, 0, 339, 339, + 339, 339, 339, 339, 0, 0, 0, 0, + 339, 339, 0, 0, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 1121, 0, 339, 1122, + 0, 339, 339, 0, 0, 1111, 0, 1093, + 1093, 1093, 1090, 1090, 0, 0, 0, 0, + 1090, 1090, 0, 0, 1090, 1090, 1101, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1123, 1124, 1125, 339, 0, 1126, + 0, 0, 0, 0, 0, 0, 0, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1090, 1090, 339, 339, 339, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1090, 1090, 1093, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 0, + 339, 339, 339, 0, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 0, 339, 339, + 339, 339, 339, 0, 0, 1111, 339, 1093, + 1093, 1093, 1090, 1090, 1090, 1090, 1090, 0, + 1090, 1090, 1093, 0, 1093, 1093, 1101, 0, + 0, 339, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 1090, 1090, 0, 0, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 0, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1090, 1093, 1093, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 0, + 339, 339, 0, 0, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 0, 339, 339, + 339, 339, 339, 0, 0, 1111, 339, 1127, + 1090, 1093, 1090, 1090, 1090, 0, 0, 0, + 1128, 1129, 0, 0, 1130, 1131, 1101, 0, + 0, 0, 0, 0, 0, 0, 0, 1132, + 1133, 0, 0, 0, 0, 1134, 1135, 0, + 339, 339, 339, 0, 0, 0, 0, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 812, 339, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1090, 339, 0, 339, 339, + 339, 339, 339, 339, 0, 0, 0, 339, + 339, 339, 0, 1136, 339, 1137, 339, 0, + 0, 0, 339, 339, 0, 339, 0, 339, + 339, 0, 0, 0, 339, 339, 0, 0, + 0, 339, 339, 339, 0, 0, 0, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 0, 0, 0, 0, 1138, + 1093, 1090, 1093, 1093, 0, 0, 0, 1139, + 1140, 1093, 0, 1141, 1142, 1143, 1101, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1144, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1120, 1120, 1120, 76, 76, 76, 76, + 76, 76, 10, 76, 0, 0, 0, 0, + 0, 0, 1093, 1093, 1093, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 0, 339, 339, + 339, 339, 339, 0, 0, 0, 0, 1090, + 1090, 1090, 1093, 1093, 1093, 1093, 0, 1145, + 1090, 1146, 0, 1090, 1090, 1090, 1101, 0, + 0, 0, 0, 0, 0, 0, 1147, 1148, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 0, 0, 0, 0, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1093, 1093, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 0, 339, 339, + 339, 339, 339, 0, 0, 1111, 339, 1093, + 1149, 1150, 1093, 1151, 1093, 1093, 0, 1152, + 1153, 1154, 0, 1155, 1156, 1090, 1101, 0, + 0, 0, 0, 0, 0, 0, 1157, 1158, + 0, 0, 0, 0, 0, 0, 0, 339, + 0, 339, 339, 1090, 1090, 0, 0, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 0, 76, 76, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1093, 1093, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 0, 0, 0, 0, 1159, + 1093, 1093, 1090, 1090, 1090, 0, 0, 1160, + 1161, 1093, 0, 1162, 1163, 1164, 1101, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1165, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 0, 0, 0, 0, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1093, 1093, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 0, 0, 0, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 0, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 0, 339, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 0, 0, 1166, 0, 0, 0, 0, + 1167, 1093, 1093, 1090, 1090, 1090, 0, 1090, + 0, 1093, 1168, 1169, 1093, 1170, 1171, 1172, + 1173, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1093, 1093, 990, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 1090, 339, 1174, 1090, 1090, 1090, + 1090, 1175, 1175, 1101, 0, 0, 0, 0, + 10, 339, 339, 339, 339, 339, 339, 507, + 1090, 1176, 1176, 1176, 1176, 1090, 1090, 1090, + 990, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 990, 990, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 339, 339, 0, 339, 0, 0, + 339, 339, 0, 339, 0, 0, 339, 0, + 0, 0, 0, 0, 0, 339, 339, 339, + 339, 0, 339, 339, 339, 339, 339, 339, + 339, 0, 339, 339, 339, 0, 339, 0, + 339, 0, 0, 339, 339, 0, 339, 339, + 339, 339, 1090, 339, 1177, 1090, 1090, 1090, + 1090, 1178, 1178, 0, 1090, 1090, 339, 0, + 0, 339, 339, 339, 339, 339, 0, 507, + 0, 1179, 1179, 1179, 1179, 1090, 1090, 0, + 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 0, 0, 1180, 1181, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 812, 812, 812, 990, 990, 990, + 990, 990, 990, 990, 990, 1182, 990, 990, + 990, 990, 990, 990, 812, 812, 812, 812, + 812, 537, 537, 812, 812, 812, 812, 812, + 812, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 812, 537, 812, + 537, 812, 1183, 11, 12, 11, 12, 1093, + 1093, 339, 339, 339, 1184, 339, 339, 339, + 339, 0, 339, 339, 339, 339, 1185, 339, + 339, 339, 339, 1186, 339, 339, 339, 339, + 1187, 339, 339, 339, 339, 1188, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 1189, 339, 0, 0, 0, 0, + 0, 0, 1190, 1191, 1192, 1193, 1194, 1195, + 1196, 1197, 1198, 1191, 1191, 1191, 1191, 1090, + 1093, 1191, 1199, 524, 524, 1101, 990, 524, + 524, 339, 339, 339, 339, 0, 0, 0, + 0, 1090, 1090, 1090, 1200, 1090, 1090, 1090, + 1090, 0, 1090, 1090, 1090, 1090, 1201, 1090, + 1090, 1090, 1090, 1202, 1090, 1090, 1090, 1090, + 1203, 1090, 1090, 1090, 1090, 1204, 1090, 1090, + 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090, + 1090, 1090, 1205, 1090, 1090, 1090, 0, 812, + 812, 812, 812, 812, 812, 812, 812, 537, + 812, 812, 812, 812, 812, 812, 0, 0, + 812, 990, 990, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 0, 339, 339, 1206, 1207, + 339, 0, 339, 339, 0, 1093, 1090, 1208, + 1090, 1090, 1093, 1090, 0, 0, 0, 1090, + 1111, 1093, 1101, 0, 0, 0, 0, 0, + 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 990, 990, 990, 990, 990, + 990, 339, 339, 339, 339, 339, 339, 1093, + 1093, 1090, 1090, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1209, 1210, 1211, 1212, 1213, 1214, 1215, + 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, + 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, + 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, + 1240, 1241, 1242, 1243, 1244, 1245, 1246, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 990, 1247, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 0, 0, 0, 0, 0, + 1248, 1248, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 0, 339, 339, 339, 339, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 0, 339, 339, 339, 339, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 0, 339, 339, 339, 339, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 0, 0, 0, 0, + 524, 812, 990, 990, 990, 990, 990, 990, + 990, 990, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 990, 990, + 339, 339, 339, 339, 339, 339, 339, 339, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 11, 12, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 990, 990, 990, 1249, + 1249, 1249, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 339, + 339, 339, 339, 1090, 1090, 1101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 1090, 1090, 1101, 990, 990, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 1090, 1090, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 339, + 339, 339, 0, 1090, 1090, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 1250, 1250, 1093, + 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1090, + 1093, 1093, 1090, 1090, 1090, 1090, 1090, 1090, + 1090, 1090, 1090, 1101, 1090, 990, 990, 990, + 507, 990, 990, 990, 10, 339, 524, 0, + 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 0, 0, 0, 0, 0, + 0, 1251, 1251, 1251, 1251, 1251, 1251, 1251, + 1251, 1251, 1251, 0, 0, 0, 0, 0, + 0, 8, 8, 8, 8, 8, 8, 1030, + 8, 8, 8, 8, 558, 558, 558, 7, + 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 507, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 1032, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 0, + 0, 1090, 1090, 1090, 1093, 1093, 1093, 1093, + 1090, 1090, 1252, 1252, 1252, 0, 0, 0, + 0, 1093, 1093, 1090, 1093, 1093, 1093, 1093, + 1093, 1093, 1031, 524, 537, 0, 0, 0, + 0, 76, 0, 0, 0, 8, 8, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 0, + 0, 339, 339, 339, 339, 339, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 0, 0, 0, 0, 0, + 0, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 339, 339, 339, 339, 339, 339, + 339, 1093, 1093, 0, 0, 0, 0, 0, + 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 0, 0, 0, 0, 8, + 8, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 524, 537, 1093, 1093, 1093, 0, 0, 990, + 990, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1090, 1090, 1090, 1090, 1093, 1253, 1254, + 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, + 339, 339, 1263, 1264, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 1111, 1265, 1090, + 1090, 1090, 1090, 1266, 1267, 1268, 1269, 1270, + 1271, 1272, 1273, 1274, 1275, 1276, 339, 339, + 339, 339, 339, 339, 339, 0, 0, 0, + 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 990, 990, 990, 990, 990, + 990, 990, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 524, 537, 524, 524, + 524, 524, 524, 524, 524, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 1277, 1278, 1279, + 507, 1280, 1281, 1282, 1283, 1284, 1285, 1286, + 1287, 1288, 1289, 1290, 507, 1291, 1292, 1293, + 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, + 1302, 1303, 1304, 1305, 1306, 1307, 1308, 507, + 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, + 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, + 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, + 1333, 1334, 1335, 1336, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 1337, 213, 213, 213, 213, 1338, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 1339, 1340, 1341, 1342, + 1307, 1343, 1344, 1345, 1346, 1347, 1348, 1349, + 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, + 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, + 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, + 1374, 524, 524, 537, 524, 524, 524, 524, + 524, 524, 524, 537, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 524, + 537, 1375, 1376, 1377, 1378, 1379, 1380, 1381, + 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, + 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, + 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, + 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, + 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, + 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, + 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, + 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, + 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, + 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, + 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, + 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, + 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, + 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, + 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, + 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, + 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, + 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, + 1526, 1527, 1528, 1529, 1530, 0, 0, 0, + 0, 1531, 1532, 1533, 1534, 1535, 1536, 1537, + 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, + 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, + 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, + 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, + 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, + 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, + 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, + 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, + 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, + 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, + 1618, 1619, 1620, 0, 0, 0, 0, 0, + 0, 1621, 1622, 1623, 1624, 1625, 1626, 1627, + 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, + 1636, 1637, 1638, 1639, 1640, 1641, 1642, 0, + 0, 1643, 1644, 1645, 1646, 1647, 1648, 0, + 0, 1649, 1650, 1651, 1652, 1653, 1654, 1655, + 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, + 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, + 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, + 1680, 1681, 1682, 1683, 1684, 1685, 1686, 0, + 0, 1687, 1688, 1689, 1690, 1691, 1692, 0, + 0, 1693, 1694, 1695, 1696, 1697, 1698, 1699, + 1700, 0, 1701, 0, 1702, 0, 1703, 0, + 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, + 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, + 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, + 1728, 1729, 1730, 1731, 1732, 1733, 1734, 0, + 0, 1735, 1736, 1737, 1738, 1739, 1740, 1741, + 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, + 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, + 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, + 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, + 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, + 1782, 1783, 1784, 1785, 1786, 1787, 0, 1788, + 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, + 1797, 1798, 1799, 1800, 1801, 1802, 0, 1803, + 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, + 1812, 1813, 1814, 1815, 1816, 0, 0, 1817, + 1818, 1819, 1820, 1821, 1822, 0, 1823, 1824, + 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, + 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, + 1841, 0, 0, 1842, 1843, 1844, 0, 1845, + 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, + 0, 1854, 1855, 1856, 1856, 1856, 1856, 1856, + 1857, 1856, 1856, 1856, 80, 1858, 1858, 1250, + 1859, 1030, 1860, 1030, 1030, 1030, 1030, 8, + 1861, 79, 91, 11, 79, 79, 91, 11, + 79, 8, 8, 8, 8, 1862, 1863, 1864, + 8, 1865, 1866, 1867, 1868, 1869, 1870, 1871, + 75, 9, 9, 9, 1872, 1873, 8, 1874, + 1875, 8, 79, 91, 8, 1876, 8, 1877, + 47, 47, 8, 8, 8, 1878, 11, 12, + 1879, 1880, 1881, 8, 8, 8, 8, 8, + 8, 8, 8, 74, 8, 47, 8, 8, + 1882, 8, 8, 8, 8, 8, 8, 8, + 1856, 80, 80, 80, 80, 0, 0, 0, + 0, 0, 0, 80, 80, 80, 80, 80, + 80, 1883, 1884, 0, 0, 1885, 1886, 1887, + 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, + 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, + 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, + 0, 1912, 1913, 1914, 1915, 1916, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 10, 10, 10, 10, 10, 10, 10, + 10, 1917, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 524, 524, 550, 550, 524, 524, 524, + 524, 550, 550, 550, 524, 524, 813, 813, + 813, 813, 524, 813, 813, 813, 550, 550, + 524, 537, 524, 550, 550, 537, 537, 537, + 537, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1918, 1919, 1920, 1921, 76, 1922, 1923, + 1924, 76, 1925, 1926, 1927, 1927, 1927, 1928, + 1929, 1930, 1930, 1931, 1932, 76, 1933, 1934, + 76, 76, 1935, 1936, 1937, 1937, 1937, 76, + 76, 1938, 1939, 1940, 76, 1941, 76, 1942, + 76, 1941, 76, 1943, 1944, 1945, 1920, 82, + 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, + 1954, 1955, 1956, 76, 1957, 1958, 1959, 1960, + 1961, 1962, 74, 74, 74, 74, 1963, 1964, + 1946, 1956, 1965, 76, 74, 76, 76, 1966, + 0, 0, 0, 0, 1967, 1968, 1969, 1970, + 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, + 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, + 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011, 1249, 1249, 1249, 2012, 2013, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2014, 74, 2015, 74, 2016, 76, 76, + 76, 76, 76, 2017, 2018, 76, 76, 76, + 76, 74, 76, 76, 74, 76, 76, 74, + 76, 76, 76, 76, 76, 76, 76, 2019, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 2020, 2021, + 2022, 2023, 76, 2024, 76, 2025, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 2026, 2026, 2027, 2028, 74, 74, + 74, 2029, 2030, 2026, 2031, 2032, 2026, 74, + 74, 74, 2026, 13, 83, 74, 2026, 2026, + 74, 74, 74, 2026, 2026, 2026, 2026, 74, + 2026, 2026, 2026, 2026, 2033, 2034, 2035, 2036, + 74, 74, 74, 74, 2026, 2037, 2038, 2026, + 2039, 2040, 2026, 2026, 2026, 74, 74, 74, + 74, 74, 2026, 74, 2026, 2041, 2026, 2026, + 2026, 2026, 2042, 2026, 2043, 2044, 2045, 2026, + 2046, 2047, 2048, 2026, 2026, 2026, 2049, 74, + 74, 74, 74, 2026, 2026, 2026, 2026, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 2026, 2050, 2051, 2052, 74, 2053, 2054, 2026, + 2026, 2026, 2026, 2026, 2026, 74, 2055, 2056, + 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, + 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2026, + 2026, 2072, 2073, 2074, 2075, 2076, 2077, 2078, + 2079, 2080, 2081, 2026, 2026, 2026, 74, 74, + 2026, 2026, 2082, 2083, 74, 74, 74, 74, + 74, 2026, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 2084, 2026, 74, 74, 2026, + 2026, 2085, 2086, 2026, 2087, 2088, 2089, 2090, + 2091, 2026, 2026, 2092, 2093, 2094, 2095, 2026, + 2026, 2026, 74, 74, 74, 74, 74, 2026, + 2026, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 2026, 2026, 2026, 2026, 2026, 74, + 74, 2026, 2026, 74, 74, 74, 74, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2096, 2097, 2098, 2099, 2026, 2026, 2026, + 2026, 2026, 2026, 2100, 2101, 2102, 2103, 74, + 74, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 76, 76, 76, 76, 76, 76, 76, + 76, 2026, 2026, 2026, 2026, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 2026, 2026, 76, 76, 76, 76, 76, + 76, 76, 2104, 2105, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 76, 74, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 812, 76, + 76, 76, 76, 76, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 74, 74, 74, + 74, 74, 74, 76, 76, 76, 76, 76, + 76, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2106, 2107, 2108, 2109, 2110, 2111, 2112, + 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, + 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, + 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, + 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, + 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, + 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, + 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, + 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, + 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, + 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, + 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, + 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, + 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, + 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, + 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, + 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, + 2241, 2242, 2243, 2244, 1251, 1251, 1251, 1251, + 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, + 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, + 1251, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 74, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 74, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 74, 74, 74, 74, 74, 74, 74, + 74, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 74, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 812, 76, 76, + 76, 76, 76, 76, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 76, 76, 76, 76, 0, 76, + 76, 76, 76, 0, 0, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 0, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 0, 76, 0, + 76, 76, 76, 76, 0, 0, 0, 76, + 0, 76, 76, 76, 76, 76, 76, 76, + 0, 0, 76, 76, 76, 76, 76, 76, + 76, 11, 12, 11, 12, 11, 12, 11, + 12, 11, 12, 11, 12, 11, 12, 1251, + 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, + 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, + 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251, + 1251, 1251, 1251, 1251, 1251, 76, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 0, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 0, 2026, 74, 74, 2026, 2026, 11, 12, + 74, 74, 74, 74, 0, 0, 0, 0, + 0, 74, 74, 74, 2026, 2026, 2026, 2026, + 74, 74, 74, 74, 74, 2026, 2026, 2026, + 74, 74, 74, 2026, 2026, 2026, 2026, 11, + 12, 11, 12, 11, 12, 0, 0, 0, + 0, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 11, 12, 11, 12, + 11, 12, 11, 12, 11, 12, 11, 12, + 11, 12, 11, 12, 11, 12, 11, 12, + 11, 12, 74, 74, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 74, 74, 74, 74, 74, 74, 74, + 74, 2026, 74, 74, 74, 74, 74, 74, + 74, 2026, 2026, 2026, 2026, 2026, 2026, 74, + 74, 74, 2026, 74, 74, 74, 74, 2026, + 2026, 2026, 2026, 2026, 74, 2026, 2026, 74, + 74, 11, 12, 11, 12, 2026, 74, 74, + 74, 74, 2026, 74, 2026, 2026, 2026, 74, + 74, 2026, 2026, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 2026, 2026, 2026, + 2026, 2026, 2026, 74, 74, 11, 12, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 2026, 2026, 2245, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 74, 2026, + 2026, 2026, 2026, 74, 74, 2026, 74, 2026, + 74, 74, 2026, 74, 2026, 2026, 2026, 2026, + 74, 74, 74, 74, 74, 2026, 2026, 74, + 74, 74, 74, 74, 74, 2026, 2026, 2026, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 2026, 2026, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 2026, 2026, 74, + 74, 74, 74, 2026, 2026, 2026, 2026, 74, + 2026, 2026, 74, 74, 2026, 2246, 2247, 2248, + 74, 74, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 74, 74, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 74, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, + 74, 74, 74, 74, 74, 2249, 2250, 2026, + 74, 74, 74, 2026, 2026, 2026, 2026, 2026, + 74, 74, 74, 74, 74, 2026, 2026, 2026, + 74, 74, 74, 74, 2026, 74, 74, 74, + 2026, 2026, 2026, 2026, 2026, 74, 2026, 74, + 74, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2251, 2252, 2253, 2254, 2255, 2256, 2257, + 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, + 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, + 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, + 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, + 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, + 0, 2298, 2299, 2300, 2301, 2302, 2303, 2304, + 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, + 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, + 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, + 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, + 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, + 0, 2345, 2346, 2347, 2348, 2349, 2350, 2351, + 2352, 2353, 2354, 2355, 2356, 2357, 0, 0, + 0, 0, 0, 0, 0, 213, 2358, 2359, + 213, 0, 0, 0, 0, 0, 0, 0, + 0, 2360, 2361, 2362, 2363, 2364, 2365, 2366, + 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, + 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, + 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, + 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, + 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, + 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, + 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, + 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, + 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, + 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, + 2447, 2448, 2449, 2450, 2451, 2452, 2453, 2454, + 2455, 2456, 2457, 2458, 2459, 213, 76, 76, + 76, 76, 76, 76, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 8, 8, 8, 1251, 8, + 8, 2460, 2461, 2462, 2463, 2464, 2465, 2466, + 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, + 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, + 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, + 2491, 2492, 2493, 2494, 2495, 2496, 2497, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2498, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 8, 79, 91, 79, 91, 8, + 8, 8, 79, 91, 8, 79, 91, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 1030, 0, 0, 0, 0, 79, 91, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 0, 76, 76, 76, 76, + 2499, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 2500, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2501, 2502, 2503, 2504, 2505, 2506, 2507, + 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, + 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, + 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531, + 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, + 2540, 2541, 2542, 2543, 2544, 2545, 2546, 2547, + 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555, + 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, + 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, + 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, + 2580, 2581, 2582, 2583, 2584, 2585, 2586, 2587, + 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, + 2596, 2597, 2598, 2599, 2600, 2601, 2602, 2603, + 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, + 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, + 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627, + 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635, + 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, + 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651, + 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, + 2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667, + 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, + 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, + 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, + 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, + 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, + 2708, 2709, 2710, 2711, 2712, 2713, 2714, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 0, 0, 0, + 0, 2715, 8, 8, 8, 76, 507, 339, + 1249, 11, 12, 11, 12, 11, 12, 11, + 12, 11, 12, 76, 76, 11, 12, 11, + 12, 11, 12, 11, 12, 1030, 11, 12, + 12, 76, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 2716, 1032, 536, 1031, 2717, + 2717, 1030, 507, 507, 507, 507, 507, 2718, + 76, 2719, 2720, 2721, 507, 339, 8, 76, + 76, 0, 339, 339, 339, 339, 339, 2722, + 339, 339, 339, 339, 2723, 2724, 2725, 2726, + 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, + 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742, + 2743, 2744, 2745, 2746, 339, 2747, 2748, 2749, + 2750, 2751, 2752, 339, 339, 339, 339, 339, + 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, + 2761, 2762, 2763, 2764, 2765, 2766, 2767, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 2768, 339, 339, + 0, 0, 2769, 2770, 2771, 2772, 2773, 2774, + 2775, 1030, 339, 339, 339, 339, 339, 2776, + 339, 339, 339, 339, 2777, 2778, 2779, 2780, + 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, + 2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796, + 2797, 2798, 2799, 2800, 339, 2801, 2802, 2803, + 2804, 2805, 2806, 339, 339, 339, 339, 339, + 2807, 2808, 2809, 2810, 2811, 2812, 2813, 2814, + 2815, 2816, 2817, 2818, 2819, 2820, 2821, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 2822, 2823, 2824, 2825, 339, 2826, 339, 339, + 2827, 2828, 2829, 2830, 8, 507, 2831, 2832, + 2833, 0, 0, 0, 0, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 0, + 0, 0, 2834, 2835, 2836, 2837, 2838, 2839, + 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, + 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, + 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, + 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, + 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, + 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, + 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, + 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, + 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, + 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, + 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, + 0, 812, 812, 2928, 2929, 2930, 2931, 2932, + 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, + 2941, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 2942, 2943, 2944, 2945, 2946, 2947, 2948, + 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, + 2957, 2958, 2959, 2960, 2961, 2962, 2963, 2964, + 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, + 0, 2973, 2974, 2975, 2976, 2977, 2978, 2979, + 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, + 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995, + 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003, + 3004, 3005, 3006, 3007, 3008, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3009, 3010, 3011, 3012, 3013, 3014, 3015, + 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, + 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, + 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, + 3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047, + 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, + 812, 3056, 3057, 3058, 3059, 3060, 3061, 3062, + 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, + 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078, + 3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086, + 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, + 3095, 3096, 3097, 3098, 3099, 3100, 3101, 3102, + 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, + 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118, + 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, + 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, + 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, + 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150, + 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, + 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, + 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, + 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, + 0, 3183, 3184, 3185, 3186, 3187, 3188, 3189, + 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197, + 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205, + 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213, + 3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221, + 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, + 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, + 3238, 3239, 3240, 3241, 3242, 3243, 3244, 3245, + 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253, + 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, + 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, + 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, + 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, + 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, + 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, + 3302, 3303, 3304, 3305, 3306, 3307, 3308, 3309, + 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, + 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, + 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, + 3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341, + 3342, 3343, 3344, 3345, 3346, 3347, 3348, 3349, + 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, + 3358, 3359, 3360, 3361, 3362, 3363, 3364, 3365, + 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373, + 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, + 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, + 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, + 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3405, + 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, + 3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, + 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, + 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, + 3438, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 507, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 506, 506, 506, 506, 0, 0, 0, 0, + 0, 46, 46, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 1252, 339, 339, 339, 1101, + 339, 339, 339, 339, 1090, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 1093, 1093, 1090, 1090, + 1093, 76, 76, 76, 76, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 8, 8, 8, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439, + 3439, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, + 3448, 3448, 3449, 3450, 3451, 3452, 3453, 3454, + 3455, 3456, 3457, 3458, 3459, 3460, 3461, 3462, + 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3470, + 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3478, + 3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486, + 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494, + 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, + 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, + 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518, + 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, + 3527, 3528, 3529, 3530, 3531, 3460, 3532, 3533, + 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, + 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549, + 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557, + 3558, 3559, 3560, 3561, 3562, 3563, 3564, 3565, + 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, + 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581, + 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, + 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, + 3598, 3599, 3550, 3600, 3601, 3602, 3603, 3604, + 3605, 3606, 3607, 3534, 3608, 3609, 3610, 3611, + 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, + 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, + 3460, 3628, 3629, 3630, 3631, 3632, 3633, 3634, + 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, + 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, + 3651, 3652, 3653, 3654, 3536, 3655, 3656, 3657, + 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, + 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, + 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3681, + 3682, 3683, 3684, 3685, 3686, 3687, 3688, 3689, + 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697, + 3698, 3699, 3700, 3701, 3702, 3703, 3704, 339, + 339, 3705, 339, 3706, 339, 339, 3707, 3708, + 3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716, + 339, 3717, 339, 3718, 339, 339, 3719, 3720, + 339, 339, 339, 3721, 3722, 3723, 3724, 0, + 0, 3725, 3726, 3727, 3728, 3729, 3730, 3731, + 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, + 3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747, + 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, + 3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763, + 3589, 3764, 3765, 3766, 3767, 3768, 3769, 3769, + 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, + 3719, 3778, 3779, 3780, 0, 0, 0, 0, + 0, 3781, 3782, 3783, 3784, 3785, 3786, 3787, + 3788, 3731, 3789, 3790, 3791, 3705, 3792, 3793, + 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, + 3802, 3803, 3740, 3804, 3741, 3805, 3806, 3807, + 3808, 3809, 3706, 3481, 3810, 3811, 3812, 3551, + 3638, 3813, 3814, 3748, 3815, 3749, 3816, 3817, + 3818, 3708, 3819, 3820, 3821, 3822, 3823, 3709, + 3824, 3825, 3826, 3827, 3828, 3829, 3763, 3830, + 3831, 3589, 3832, 3767, 3833, 3834, 3835, 3836, + 3837, 3772, 3838, 3718, 3839, 3773, 3532, 3840, + 3774, 3841, 3776, 3842, 3843, 3844, 3845, 3846, + 3778, 3714, 3847, 3779, 3848, 3780, 3849, 3448, + 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, + 3858, 3859, 3860, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3861, 3862, 3863, 3864, 3865, 3866, 3867, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3868, 3869, 3870, 3871, + 3872, 0, 0, 0, 0, 0, 3873, 3874, + 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, + 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, + 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3898, + 0, 3899, 3900, 3901, 3902, 3903, 0, 3904, + 0, 3905, 3906, 0, 3907, 3908, 0, 3909, + 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917, + 3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925, + 3926, 3927, 3928, 3929, 3930, 3931, 3932, 3933, + 3934, 3935, 3936, 3937, 3938, 3939, 3940, 3941, + 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, + 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957, + 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965, + 3966, 3967, 3968, 3969, 3970, 3971, 3972, 3973, + 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981, + 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, + 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997, + 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, + 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013, + 4014, 4015, 4016, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4017, 4018, 4019, 4020, + 4021, 4022, 4023, 4024, 4025, 4026, 4027, 4028, + 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, + 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, + 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, + 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, + 4061, 4062, 4063, 4064, 4055, 4065, 4066, 4067, + 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, + 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, + 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, + 4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099, + 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, + 4108, 4109, 4110, 4111, 4112, 4113, 4114, 4115, + 4116, 4117, 4118, 4119, 4120, 4121, 4122, 4123, + 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, + 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, + 4140, 4141, 4142, 4143, 4144, 4145, 4146, 4147, + 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, + 4156, 4157, 4158, 4159, 4160, 4161, 4162, 4163, + 4164, 4056, 4165, 4166, 4167, 4168, 4169, 4170, + 4171, 4172, 4173, 4174, 4175, 4176, 4177, 4178, + 4179, 4180, 4181, 4182, 4183, 4184, 4185, 4186, + 4187, 4188, 4189, 4190, 4191, 4192, 4193, 4194, + 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, + 4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210, + 4211, 4212, 4213, 4214, 4215, 4216, 4217, 4218, + 4219, 4220, 4221, 4222, 4223, 4224, 4225, 4226, + 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234, + 4235, 4236, 4237, 4238, 4239, 4240, 4241, 4242, + 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, + 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, + 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, + 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, + 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, + 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4290, + 4291, 4292, 4293, 4294, 4295, 4296, 4297, 4298, + 4299, 4300, 4301, 4302, 4303, 4304, 4305, 4306, + 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314, + 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, + 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, + 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, + 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346, + 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354, + 4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362, + 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, + 4371, 4372, 4373, 4374, 4375, 4376, 4377, 4378, + 4379, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4380, 4381, 4382, 4383, 4384, 4385, 4386, + 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, + 4395, 4396, 4397, 4398, 4399, 4400, 4401, 4402, + 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, + 4411, 4412, 4413, 4414, 4415, 4416, 4417, 4418, + 4419, 4420, 4421, 4422, 4423, 4424, 4425, 4426, + 4427, 4428, 4429, 4430, 4431, 4432, 4433, 4434, + 4435, 4436, 4437, 4438, 4439, 4440, 4441, 4442, + 4443, 0, 0, 4444, 4445, 4446, 4447, 4448, + 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, + 4457, 4458, 4459, 4460, 4461, 4462, 4463, 4464, + 4465, 4466, 4467, 4468, 4469, 4470, 4471, 4472, + 4473, 4474, 4475, 4476, 4477, 4478, 4479, 4480, + 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, + 4489, 4490, 4491, 4492, 4493, 4494, 4495, 4496, + 4497, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4498, 4499, 4500, 4501, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4509, 4510, 76, 0, + 0, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 4511, 4512, 4513, 4514, 4515, 4516, 4517, + 4518, 4519, 4520, 0, 0, 0, 0, 0, + 0, 524, 524, 524, 524, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4521, 4522, 4523, 4524, 4524, 4525, 4526, + 4527, 4528, 4529, 4530, 4531, 4532, 4533, 4534, + 4535, 4536, 4537, 4538, 4539, 4540, 8, 8, + 4541, 4542, 4543, 4543, 4543, 4543, 4544, 4544, + 4544, 4545, 4546, 4547, 0, 4548, 4549, 4550, + 4551, 4552, 4553, 4554, 4555, 4556, 4557, 4558, + 4559, 4560, 4561, 4562, 4563, 4564, 4565, 4566, + 0, 4567, 4568, 4569, 4570, 0, 0, 0, + 0, 4571, 4572, 4573, 1054, 4574, 0, 4575, + 4576, 4577, 4578, 4579, 4580, 4581, 4582, 4583, + 4584, 4585, 4586, 4587, 4588, 4589, 4590, 4591, + 4592, 4593, 4594, 4595, 4596, 4597, 4598, 4599, + 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, + 4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615, + 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, + 4624, 4625, 4626, 4627, 4628, 4629, 4630, 4631, + 4632, 4633, 4634, 4635, 4636, 4637, 4638, 4639, + 4640, 4641, 4642, 4643, 4644, 4645, 4646, 4647, + 4648, 4649, 4650, 4651, 4652, 4653, 4654, 4655, + 4656, 4657, 4658, 4659, 4660, 4661, 4662, 4663, + 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, + 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, + 4680, 4681, 4682, 4683, 4684, 4685, 4686, 4687, + 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, + 4696, 4697, 4698, 4699, 4700, 4701, 4702, 4703, + 4704, 4705, 4706, 4707, 4708, 4709, 0, 0, + 80, 0, 4710, 4711, 4712, 4713, 4714, 4715, + 4716, 4717, 4718, 4719, 4720, 4721, 4722, 4723, + 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4731, + 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, + 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, + 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, + 4756, 4757, 4758, 4759, 4760, 4761, 4762, 4763, + 4764, 4765, 4766, 4767, 4768, 4769, 4770, 4771, + 4772, 4773, 4774, 4775, 4776, 4777, 4778, 4779, + 4780, 4781, 4782, 4783, 4784, 4785, 4786, 4787, + 4788, 4789, 4790, 4791, 4792, 4793, 4794, 4795, + 4796, 4797, 4798, 4799, 4800, 4801, 4802, 4803, + 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, + 4812, 4813, 4814, 4815, 4816, 4817, 4818, 4819, + 4820, 4821, 4822, 4823, 4824, 4825, 4826, 4827, + 4828, 4829, 4830, 4831, 4832, 4833, 4834, 4835, + 4836, 4837, 4838, 4839, 4840, 4841, 4842, 4843, + 4844, 4845, 4846, 4847, 4848, 4849, 4850, 4851, + 4852, 4853, 4854, 4855, 4856, 4857, 4858, 4859, + 4860, 4861, 4862, 4863, 4864, 4865, 4866, 4867, + 4868, 4869, 4870, 4871, 4872, 4873, 4874, 4875, + 4876, 4877, 4878, 4879, 4880, 4881, 4882, 4883, + 4884, 4885, 4886, 4887, 4888, 4889, 4890, 4891, + 4892, 4893, 4894, 4895, 4896, 4897, 4898, 4899, + 0, 0, 0, 4900, 4901, 4902, 4903, 4904, + 4905, 0, 0, 4906, 4907, 4908, 4909, 4910, + 4911, 0, 0, 4912, 4913, 4914, 4915, 4916, + 4917, 0, 0, 4918, 4919, 4920, 0, 0, + 0, 4921, 4922, 4923, 4924, 4925, 4926, 4927, + 0, 4928, 4929, 4930, 4931, 4932, 4933, 4934, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4935, 4935, 4935, 76, 76, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 0, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 0, 339, 339, 0, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 0, 0, 0, 0, + 0, 990, 8, 812, 0, 0, 0, 0, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 0, 0, 0, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 4936, 4936, 4936, 4936, 4936, 4936, 4936, + 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936, + 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936, + 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936, + 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936, + 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936, + 4936, 4936, 4936, 4936, 4936, 4936, 1251, 1251, + 1251, 1251, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 1251, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 0, 1120, 1120, 1120, 1120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 1249, 339, 339, 339, 339, 339, + 339, 339, 339, 1249, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 0, + 990, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 990, 1249, 1249, 1249, 1249, 1249, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4937, 4938, 4939, 4940, 4941, 4942, 4943, + 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, + 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959, + 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, + 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975, + 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, + 4984, 4985, 4986, 4987, 4988, 4989, 4990, 4991, + 4992, 4993, 4994, 4995, 4996, 4997, 4998, 4999, + 5000, 5001, 5002, 5003, 5004, 5005, 5006, 5007, + 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, + 5016, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 0, + 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1050, 1050, 1050, 1050, 1050, 1050, 0, + 0, 1050, 0, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 0, + 1050, 1050, 0, 0, 0, 1050, 0, 0, + 1050, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 5017, + 5017, 5017, 5017, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1050, 1090, 1090, 1090, 0, 1090, 1090, + 0, 0, 0, 0, 0, 1090, 537, 1090, + 524, 1050, 1050, 1050, 1050, 0, 1050, 1050, + 1050, 0, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 0, 0, 0, + 0, 524, 550, 537, 0, 0, 0, 0, + 1101, 5017, 5017, 5017, 5017, 5017, 5017, 5017, + 5017, 0, 0, 0, 0, 0, 0, 0, + 0, 1046, 1046, 1046, 1046, 1046, 1046, 1046, + 1046, 1046, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 990, 990, 990, 990, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 0, 0, 0, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 5018, 5019, 812, 812, 812, 812, 812, 5020, + 5021, 5022, 5023, 5024, 5025, 5026, 5027, 5028, + 550, 550, 550, 812, 812, 812, 5029, 5030, + 5031, 5032, 5033, 5034, 80, 80, 80, 80, + 80, 80, 80, 80, 537, 537, 537, 537, + 537, 537, 537, 537, 812, 812, 524, 524, + 524, 524, 524, 537, 537, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 524, 524, 524, 524, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 5035, 5036, 5037, 5038, 5039, 5040, + 5041, 5042, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 524, 524, 524, 76, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5043, 1945, 1920, 1963, 1947, 1948, 5044, + 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047, + 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052, + 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946, + 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060, + 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5043, 1945, 1920, + 1963, 1947, 1948, 5044, 1927, 1930, 5045, 5046, + 1931, 1950, 1933, 5047, 1935, 1936, 1937, 5048, + 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055, + 5056, 5057, 1964, 1946, 5058, 1926, 0, 1956, + 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044, + 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047, + 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052, + 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946, + 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060, + 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5043, 0, 1920, + 1963, 0, 0, 5044, 0, 0, 5045, 5046, + 0, 0, 1933, 5047, 1935, 1936, 0, 5048, + 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055, + 5056, 5057, 1964, 0, 5058, 0, 1928, 1956, + 1965, 5059, 1932, 5060, 5061, 0, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044, + 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047, + 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052, + 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946, + 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060, + 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5043, 1945, 0, + 1963, 1947, 1948, 5044, 0, 0, 5045, 5046, + 1931, 1950, 1933, 5047, 1935, 1936, 0, 5048, + 5049, 5050, 5051, 5052, 5053, 5054, 0, 5055, + 5056, 5057, 1964, 1946, 5058, 1926, 1928, 1956, + 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5043, 1945, 0, 1963, 1947, 1948, 5044, + 0, 1930, 5045, 5046, 1931, 1950, 0, 5047, + 0, 0, 0, 5048, 5049, 5050, 5051, 5052, + 5053, 5054, 0, 5055, 5056, 5057, 1964, 1946, + 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060, + 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5043, 1945, 1920, + 1963, 1947, 1948, 5044, 1927, 1930, 5045, 5046, + 1931, 1950, 1933, 5047, 1935, 1936, 1937, 5048, + 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055, + 5056, 5057, 1964, 1946, 5058, 1926, 1928, 1956, + 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044, + 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047, + 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052, + 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946, + 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060, + 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5043, 1945, 1920, + 1963, 1947, 1948, 5044, 1927, 1930, 5045, 5046, + 1931, 1950, 1933, 5047, 1935, 1936, 1937, 5048, + 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055, + 5056, 5057, 1964, 1946, 5058, 1926, 1928, 1956, + 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044, + 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047, + 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052, + 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946, + 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060, + 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5043, 1945, 1920, + 1963, 1947, 1948, 5044, 1927, 1930, 5045, 5046, + 1931, 1950, 1933, 5047, 1935, 1936, 1937, 5048, + 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055, + 5056, 5057, 1964, 1946, 5058, 1926, 1928, 1956, + 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063, + 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071, + 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044, + 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047, + 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052, + 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946, + 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060, + 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067, + 5068, 5069, 5070, 5071, 5072, 5073, 5074, 0, + 0, 5075, 5076, 1960, 5077, 5078, 5079, 5080, + 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, + 1961, 5089, 5090, 5091, 5092, 5093, 5094, 5095, + 5096, 5097, 5098, 5099, 5100, 1959, 5101, 5102, + 5103, 5104, 5105, 5106, 5107, 5108, 5109, 5110, + 5111, 5112, 1958, 5113, 5114, 5115, 5116, 5117, + 5118, 5119, 5120, 5121, 5122, 5123, 5124, 5125, + 5126, 5127, 5128, 5075, 5076, 1960, 5077, 5078, + 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086, + 5087, 5088, 1961, 5089, 5090, 5091, 5092, 5093, + 5094, 5095, 5096, 5097, 5098, 5099, 5100, 1959, + 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108, + 5109, 5110, 5111, 5112, 1958, 5113, 5114, 5115, + 5116, 5117, 5118, 5119, 5120, 5121, 5122, 5123, + 5124, 5125, 5126, 5127, 5128, 5075, 5076, 1960, + 5077, 5078, 5079, 5080, 5081, 5082, 5083, 5084, + 5085, 5086, 5087, 5088, 1961, 5089, 5090, 5091, + 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099, + 5100, 1959, 5101, 5102, 5103, 5104, 5105, 5106, + 5107, 5108, 5109, 5110, 5111, 5112, 1958, 5113, + 5114, 5115, 5116, 5117, 5118, 5119, 5120, 5121, + 5122, 5123, 5124, 5125, 5126, 5127, 5128, 5075, + 5076, 1960, 5077, 5078, 5079, 5080, 5081, 5082, + 5083, 5084, 5085, 5086, 5087, 5088, 1961, 5089, + 5090, 5091, 5092, 5093, 5094, 5095, 5096, 5097, + 5098, 5099, 5100, 1959, 5101, 5102, 5103, 5104, + 5105, 5106, 5107, 5108, 5109, 5110, 5111, 5112, + 1958, 5113, 5114, 5115, 5116, 5117, 5118, 5119, + 5120, 5121, 5122, 5123, 5124, 5125, 5126, 5127, + 5128, 5075, 5076, 1960, 5077, 5078, 5079, 5080, + 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088, + 1961, 5089, 5090, 5091, 5092, 5093, 5094, 5095, + 5096, 5097, 5098, 5099, 5100, 1959, 5101, 5102, + 5103, 5104, 5105, 5106, 5107, 5108, 5109, 5110, + 5111, 5112, 1958, 5113, 5114, 5115, 5116, 5117, + 5118, 5119, 5120, 5121, 5122, 5123, 5124, 5125, + 5126, 5127, 5128, 5129, 5130, 0, 0, 5131, + 5132, 5133, 5134, 5135, 5136, 5137, 5138, 5139, + 5140, 5131, 5132, 5133, 5134, 5135, 5136, 5137, + 5138, 5139, 5140, 5131, 5132, 5133, 5134, 5135, + 5136, 5137, 5138, 5139, 5140, 5131, 5132, 5133, + 5134, 5135, 5136, 5137, 5138, 5139, 5140, 5131, + 5132, 5133, 5134, 5135, 5136, 5137, 5138, 5139, + 5140, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, 339, 339, 339, 339, 339, 339, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5141, 5142, 5143, 5144, 5145, 3725, 5146, + 5147, 5148, 5149, 3726, 5150, 5151, 5152, 3727, + 5153, 5154, 5155, 5156, 5157, 5158, 5159, 5160, + 5161, 5162, 5163, 5164, 3782, 5165, 5166, 5167, + 5168, 5169, 5170, 5171, 5172, 5173, 3787, 3728, + 3729, 3788, 5174, 5175, 3538, 5176, 3730, 5177, + 5178, 5179, 5180, 5180, 5180, 5181, 5182, 5183, + 5184, 5185, 5186, 5187, 5188, 5189, 5190, 5191, + 5192, 5193, 5194, 5195, 5196, 5197, 5198, 5198, + 3790, 5199, 5200, 5201, 5202, 3732, 5203, 5204, + 5205, 3691, 5206, 5207, 5208, 5209, 5210, 5211, + 5212, 5213, 5214, 5215, 5216, 5217, 5218, 5219, + 5220, 5221, 5222, 5223, 5224, 5225, 5226, 5227, + 5228, 5229, 5230, 5231, 5231, 5232, 5233, 5234, + 3534, 5235, 5236, 5237, 5238, 5239, 5240, 5241, + 5242, 3737, 5243, 5244, 5245, 5246, 5247, 5248, + 5249, 5250, 5251, 5252, 5253, 5254, 5255, 5256, + 5257, 5258, 5259, 5260, 5261, 5262, 5263, 3480, + 5264, 5265, 5266, 5266, 5267, 5268, 5268, 5269, + 5270, 5271, 5272, 5273, 5274, 5275, 5276, 5277, + 5278, 5279, 5280, 5281, 3738, 5282, 5283, 5284, + 5285, 3802, 5285, 5286, 3740, 5287, 5288, 5289, + 5290, 3741, 3453, 5291, 5292, 5293, 5294, 5295, + 5296, 5297, 5298, 5299, 5300, 5301, 5302, 5303, + 5304, 5305, 5306, 5307, 5308, 5309, 5310, 5311, + 5312, 3742, 5313, 5314, 5315, 5316, 5317, 5318, + 3744, 5319, 5320, 5321, 5322, 5323, 5324, 5325, + 5326, 3481, 3810, 5327, 5328, 5329, 5330, 5331, + 5332, 5333, 5334, 3745, 5335, 5336, 5337, 5338, + 3853, 5339, 5340, 5341, 5342, 5343, 5344, 5345, + 5346, 5347, 5348, 5349, 5350, 5351, 3551, 5352, + 5353, 5354, 5355, 5356, 5357, 5358, 5359, 5360, + 5361, 5362, 3746, 3638, 5363, 5364, 5365, 5366, + 5367, 5368, 5369, 5370, 3814, 5371, 5372, 5373, + 5374, 5375, 5376, 5377, 5378, 3815, 5379, 5380, + 5381, 5382, 5383, 5384, 5385, 5386, 5387, 5388, + 5389, 5390, 3817, 5391, 5392, 5393, 5394, 5395, + 5396, 5397, 5398, 5399, 5400, 5401, 5401, 5402, + 5403, 3819, 5404, 5405, 5406, 5407, 5408, 5409, + 5410, 3537, 5411, 5412, 5413, 5414, 5415, 5416, + 5417, 3825, 5418, 5419, 5420, 5421, 5422, 5423, + 5423, 3826, 3855, 5424, 5425, 5426, 5427, 5428, + 3499, 3828, 5429, 5430, 3757, 5431, 5432, 3713, + 5433, 5434, 3761, 5435, 5436, 5437, 5438, 5438, + 5439, 5440, 5441, 5442, 5443, 5444, 5445, 5446, + 5447, 5448, 5449, 5450, 5451, 5452, 5453, 5454, + 5455, 5456, 5457, 5458, 5459, 5460, 5461, 5462, + 5463, 5464, 5465, 3767, 5466, 5467, 5468, 5469, + 5470, 5471, 5472, 5473, 5474, 5475, 5476, 5477, + 5478, 5479, 5480, 5481, 5267, 5482, 5483, 5484, + 5485, 5486, 5487, 5488, 5489, 5490, 5491, 5492, + 5493, 3555, 5494, 5495, 5496, 5497, 5498, 5499, + 3770, 5500, 5501, 5502, 5503, 5504, 5505, 5506, + 5507, 5508, 5509, 5510, 5511, 5512, 5513, 5514, + 5515, 5516, 5517, 5518, 5519, 3494, 5520, 5521, + 5522, 5523, 5524, 5525, 3835, 5526, 5527, 5528, + 5529, 5530, 5531, 5532, 5533, 5534, 5535, 5536, + 5537, 5538, 5539, 5540, 5541, 5542, 5543, 5544, + 5545, 3840, 3841, 5546, 5547, 5548, 5549, 5550, + 5551, 5552, 5553, 5554, 5555, 5556, 5557, 5558, + 3842, 5559, 5560, 5561, 5562, 5563, 5564, 5565, + 5566, 5567, 5568, 5569, 5570, 5571, 5572, 5573, + 5574, 5575, 5576, 5577, 5578, 5579, 5580, 5581, + 5582, 5583, 5584, 5585, 5586, 5587, 5588, 3848, + 3848, 5589, 5590, 5591, 5592, 5593, 5594, 5595, + 5596, 5597, 5598, 3849, 5599, 5600, 5601, 5602, + 5603, 5604, 5605, 5606, 5607, 5608, 5609, 5610, + 5611, 5612, 5613, 5614, 5615, 5616, 5617, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 80, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, + 558, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440, + 3440, 3440, 3440, 3440, 3440, 3440, 3440, 0, + 0, }; + +const utf8proc_property_t utf8proc_properties[] = { + {0, 0, 0, 0, NULL, false, -1, -1, -1, -1, -1, false}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_BN, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_S, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_WS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_S, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17580, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17400, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17640, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 97, -1, 0, -1, false, false, false, false, utf8proc_sequences + 0}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 98, -1, 8640, -1, false, false, false, false, utf8proc_sequences + 2}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 99, -1, 60, -1, false, false, false, false, utf8proc_sequences + 4}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 100, -1, 960, -1, false, false, false, false, utf8proc_sequences + 6}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 101, -1, 120, -1, false, false, false, false, utf8proc_sequences + 8}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 102, -1, 9120, -1, false, false, false, false, utf8proc_sequences + 10}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 103, -1, 1080, -1, false, false, false, false, utf8proc_sequences + 12}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 104, -1, 1200, -1, false, false, false, false, utf8proc_sequences + 14}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 105, -1, 180, -1, false, false, false, false, utf8proc_sequences + 16}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 106, -1, 1320, -1, false, false, false, false, utf8proc_sequences + 18}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 107, -1, 1440, -1, false, false, false, false, utf8proc_sequences + 20}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 108, -1, 1560, -1, false, false, false, false, utf8proc_sequences + 22}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 109, -1, 9480, -1, false, false, false, false, utf8proc_sequences + 24}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 110, -1, 240, -1, false, false, false, false, utf8proc_sequences + 26}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 111, -1, 300, -1, false, false, false, false, utf8proc_sequences + 28}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 112, -1, 9720, -1, false, false, false, false, utf8proc_sequences + 30}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 113, -1, -1, -1, false, false, false, false, utf8proc_sequences + 32}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 114, -1, 1680, -1, false, false, false, false, utf8proc_sequences + 34}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 115, -1, 1800, -1, false, false, false, false, utf8proc_sequences + 36}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 116, -1, 1920, -1, false, false, false, false, utf8proc_sequences + 38}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 117, -1, 360, -1, false, false, false, false, utf8proc_sequences + 40}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 118, -1, 10560, -1, false, false, false, false, utf8proc_sequences + 42}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 119, -1, 2040, -1, false, false, false, false, utf8proc_sequences + 44}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 120, -1, 10680, -1, false, false, false, false, utf8proc_sequences + 46}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 121, -1, 420, -1, false, false, false, false, utf8proc_sequences + 48}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 122, -1, 2160, -1, false, false, false, false, utf8proc_sequences + 50}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 65, -1, 65, 480, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66, -1, 66, 8700, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 67, -1, 67, 540, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 68, -1, 68, 1020, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 69, -1, 69, 600, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 70, -1, 70, 9180, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 71, -1, 71, 1140, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 72, -1, 72, 1260, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 73, -1, 73, 660, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 74, -1, 74, 1380, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 75, -1, 75, 1500, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 76, -1, 76, 1620, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 77, -1, 77, 9540, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 78, -1, 78, 720, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 79, -1, 79, 780, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 80, -1, 80, 9780, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 81, -1, 81, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 82, -1, 82, 1740, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 83, -1, 83, 1860, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 84, -1, 84, 1980, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 85, -1, 85, 840, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 86, -1, 86, 10620, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 87, -1, 87, 2100, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 88, -1, 88, 10740, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 89, -1, 89, 900, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 90, -1, 90, 2220, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_NOBREAK, utf8proc_sequences + 52, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 54, false, -1, -1, -1, 3600, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 0, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PI, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 57, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ET, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ET, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 64, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 67, false, 924, -1, 924, -1, -1, false, false, false, false, utf8proc_sequences + 67}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 69, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 28, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PF, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 74, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 78, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 82, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 86, false, -1, 224, -1, -1, -1, false, false, false, false, utf8proc_sequences + 89}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 91, false, -1, 225, -1, -1, -1, false, false, false, false, utf8proc_sequences + 94}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 96, false, -1, 226, -1, 10860, -1, false, false, false, false, utf8proc_sequences + 99}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 101, false, -1, 227, -1, -1, -1, false, false, false, false, utf8proc_sequences + 104}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 106, false, -1, 228, -1, 2400, -1, false, false, false, false, utf8proc_sequences + 109}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 111, false, -1, 229, -1, 3000, -1, false, false, false, false, utf8proc_sequences + 114}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 230, -1, 2640, -1, false, false, false, false, utf8proc_sequences + 116}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 118, false, -1, 231, -1, 8760, -1, false, false, false, false, utf8proc_sequences + 121}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 123, false, -1, 232, -1, -1, -1, false, false, false, false, utf8proc_sequences + 126}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 128, false, -1, 233, -1, -1, -1, false, false, false, false, utf8proc_sequences + 131}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 133, false, -1, 234, -1, 11220, -1, false, false, false, false, utf8proc_sequences + 136}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 138, false, -1, 235, -1, -1, -1, false, false, false, false, utf8proc_sequences + 141}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 143, false, -1, 236, -1, -1, -1, false, false, false, false, utf8proc_sequences + 146}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 148, false, -1, 237, -1, -1, -1, false, false, false, false, utf8proc_sequences + 151}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 153, false, -1, 238, -1, -1, -1, false, false, false, false, utf8proc_sequences + 156}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 158, false, -1, 239, -1, 9240, -1, false, false, false, false, utf8proc_sequences + 161}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 240, -1, -1, -1, false, false, false, false, utf8proc_sequences + 163}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 165, false, -1, 241, -1, -1, -1, false, false, false, false, utf8proc_sequences + 168}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 170, false, -1, 242, -1, -1, -1, false, false, false, false, utf8proc_sequences + 173}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 175, false, -1, 243, -1, -1, -1, false, false, false, false, utf8proc_sequences + 178}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 180, false, -1, 244, -1, 11460, -1, false, false, false, false, utf8proc_sequences + 183}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 185, false, -1, 245, -1, 3360, -1, false, false, false, false, utf8proc_sequences + 188}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 190, false, -1, 246, -1, 3240, -1, false, false, false, false, utf8proc_sequences + 193}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 248, -1, 3120, -1, false, false, false, false, utf8proc_sequences + 195}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 197, false, -1, 249, -1, -1, -1, false, false, false, false, utf8proc_sequences + 200}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 202, false, -1, 250, -1, -1, -1, false, false, false, false, utf8proc_sequences + 205}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 207, false, -1, 251, -1, -1, -1, false, false, false, false, utf8proc_sequences + 210}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 212, false, -1, 252, -1, 2280, -1, false, false, false, false, utf8proc_sequences + 215}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 217, false, -1, 253, -1, -1, -1, false, false, false, false, utf8proc_sequences + 220}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 254, -1, -1, -1, false, false, false, false, utf8proc_sequences + 222}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 224}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 227, false, 192, -1, 192, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 230, false, 193, -1, 193, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 233, false, 194, -1, 194, 10920, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 236, false, 195, -1, 195, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 239, false, 196, -1, 196, 2460, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 242, false, 197, -1, 197, 3060, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 198, -1, 198, 2700, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 245, false, 199, -1, 199, 8820, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 248, false, 200, -1, 200, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 251, false, 201, -1, 201, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 254, false, 202, -1, 202, 11280, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 257, false, 203, -1, 203, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 260, false, 204, -1, 204, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 263, false, 205, -1, 205, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 266, false, 206, -1, 206, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 269, false, 207, -1, 207, 9300, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 208, -1, 208, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 272, false, 209, -1, 209, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 275, false, 210, -1, 210, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 278, false, 211, -1, 211, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 281, false, 212, -1, 212, 11520, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 284, false, 213, -1, 213, 3420, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 287, false, 214, -1, 214, 3300, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 216, -1, 216, 3180, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 290, false, 217, -1, 217, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 293, false, 218, -1, 218, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 296, false, 219, -1, 219, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 299, false, 220, -1, 220, 2340, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 302, false, 221, -1, 221, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 222, -1, 222, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 305, false, 376, -1, 376, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 308, false, -1, 257, -1, -1, -1, false, false, false, false, utf8proc_sequences + 311}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 313, false, 256, -1, 256, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 316, false, -1, 259, -1, 11100, -1, false, false, false, false, utf8proc_sequences + 319}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 321, false, 258, -1, 258, 11160, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 324, false, -1, 261, -1, -1, -1, false, false, false, false, utf8proc_sequences + 327}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 329, false, 260, -1, 260, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 332, false, -1, 263, -1, -1, -1, false, false, false, false, utf8proc_sequences + 335}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 337, false, 262, -1, 262, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 340, false, -1, 265, -1, -1, -1, false, false, false, false, utf8proc_sequences + 343}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 345, false, 264, -1, 264, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 348, false, -1, 267, -1, -1, -1, false, false, false, false, utf8proc_sequences + 351}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 353, false, 266, -1, 266, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 356, false, -1, 269, -1, -1, -1, false, false, false, false, utf8proc_sequences + 359}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 361, false, 268, -1, 268, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 364, false, -1, 271, -1, -1, -1, false, false, false, false, utf8proc_sequences + 367}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 369, false, 270, -1, 270, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 273, -1, -1, -1, false, false, false, false, utf8proc_sequences + 372}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 272, -1, 272, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 374, false, -1, 275, -1, 8880, -1, false, false, false, false, utf8proc_sequences + 377}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 379, false, 274, -1, 274, 8940, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 382, false, -1, 277, -1, -1, -1, false, false, false, false, utf8proc_sequences + 385}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 387, false, 276, -1, 276, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 390, false, -1, 279, -1, -1, -1, false, false, false, false, utf8proc_sequences + 393}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 395, false, 278, -1, 278, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 398, false, -1, 281, -1, -1, -1, false, false, false, false, utf8proc_sequences + 401}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 403, false, 280, -1, 280, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 406, false, -1, 283, -1, -1, -1, false, false, false, false, utf8proc_sequences + 409}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 411, false, 282, -1, 282, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 414, false, -1, 285, -1, -1, -1, false, false, false, false, utf8proc_sequences + 417}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 419, false, 284, -1, 284, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 422, false, -1, 287, -1, -1, -1, false, false, false, false, utf8proc_sequences + 425}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 427, false, 286, -1, 286, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 430, false, -1, 289, -1, -1, -1, false, false, false, false, utf8proc_sequences + 433}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 435, false, 288, -1, 288, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 438, false, -1, 291, -1, -1, -1, false, false, false, false, utf8proc_sequences + 441}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 443, false, 290, -1, 290, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 446, false, -1, 293, -1, -1, -1, false, false, false, false, utf8proc_sequences + 449}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 451, false, 292, -1, 292, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 295, -1, -1, -1, false, false, false, false, utf8proc_sequences + 454}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 294, -1, 294, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 456, false, -1, 297, -1, -1, -1, false, false, false, false, utf8proc_sequences + 459}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 461, false, 296, -1, 296, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 464, false, -1, 299, -1, -1, -1, false, false, false, false, utf8proc_sequences + 467}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 469, false, 298, -1, 298, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 472, false, -1, 301, -1, -1, -1, false, false, false, false, utf8proc_sequences + 475}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 477, false, 300, -1, 300, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 480, false, -1, 303, -1, -1, -1, false, false, false, false, utf8proc_sequences + 483}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 485, false, 302, -1, 302, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 488, false, -1, 105, -1, -1, -1, false, false, false, false, utf8proc_sequences + 491}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 73, -1, 73, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 494, false, -1, 307, -1, -1, -1, false, false, false, false, utf8proc_sequences + 497}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 499, false, 306, -1, 306, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 502, false, -1, 309, -1, -1, -1, false, false, false, false, utf8proc_sequences + 505}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 507, false, 308, -1, 308, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 510, false, -1, 311, -1, -1, -1, false, false, false, false, utf8proc_sequences + 513}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 515, false, 310, -1, 310, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 518, false, -1, 314, -1, -1, -1, false, false, false, false, utf8proc_sequences + 521}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 523, false, 313, -1, 313, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 526, false, -1, 316, -1, -1, -1, false, false, false, false, utf8proc_sequences + 529}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 531, false, 315, -1, 315, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 534, false, -1, 318, -1, -1, -1, false, false, false, false, utf8proc_sequences + 537}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 539, false, 317, -1, 317, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 542, false, -1, 320, -1, -1, -1, false, false, false, false, utf8proc_sequences + 545}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 547, false, 319, -1, 319, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 322, -1, -1, -1, false, false, false, false, utf8proc_sequences + 550}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 321, -1, 321, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 552, false, -1, 324, -1, -1, -1, false, false, false, false, utf8proc_sequences + 555}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 557, false, 323, -1, 323, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 560, false, -1, 326, -1, -1, -1, false, false, false, false, utf8proc_sequences + 563}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 565, false, 325, -1, 325, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 568, false, -1, 328, -1, -1, -1, false, false, false, false, utf8proc_sequences + 571}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 573, false, 327, -1, 327, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 576, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 576}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 331, -1, -1, -1, false, false, false, false, utf8proc_sequences + 579}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 330, -1, 330, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 581, false, -1, 333, -1, 9600, -1, false, false, false, false, utf8proc_sequences + 584}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 586, false, 332, -1, 332, 9660, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 589, false, -1, 335, -1, -1, -1, false, false, false, false, utf8proc_sequences + 592}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 594, false, 334, -1, 334, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 597, false, -1, 337, -1, -1, -1, false, false, false, false, utf8proc_sequences + 600}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 602, false, 336, -1, 336, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 339, -1, -1, -1, false, false, false, false, utf8proc_sequences + 605}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 338, -1, 338, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 607, false, -1, 341, -1, -1, -1, false, false, false, false, utf8proc_sequences + 610}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 612, false, 340, -1, 340, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 615, false, -1, 343, -1, -1, -1, false, false, false, false, utf8proc_sequences + 618}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 620, false, 342, -1, 342, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 623, false, -1, 345, -1, -1, -1, false, false, false, false, utf8proc_sequences + 626}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 628, false, 344, -1, 344, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 631, false, -1, 347, -1, 9960, -1, false, false, false, false, utf8proc_sequences + 634}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 636, false, 346, -1, 346, 10020, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 639, false, -1, 349, -1, -1, -1, false, false, false, false, utf8proc_sequences + 642}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 644, false, 348, -1, 348, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 647, false, -1, 351, -1, -1, -1, false, false, false, false, utf8proc_sequences + 650}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 652, false, 350, -1, 350, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 655, false, -1, 353, -1, 10080, -1, false, false, false, false, utf8proc_sequences + 658}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 660, false, 352, -1, 352, 10140, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 663, false, -1, 355, -1, -1, -1, false, false, false, false, utf8proc_sequences + 666}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 668, false, 354, -1, 354, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 671, false, -1, 357, -1, -1, -1, false, false, false, false, utf8proc_sequences + 674}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 676, false, 356, -1, 356, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 359, -1, -1, -1, false, false, false, false, utf8proc_sequences + 679}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 358, -1, 358, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 681, false, -1, 361, -1, 10320, -1, false, false, false, false, utf8proc_sequences + 684}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 686, false, 360, -1, 360, 10380, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 689, false, -1, 363, -1, 10440, -1, false, false, false, false, utf8proc_sequences + 692}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 694, false, 362, -1, 362, 10500, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 697, false, -1, 365, -1, -1, -1, false, false, false, false, utf8proc_sequences + 700}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 702, false, 364, -1, 364, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 705, false, -1, 367, -1, -1, -1, false, false, false, false, utf8proc_sequences + 708}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 710, false, 366, -1, 366, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 713, false, -1, 369, -1, -1, -1, false, false, false, false, utf8proc_sequences + 716}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 718, false, 368, -1, 368, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 721, false, -1, 371, -1, -1, -1, false, false, false, false, utf8proc_sequences + 724}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 726, false, 370, -1, 370, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 729, false, -1, 373, -1, -1, -1, false, false, false, false, utf8proc_sequences + 732}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 734, false, 372, -1, 372, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 737, false, -1, 375, -1, -1, -1, false, false, false, false, utf8proc_sequences + 740}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 742, false, 374, -1, 374, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 745, false, -1, 255, -1, -1, -1, false, false, false, false, utf8proc_sequences + 748}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 750, false, -1, 378, -1, -1, -1, false, false, false, false, utf8proc_sequences + 753}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 755, false, 377, -1, 377, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 758, false, -1, 380, -1, -1, -1, false, false, false, false, utf8proc_sequences + 761}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 763, false, 379, -1, 379, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 766, false, -1, 382, -1, -1, -1, false, false, false, false, utf8proc_sequences + 769}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 771, false, 381, -1, 381, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 36, false, 83, -1, 83, 10800, -1, false, false, false, false, utf8proc_sequences + 36}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 579, -1, 579, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 595, -1, -1, -1, false, false, false, false, utf8proc_sequences + 774}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 387, -1, -1, -1, false, false, false, false, utf8proc_sequences + 776}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 386, -1, 386, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 389, -1, -1, -1, false, false, false, false, utf8proc_sequences + 778}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 388, -1, 388, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 596, -1, -1, -1, false, false, false, false, utf8proc_sequences + 780}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 392, -1, -1, -1, false, false, false, false, utf8proc_sequences + 782}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 391, -1, 391, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 598, -1, -1, -1, false, false, false, false, utf8proc_sequences + 784}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 599, -1, -1, -1, false, false, false, false, utf8proc_sequences + 786}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 396, -1, -1, -1, false, false, false, false, utf8proc_sequences + 788}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 395, -1, 395, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 477, -1, -1, -1, false, false, false, false, utf8proc_sequences + 790}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 601, -1, -1, -1, false, false, false, false, utf8proc_sequences + 792}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 603, -1, -1, -1, false, false, false, false, utf8proc_sequences + 794}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 402, -1, -1, -1, false, false, false, false, utf8proc_sequences + 796}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 401, -1, 401, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 608, -1, -1, -1, false, false, false, false, utf8proc_sequences + 798}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 611, -1, -1, -1, false, false, false, false, utf8proc_sequences + 800}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 502, -1, 502, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 617, -1, -1, -1, false, false, false, false, utf8proc_sequences + 802}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 616, -1, -1, -1, false, false, false, false, utf8proc_sequences + 804}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 409, -1, -1, -1, false, false, false, false, utf8proc_sequences + 806}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 408, -1, 408, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 573, -1, 573, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 623, -1, -1, -1, false, false, false, false, utf8proc_sequences + 808}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 626, -1, -1, -1, false, false, false, false, utf8proc_sequences + 810}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 544, -1, 544, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 629, -1, -1, -1, false, false, false, false, utf8proc_sequences + 812}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 814, false, -1, 417, -1, 11700, -1, false, false, false, false, utf8proc_sequences + 817}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 819, false, 416, -1, 416, 11760, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 419, -1, -1, -1, false, false, false, false, utf8proc_sequences + 822}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 418, -1, 418, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 421, -1, -1, -1, false, false, false, false, utf8proc_sequences + 824}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 420, -1, 420, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 640, -1, -1, -1, false, false, false, false, utf8proc_sequences + 826}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 424, -1, -1, -1, false, false, false, false, utf8proc_sequences + 828}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 423, -1, 423, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 643, -1, -1, -1, false, false, false, false, utf8proc_sequences + 830}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 429, -1, -1, -1, false, false, false, false, utf8proc_sequences + 832}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 428, -1, 428, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 648, -1, -1, -1, false, false, false, false, utf8proc_sequences + 834}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 836, false, -1, 432, -1, 11820, -1, false, false, false, false, utf8proc_sequences + 839}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 841, false, 431, -1, 431, 11880, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 650, -1, -1, -1, false, false, false, false, utf8proc_sequences + 844}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 651, -1, -1, -1, false, false, false, false, utf8proc_sequences + 846}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 436, -1, -1, -1, false, false, false, false, utf8proc_sequences + 848}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 435, -1, 435, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 438, -1, -1, -1, false, false, false, false, utf8proc_sequences + 850}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 437, -1, 437, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 658, -1, 2880, -1, false, false, false, false, utf8proc_sequences + 852}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 441, -1, -1, -1, false, false, false, false, utf8proc_sequences + 854}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 440, -1, 440, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 445, -1, -1, -1, false, false, false, false, utf8proc_sequences + 856}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 444, -1, 444, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 503, -1, 503, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 858, false, -1, 454, 453, -1, -1, false, false, false, false, utf8proc_sequences + 861}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 863, false, 452, 454, 453, -1, -1, false, false, false, false, utf8proc_sequences + 861}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 866, false, 452, -1, 453, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 869, false, -1, 457, 456, -1, -1, false, false, false, false, utf8proc_sequences + 872}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 874, false, 455, 457, 456, -1, -1, false, false, false, false, utf8proc_sequences + 872}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 877, false, 455, -1, 456, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 880, false, -1, 460, 459, -1, -1, false, false, false, false, utf8proc_sequences + 883}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 885, false, 458, 460, 459, -1, -1, false, false, false, false, utf8proc_sequences + 883}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 888, false, 458, -1, 459, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 891, false, -1, 462, -1, -1, -1, false, false, false, false, utf8proc_sequences + 894}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 896, false, 461, -1, 461, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 899, false, -1, 464, -1, -1, -1, false, false, false, false, utf8proc_sequences + 902}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 904, false, 463, -1, 463, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 907, false, -1, 466, -1, -1, -1, false, false, false, false, utf8proc_sequences + 910}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 912, false, 465, -1, 465, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 915, false, -1, 468, -1, -1, -1, false, false, false, false, utf8proc_sequences + 918}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 920, false, 467, -1, 467, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 923, false, -1, 470, -1, -1, -1, false, false, false, false, utf8proc_sequences + 926}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 928, false, 469, -1, 469, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 931, false, -1, 472, -1, -1, -1, false, false, false, false, utf8proc_sequences + 934}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 936, false, 471, -1, 471, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 939, false, -1, 474, -1, -1, -1, false, false, false, false, utf8proc_sequences + 942}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 944, false, 473, -1, 473, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 947, false, -1, 476, -1, -1, -1, false, false, false, false, utf8proc_sequences + 950}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 952, false, 475, -1, 475, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 398, -1, 398, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 955, false, -1, 479, -1, -1, -1, false, false, false, false, utf8proc_sequences + 958}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 960, false, 478, -1, 478, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 963, false, -1, 481, -1, -1, -1, false, false, false, false, utf8proc_sequences + 966}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 968, false, 480, -1, 480, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 971, false, -1, 483, -1, -1, -1, false, false, false, false, utf8proc_sequences + 974}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 976, false, 482, -1, 482, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 485, -1, -1, -1, false, false, false, false, utf8proc_sequences + 979}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 484, -1, 484, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 981, false, -1, 487, -1, -1, -1, false, false, false, false, utf8proc_sequences + 984}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 986, false, 486, -1, 486, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 989, false, -1, 489, -1, -1, -1, false, false, false, false, utf8proc_sequences + 992}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 994, false, 488, -1, 488, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 997, false, -1, 491, -1, 2760, -1, false, false, false, false, utf8proc_sequences + 1000}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1002, false, 490, -1, 490, 2820, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1005, false, -1, 493, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1008}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1010, false, 492, -1, 492, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1013, false, -1, 495, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1016}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1018, false, 494, -1, 494, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1021, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1021}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1024, false, -1, 499, 498, -1, -1, false, false, false, false, utf8proc_sequences + 1027}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1029, false, 497, 499, 498, -1, -1, false, false, false, false, utf8proc_sequences + 1027}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1032, false, 497, -1, 498, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1035, false, -1, 501, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1038}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1040, false, 500, -1, 500, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 405, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1043}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 447, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1045}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1047, false, -1, 505, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1050}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1052, false, 504, -1, 504, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1055, false, -1, 507, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1058}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1060, false, 506, -1, 506, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1063, false, -1, 509, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1066}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1068, false, 508, -1, 508, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1071, false, -1, 511, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1074}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1076, false, 510, -1, 510, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1079, false, -1, 513, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1082}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1084, false, 512, -1, 512, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1087, false, -1, 515, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1090}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1092, false, 514, -1, 514, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1095, false, -1, 517, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1098}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1100, false, 516, -1, 516, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1103, false, -1, 519, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1106}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1108, false, 518, -1, 518, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1111, false, -1, 521, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1114}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1116, false, 520, -1, 520, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1119, false, -1, 523, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1122}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1124, false, 522, -1, 522, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1127, false, -1, 525, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1130}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1132, false, 524, -1, 524, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1135, false, -1, 527, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1138}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1140, false, 526, -1, 526, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1143, false, -1, 529, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1146}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1148, false, 528, -1, 528, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1151, false, -1, 531, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1154}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1156, false, 530, -1, 530, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1159, false, -1, 533, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1162}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1164, false, 532, -1, 532, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1167, false, -1, 535, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1170}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1172, false, 534, -1, 534, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1175, false, -1, 537, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1178}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1180, false, 536, -1, 536, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1183, false, -1, 539, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1186}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1188, false, 538, -1, 538, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 541, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1191}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 540, -1, 540, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1193, false, -1, 543, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1196}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1198, false, 542, -1, 542, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 414, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1201}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 547, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1203}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 546, -1, 546, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 549, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1205}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 548, -1, 548, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1207, false, -1, 551, -1, 2520, -1, false, false, false, false, utf8proc_sequences + 1210}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1212, false, 550, -1, 550, 2580, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1215, false, -1, 553, -1, 9000, -1, false, false, false, false, utf8proc_sequences + 1218}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1220, false, 552, -1, 552, 9060, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1223, false, -1, 555, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1226}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1228, false, 554, -1, 554, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1231, false, -1, 557, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1234}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1236, false, 556, -1, 556, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1239, false, -1, 559, -1, 3480, -1, false, false, false, false, utf8proc_sequences + 1242}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1244, false, 558, -1, 558, 3540, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1247, false, -1, 561, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1250}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1252, false, 560, -1, 560, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1255, false, -1, 563, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1258}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1260, false, 562, -1, 562, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11365, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1263}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 572, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1265}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 571, -1, 571, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 410, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1267}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11366, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1269}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 578, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1271}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 577, -1, 577, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 384, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1273}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 649, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1275}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 652, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1277}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 583, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1279}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 582, -1, 582, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 585, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1281}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 584, -1, 584, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 587, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1283}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 586, -1, 586, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 589, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1285}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 588, -1, 588, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 591, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1287}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 590, -1, 590, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 385, -1, 385, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 390, -1, 390, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 393, -1, 393, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 394, -1, 394, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 399, -1, 399, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 400, -1, 400, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 403, -1, 403, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 404, -1, 404, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 407, -1, 407, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 406, -1, 406, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11362, -1, 11362, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 412, -1, 412, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 413, -1, 413, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 415, -1, 415, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11364, -1, 11364, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 422, -1, 422, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 425, -1, 425, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 430, -1, 430, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 580, -1, 580, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 433, -1, 433, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 434, -1, 434, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 581, -1, 581, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 439, -1, 439, 2940, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 14, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1289, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 18, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 34, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1293, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1295, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 44, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 48, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1297, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1306, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1309, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1312, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 22, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 36, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 46, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1315, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 0, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 2, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 3, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 7, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 8, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 10, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 4, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 46, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 5, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 12, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 11, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 14, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 15, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 47, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 48, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 232, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 216, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 13, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 40, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 45, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 39, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 16, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 6, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 9, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 42, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 44, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 43, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 41, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 1, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 1, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 51, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 1317, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 1319, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 49, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 1321, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 1323, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 240, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, 921, -1, 921, -1, 50, false, false, false, true, utf8proc_sequences + 1326}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, true, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 233, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 234, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 1328, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1330, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1021, -1, 1021, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1022, -1, 1022, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1023, -1, 1023, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 1333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 1335, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1338, false, -1, 940, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1341}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 1343, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1345, false, -1, 941, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1348}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1350, false, -1, 942, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1353}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1355, false, -1, 943, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1358}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1360, false, -1, 972, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1363}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1365, false, -1, 973, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1368}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1370, false, -1, 974, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1373}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1375, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1378}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 945, -1, 3660, -1, false, false, false, false, utf8proc_sequences + 1382}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 946, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1384}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 947, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1386}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 948, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1388}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 949, -1, 3720, -1, false, false, false, false, utf8proc_sequences + 1390}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 950, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1392}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 951, -1, 3780, -1, false, false, false, false, utf8proc_sequences + 1394}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 952, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1396}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 953, -1, 3840, -1, false, false, false, false, utf8proc_sequences + 1326}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 954, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1398}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 955, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1400}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 956, -1, -1, -1, false, false, false, false, utf8proc_sequences + 67}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 957, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1402}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 958, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1404}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 959, -1, 3900, -1, false, false, false, false, utf8proc_sequences + 1406}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 960, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1408}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 961, -1, 16260, -1, false, false, false, false, utf8proc_sequences + 1410}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 963, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1412}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 964, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1414}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 965, -1, 3960, -1, false, false, false, false, utf8proc_sequences + 1416}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 966, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1418}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 967, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1420}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 968, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1422}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 969, -1, 4020, -1, false, false, false, false, utf8proc_sequences + 1424}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1426, false, -1, 970, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1429}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1431, false, -1, 971, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1434}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1436, false, 902, -1, 902, 15780, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1439, false, 904, -1, 904, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1442, false, 905, -1, 905, 15960, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1445, false, 906, -1, 906, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1448, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1451}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 913, -1, 913, 4140, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 914, -1, 914, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 915, -1, 915, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 916, -1, 916, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 917, -1, 917, 4200, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 918, -1, 918, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 919, -1, 919, 4260, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 920, -1, 920, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 921, -1, 921, 4320, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 922, -1, 922, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 923, -1, 923, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 924, -1, 924, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 925, -1, 925, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 926, -1, 926, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 927, -1, 927, 4500, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 928, -1, 928, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 929, -1, 929, 16200, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 931, -1, 931, -1, -1, false, false, false, false, utf8proc_sequences + 1412}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 931, -1, 931, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 932, -1, 932, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 933, -1, 933, 4440, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 934, -1, 934, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 935, -1, 935, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 936, -1, 936, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 937, -1, 937, 4560, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1455, false, 938, -1, 938, 4080, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1458, false, 939, -1, 939, 4380, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1461, false, 908, -1, 908, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1464, false, 910, -1, 910, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1467, false, 911, -1, 911, 16380, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1384, false, 914, -1, 914, -1, -1, false, false, false, false, utf8proc_sequences + 1384}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1396, false, 920, -1, 920, -1, -1, false, false, false, false, utf8proc_sequences + 1396}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1470, false, -1, -1, -1, 4620, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1475, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1418, false, 934, -1, 934, -1, -1, false, false, false, false, utf8proc_sequences + 1418}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1408, false, 928, -1, 928, -1, -1, false, false, false, false, utf8proc_sequences + 1408}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 985, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1478}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 984, -1, 984, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 987, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1480}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 986, -1, 986, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 989, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1482}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 988, -1, 988, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 991, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1484}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 990, -1, 990, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 993, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1486}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 992, -1, 992, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 995, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1488}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 994, -1, 994, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 997, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1490}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 996, -1, 996, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 999, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1492}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 998, -1, 998, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1001, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1494}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1000, -1, 1000, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1003, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1496}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1002, -1, 1002, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1005, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1498}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1004, -1, 1004, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1007, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1500}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1006, -1, 1006, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1398, false, 922, -1, 922, -1, -1, false, false, false, false, utf8proc_sequences + 1398}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1410, false, 929, -1, 929, -1, -1, false, false, false, false, utf8proc_sequences + 1410}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1502, false, 1017, -1, 1017, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1504, false, -1, 952, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1396}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1390, false, 917, -1, 917, -1, -1, false, false, false, false, utf8proc_sequences + 1390}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1016, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1506}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1015, -1, 1015, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1508, false, -1, 1010, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1510}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1019, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1512}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1018, -1, 1018, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 891, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1514}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 892, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1516}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 893, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1518}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1520, false, -1, 1104, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1523}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1525, false, -1, 1105, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1528}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1106, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1530}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1532, false, -1, 1107, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1535}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1108, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1537}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1109, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1539}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1110, -1, 4800, -1, false, false, false, false, utf8proc_sequences + 1541}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1543, false, -1, 1111, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1546}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1112, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1548}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1113, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1550}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1114, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1552}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1115, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1554}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1556, false, -1, 1116, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1559}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1561, false, -1, 1117, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1564}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1566, false, -1, 1118, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1569}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1119, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1571}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1072, -1, 5640, -1, false, false, false, false, utf8proc_sequences + 1573}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1073, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1575}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1074, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1577}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1075, -1, 4740, -1, false, false, false, false, utf8proc_sequences + 1579}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1076, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1581}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1077, -1, 4680, -1, false, false, false, false, utf8proc_sequences + 1583}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1078, -1, 5520, -1, false, false, false, false, utf8proc_sequences + 1585}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1079, -1, 5880, -1, false, false, false, false, utf8proc_sequences + 1587}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1080, -1, 4920, -1, false, false, false, false, utf8proc_sequences + 1589}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1591, false, -1, 1081, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1594}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1082, -1, 4860, -1, false, false, false, false, utf8proc_sequences + 1596}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1083, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1598}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1084, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1600}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1085, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1602}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1086, -1, 6000, -1, false, false, false, false, utf8proc_sequences + 1604}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1087, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1606}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1088, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1608}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1089, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1610}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1090, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1612}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1091, -1, 4980, -1, false, false, false, false, utf8proc_sequences + 1614}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1092, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1616}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1093, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1618}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1094, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1620}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1095, -1, 6360, -1, false, false, false, false, utf8proc_sequences + 1622}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1096, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1624}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1097, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1626}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1098, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1628}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1099, -1, 6480, -1, false, false, false, false, utf8proc_sequences + 1630}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1100, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1632}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1101, -1, 6240, -1, false, false, false, false, utf8proc_sequences + 1634}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1102, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1636}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1103, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1638}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1040, -1, 1040, 5700, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1041, -1, 1041, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1042, -1, 1042, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1043, -1, 1043, 5160, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1044, -1, 1044, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1045, -1, 1045, 5100, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1046, -1, 1046, 5580, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1047, -1, 1047, 5940, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1048, -1, 1048, 5040, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1640, false, 1049, -1, 1049, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1050, -1, 1050, 5280, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1051, -1, 1051, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1052, -1, 1052, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1053, -1, 1053, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1054, -1, 1054, 6060, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1055, -1, 1055, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1056, -1, 1056, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1057, -1, 1057, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1058, -1, 1058, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1059, -1, 1059, 5340, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1060, -1, 1060, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1061, -1, 1061, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1062, -1, 1062, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1063, -1, 1063, 6420, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1064, -1, 1064, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1065, -1, 1065, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1066, -1, 1066, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1067, -1, 1067, 6540, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1068, -1, 1068, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1069, -1, 1069, 6300, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1070, -1, 1070, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1071, -1, 1071, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1643, false, 1024, -1, 1024, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1646, false, 1025, -1, 1025, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1026, -1, 1026, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1649, false, 1027, -1, 1027, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1028, -1, 1028, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1029, -1, 1029, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1030, -1, 1030, 5220, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1652, false, 1031, -1, 1031, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1032, -1, 1032, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1033, -1, 1033, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1034, -1, 1034, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1035, -1, 1035, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1655, false, 1036, -1, 1036, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1658, false, 1037, -1, 1037, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1661, false, 1038, -1, 1038, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1039, -1, 1039, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1121, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1664}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1120, -1, 1120, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1123, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1666}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1122, -1, 1122, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1125, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1668}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1124, -1, 1124, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1127, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1670}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1126, -1, 1126, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1129, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1672}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1128, -1, 1128, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1131, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1674}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1130, -1, 1130, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1133, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1676}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1132, -1, 1132, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1135, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1678}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1134, -1, 1134, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1137, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1680}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1136, -1, 1136, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1139, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1682}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1138, -1, 1138, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1141, -1, 5400, -1, false, false, false, false, utf8proc_sequences + 1684}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1140, -1, 1140, 5460, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1686, false, -1, 1143, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1689}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1691, false, 1142, -1, 1142, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1145, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1694}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1144, -1, 1144, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1147, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1696}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1146, -1, 1146, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1149, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1698}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1148, -1, 1148, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1151, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1700}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1150, -1, 1150, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1153, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1702}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1152, -1, 1152, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ME, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1163, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1704}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1162, -1, 1162, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1165, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1706}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1164, -1, 1164, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1167, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1708}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1166, -1, 1166, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1169, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1710}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1168, -1, 1168, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1171, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1712}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1170, -1, 1170, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1173, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1714}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1172, -1, 1172, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1175, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1716}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1174, -1, 1174, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1177, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1718}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1176, -1, 1176, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1179, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1720}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1178, -1, 1178, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1181, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1722}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1180, -1, 1180, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1183, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1724}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1182, -1, 1182, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1185, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1726}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1184, -1, 1184, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1187, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1728}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1186, -1, 1186, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1189, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1730}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1188, -1, 1188, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1191, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1732}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1190, -1, 1190, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1193, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1734}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1192, -1, 1192, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1195, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1736}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1194, -1, 1194, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1197, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1738}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1196, -1, 1196, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1199, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1740}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1198, -1, 1198, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1201, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1742}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1200, -1, 1200, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1203, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1744}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1202, -1, 1202, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1205, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1746}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1204, -1, 1204, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1207, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1748}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1206, -1, 1206, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1209, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1750}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1208, -1, 1208, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1211, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1752}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1210, -1, 1210, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1213, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1754}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1212, -1, 1212, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1215, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1756}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1214, -1, 1214, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1231, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1758}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1760, false, -1, 1218, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1763}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1765, false, 1217, -1, 1217, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1220, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1768}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1219, -1, 1219, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1222, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1770}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1221, -1, 1221, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1224, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1772}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1223, -1, 1223, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1226, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1774}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1225, -1, 1225, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1228, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1776}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1227, -1, 1227, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1230, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1778}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1229, -1, 1229, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1216, -1, 1216, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1780, false, -1, 1233, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1783}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1785, false, 1232, -1, 1232, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1788, false, -1, 1235, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1791}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1793, false, 1234, -1, 1234, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1237, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1796}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1236, -1, 1236, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1798, false, -1, 1239, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1801}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1803, false, 1238, -1, 1238, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1241, -1, 5760, -1, false, false, false, false, utf8proc_sequences + 1806}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1240, -1, 1240, 5820, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1808, false, -1, 1243, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1811}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1813, false, 1242, -1, 1242, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1816, false, -1, 1245, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1819}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1821, false, 1244, -1, 1244, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1824, false, -1, 1247, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1827}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1829, false, 1246, -1, 1246, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1249, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1832}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1248, -1, 1248, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1834, false, -1, 1251, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1837}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1839, false, 1250, -1, 1250, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1842, false, -1, 1253, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1845}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1847, false, 1252, -1, 1252, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1850, false, -1, 1255, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1853}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1855, false, 1254, -1, 1254, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1257, -1, 6120, -1, false, false, false, false, utf8proc_sequences + 1858}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1256, -1, 1256, 6180, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1860, false, -1, 1259, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1863}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1865, false, 1258, -1, 1258, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1868, false, -1, 1261, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1871}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1873, false, 1260, -1, 1260, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1876, false, -1, 1263, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1879}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1881, false, 1262, -1, 1262, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1884, false, -1, 1265, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1887}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1889, false, 1264, -1, 1264, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1892, false, -1, 1267, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1895}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1897, false, 1266, -1, 1266, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1900, false, -1, 1269, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1903}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1905, false, 1268, -1, 1268, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1271, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1908}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1270, -1, 1270, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1910, false, -1, 1273, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1913}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1915, false, 1272, -1, 1272, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1275, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1918}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1274, -1, 1274, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1277, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1920}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1276, -1, 1276, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1279, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1922}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1278, -1, 1278, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1281, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1924}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1280, -1, 1280, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1283, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1926}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1282, -1, 1282, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1285, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1928}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1284, -1, 1284, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1287, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1930}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1286, -1, 1286, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1289, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1932}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1288, -1, 1288, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1291, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1934}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1290, -1, 1290, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1293, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1936}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1292, -1, 1292, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1295, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1938}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1294, -1, 1294, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1297, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1940}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1296, -1, 1296, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1299, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1942}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1298, -1, 1298, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1377, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1944}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1378, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1946}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1379, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1948}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1380, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1950}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1381, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1952}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1382, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1954}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1383, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1956}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1384, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1958}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1385, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1960}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1386, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1962}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1387, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1964}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1388, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1966}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1389, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1968}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1390, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1970}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1391, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1972}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1392, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1974}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1393, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1976}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1394, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1978}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1395, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1980}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1396, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1982}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1397, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1984}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1398, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1986}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1399, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1988}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1400, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1990}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1401, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1992}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1402, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1994}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1403, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1996}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1404, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1998}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1405, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2000}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1406, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2002}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1407, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2004}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1408, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2006}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1409, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2008}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1410, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2010}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1411, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2012}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1412, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2014}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1413, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2016}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1414, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2018}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1329, -1, 1329, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1330, -1, 1330, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1331, -1, 1331, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1332, -1, 1332, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1333, -1, 1333, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1334, -1, 1334, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1335, -1, 1335, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1336, -1, 1336, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1337, -1, 1337, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1338, -1, 1338, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1339, -1, 1339, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1340, -1, 1340, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1341, -1, 1341, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1342, -1, 1342, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1343, -1, 1343, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1344, -1, 1344, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1345, -1, 1345, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1346, -1, 1346, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1347, -1, 1347, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1348, -1, 1348, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1349, -1, 1349, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1350, -1, 1350, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1351, -1, 1351, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1352, -1, 1352, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1353, -1, 1353, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1354, -1, 1354, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1355, -1, 1355, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1356, -1, 1356, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1357, -1, 1357, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1358, -1, 1358, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1359, -1, 1359, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1360, -1, 1360, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1361, -1, 1361, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1362, -1, 1362, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1363, -1, 1363, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1364, -1, 1364, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1365, -1, 1365, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1366, -1, 1366, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2020, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2020}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 222, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 228, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 10, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 11, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 12, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 13, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 14, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 15, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 16, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 17, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 18, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 19, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 20, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 21, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 22, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 23, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 24, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 25, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6600, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6660, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6720, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 27, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 28, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 29, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 30, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 31, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 32, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 33, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 34, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 17, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 18, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 19, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_AN, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_AN, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 35, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6840, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6900, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2056, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6780, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 36, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 6960, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7020, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7080, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 20, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2068, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2071, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2074, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2077, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2080, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2083, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2086, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2089, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 21, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7140, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 22, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2098, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2101, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2104, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2107, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2110, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2113, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2116, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2119, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2122, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 24, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7200, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 23, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 25, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2134, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2137, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7260, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 27, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7320, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7380, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2149, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 26, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, 7440, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2152, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 84, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 91, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 28, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7500, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 31, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7560, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2164, false, -1, -1, -1, 7620, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 29, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 30, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 32, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7680, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7740, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 33, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 34, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 35, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7800, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2182, false, -1, -1, -1, 7860, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 36, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 103, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 107, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 118, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 122, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2197, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NOBREAK, utf8proc_sequences + 2203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 216, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2205, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2208, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2211, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2214, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2217, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2220, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 129, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 130, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2223, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 132, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2226, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2229, false, -1, -1, -1, -1, -1, true, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2232, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2235, false, -1, -1, -1, -1, -1, true, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2238, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2241, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2244, false, -1, -1, -1, -1, -1, true, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2247, false, -1, -1, -1, -1, -1, true, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2250, false, -1, -1, -1, -1, -1, true, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2253, false, -1, -1, -1, -1, -1, true, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2256, false, -1, -1, -1, -1, -1, true, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2259, false, -1, -1, -1, -1, -1, true, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7920, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2262, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 37, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11520, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2265}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11521, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2267}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11522, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2269}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11523, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2271}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11524, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2273}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11525, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2275}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11526, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2277}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11527, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2279}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11528, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2281}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11529, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2283}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11530, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2285}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11531, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2287}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11532, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2289}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11533, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2291}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11534, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2293}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11535, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2295}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11536, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2297}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11537, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2299}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11538, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2301}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11539, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2303}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11540, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2305}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11541, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2307}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11542, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2309}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11543, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2311}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11544, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2313}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11545, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2315}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11546, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2317}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11547, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2319}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11548, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2321}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11549, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2323}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11550, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2325}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11551, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2327}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11552, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2329}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11553, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2331}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11554, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2333}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11555, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2335}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11556, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2337}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11557, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2339}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2341, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, true, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7980, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2343, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8040, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2346, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8100, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2349, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8160, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2352, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8220, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2355, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8280, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2358, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 38, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, 8340, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2361, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, 8400, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2364, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8460, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8520, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2367, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2370, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, 8580, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2373, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 9, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2376, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2378, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2394, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2402, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2406, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2408, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2412, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2414, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2416, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 0, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 8, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 794, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2424, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 12, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 20, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 24, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 579, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 28, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 780, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2426, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2428, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 30, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 38, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 40, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2430, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 808, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 42, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2432, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 16, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 34, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 40, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 42, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1602, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11363, -1, 11363, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2434, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2436, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 163, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 10, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2438, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2442, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 804, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 802, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2444, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2446, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2448, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2450, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2456, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2458, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 810, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2460, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2462, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 812, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2466, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2468, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 844, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 846, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1277, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 50, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2474, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 852, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2476, false, -1, 7681, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2479}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2481, false, 7680, -1, 7680, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2484, false, -1, 7683, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2487}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2489, false, 7682, -1, 7682, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2492, false, -1, 7685, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2495}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2497, false, 7684, -1, 7684, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2500, false, -1, 7687, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2503}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2505, false, 7686, -1, 7686, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2508, false, -1, 7689, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2511}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2513, false, 7688, -1, 7688, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2516, false, -1, 7691, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2519}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2521, false, 7690, -1, 7690, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2524, false, -1, 7693, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2527}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2529, false, 7692, -1, 7692, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2532, false, -1, 7695, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2535}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2537, false, 7694, -1, 7694, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2540, false, -1, 7697, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2543}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2545, false, 7696, -1, 7696, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2548, false, -1, 7699, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2551}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2553, false, 7698, -1, 7698, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2556, false, -1, 7701, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2559}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2561, false, 7700, -1, 7700, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2564, false, -1, 7703, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2567}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2569, false, 7702, -1, 7702, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2572, false, -1, 7705, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2575}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2577, false, 7704, -1, 7704, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2580, false, -1, 7707, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2583}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2585, false, 7706, -1, 7706, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2588, false, -1, 7709, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2591}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2593, false, 7708, -1, 7708, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2596, false, -1, 7711, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2599}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2601, false, 7710, -1, 7710, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2604, false, -1, 7713, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2607}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2609, false, 7712, -1, 7712, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2612, false, -1, 7715, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2615}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2617, false, 7714, -1, 7714, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2620, false, -1, 7717, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2623}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2625, false, 7716, -1, 7716, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2628, false, -1, 7719, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2631}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2633, false, 7718, -1, 7718, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2636, false, -1, 7721, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2639}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2641, false, 7720, -1, 7720, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2644, false, -1, 7723, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2647}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2649, false, 7722, -1, 7722, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2652, false, -1, 7725, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2655}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2657, false, 7724, -1, 7724, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2660, false, -1, 7727, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2663}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2665, false, 7726, -1, 7726, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2668, false, -1, 7729, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2671}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2673, false, 7728, -1, 7728, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2676, false, -1, 7731, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2679}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2681, false, 7730, -1, 7730, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2684, false, -1, 7733, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2687}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2689, false, 7732, -1, 7732, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2692, false, -1, 7735, -1, 9360, -1, false, false, false, false, utf8proc_sequences + 2695}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2697, false, 7734, -1, 7734, 9420, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2700, false, -1, 7737, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2703}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2705, false, 7736, -1, 7736, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2708, false, -1, 7739, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2711}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2713, false, 7738, -1, 7738, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2716, false, -1, 7741, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2719}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2721, false, 7740, -1, 7740, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2724, false, -1, 7743, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2727}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2729, false, 7742, -1, 7742, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2732, false, -1, 7745, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2735}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2737, false, 7744, -1, 7744, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2740, false, -1, 7747, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2743}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2745, false, 7746, -1, 7746, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2748, false, -1, 7749, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2751}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2753, false, 7748, -1, 7748, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2756, false, -1, 7751, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2759}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2761, false, 7750, -1, 7750, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2764, false, -1, 7753, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2767}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2769, false, 7752, -1, 7752, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2772, false, -1, 7755, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2775}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2777, false, 7754, -1, 7754, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2780, false, -1, 7757, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2783}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2785, false, 7756, -1, 7756, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2788, false, -1, 7759, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2791}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2793, false, 7758, -1, 7758, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2796, false, -1, 7761, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2799}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2801, false, 7760, -1, 7760, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2804, false, -1, 7763, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2807}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2809, false, 7762, -1, 7762, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2812, false, -1, 7765, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2815}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2817, false, 7764, -1, 7764, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2820, false, -1, 7767, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2823}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2825, false, 7766, -1, 7766, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2828, false, -1, 7769, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2831}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2833, false, 7768, -1, 7768, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2836, false, -1, 7771, -1, 9840, -1, false, false, false, false, utf8proc_sequences + 2839}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2841, false, 7770, -1, 7770, 9900, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2844, false, -1, 7773, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2847}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2849, false, 7772, -1, 7772, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2852, false, -1, 7775, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2855}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2857, false, 7774, -1, 7774, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2860, false, -1, 7777, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2863}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2865, false, 7776, -1, 7776, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2868, false, -1, 7779, -1, 10200, -1, false, false, false, false, utf8proc_sequences + 2871}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2873, false, 7778, -1, 7778, 10260, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2876, false, -1, 7781, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2879}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2881, false, 7780, -1, 7780, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2884, false, -1, 7783, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2887}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2889, false, 7782, -1, 7782, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2892, false, -1, 7785, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2895}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2897, false, 7784, -1, 7784, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2900, false, -1, 7787, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2903}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2905, false, 7786, -1, 7786, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2908, false, -1, 7789, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2911}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2913, false, 7788, -1, 7788, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2916, false, -1, 7791, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2919}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2921, false, 7790, -1, 7790, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2924, false, -1, 7793, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2927}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2929, false, 7792, -1, 7792, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2932, false, -1, 7795, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2935}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2937, false, 7794, -1, 7794, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2940, false, -1, 7797, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2943}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2945, false, 7796, -1, 7796, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2948, false, -1, 7799, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2951}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2953, false, 7798, -1, 7798, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2956, false, -1, 7801, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2959}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2961, false, 7800, -1, 7800, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2964, false, -1, 7803, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2967}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2969, false, 7802, -1, 7802, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2972, false, -1, 7805, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2975}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2977, false, 7804, -1, 7804, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2980, false, -1, 7807, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2983}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2985, false, 7806, -1, 7806, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2988, false, -1, 7809, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2991}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2993, false, 7808, -1, 7808, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2996, false, -1, 7811, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2999}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3001, false, 7810, -1, 7810, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3004, false, -1, 7813, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3007}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3009, false, 7812, -1, 7812, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3012, false, -1, 7815, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3015}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3017, false, 7814, -1, 7814, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3020, false, -1, 7817, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3023}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3025, false, 7816, -1, 7816, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3028, false, -1, 7819, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3031}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3033, false, 7818, -1, 7818, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3036, false, -1, 7821, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3039}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3041, false, 7820, -1, 7820, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3044, false, -1, 7823, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3047}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3049, false, 7822, -1, 7822, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3052, false, -1, 7825, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3055}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3057, false, 7824, -1, 7824, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3060, false, -1, 7827, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3063}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3065, false, 7826, -1, 7826, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3068, false, -1, 7829, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3071}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3073, false, 7828, -1, 7828, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3076, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3076}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3079, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3079}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3082, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3082}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3085, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3085}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 3088, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3088}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3091, false, 7776, -1, 7776, -1, -1, false, false, false, false, utf8proc_sequences + 2863}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3094, false, -1, 7841, -1, 10980, -1, false, false, false, false, utf8proc_sequences + 3097}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3099, false, 7840, -1, 7840, 11040, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3102, false, -1, 7843, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3105}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3107, false, 7842, -1, 7842, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3110, false, -1, 7845, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3113}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3115, false, 7844, -1, 7844, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3118, false, -1, 7847, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3121}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3123, false, 7846, -1, 7846, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3126, false, -1, 7849, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3129}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3131, false, 7848, -1, 7848, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3134, false, -1, 7851, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3137}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3139, false, 7850, -1, 7850, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3142, false, -1, 7853, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3145}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3147, false, 7852, -1, 7852, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3150, false, -1, 7855, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3153}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3155, false, 7854, -1, 7854, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3158, false, -1, 7857, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3161}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3163, false, 7856, -1, 7856, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3166, false, -1, 7859, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3169}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3171, false, 7858, -1, 7858, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3174, false, -1, 7861, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3177}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3179, false, 7860, -1, 7860, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3182, false, -1, 7863, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3185}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3187, false, 7862, -1, 7862, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3190, false, -1, 7865, -1, 11340, -1, false, false, false, false, utf8proc_sequences + 3193}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3195, false, 7864, -1, 7864, 11400, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3198, false, -1, 7867, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3201}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3203, false, 7866, -1, 7866, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3206, false, -1, 7869, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3209}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3211, false, 7868, -1, 7868, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3214, false, -1, 7871, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3217}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3219, false, 7870, -1, 7870, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3222, false, -1, 7873, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3225}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3227, false, 7872, -1, 7872, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3230, false, -1, 7875, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3233}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3235, false, 7874, -1, 7874, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3238, false, -1, 7877, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3241}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3243, false, 7876, -1, 7876, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3246, false, -1, 7879, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3249}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3251, false, 7878, -1, 7878, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3254, false, -1, 7881, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3257}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3259, false, 7880, -1, 7880, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3262, false, -1, 7883, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3265}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3267, false, 7882, -1, 7882, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3270, false, -1, 7885, -1, 11580, -1, false, false, false, false, utf8proc_sequences + 3273}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3275, false, 7884, -1, 7884, 11640, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3278, false, -1, 7887, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3281}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3283, false, 7886, -1, 7886, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3286, false, -1, 7889, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3289}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3291, false, 7888, -1, 7888, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3294, false, -1, 7891, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3297}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3299, false, 7890, -1, 7890, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3302, false, -1, 7893, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3305}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3307, false, 7892, -1, 7892, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3310, false, -1, 7895, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3313}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3315, false, 7894, -1, 7894, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3318, false, -1, 7897, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3321}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3323, false, 7896, -1, 7896, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3326, false, -1, 7899, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3329}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3331, false, 7898, -1, 7898, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3334, false, -1, 7901, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3337}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3339, false, 7900, -1, 7900, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3342, false, -1, 7903, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3345}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3347, false, 7902, -1, 7902, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3350, false, -1, 7905, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3353}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3355, false, 7904, -1, 7904, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3358, false, -1, 7907, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3361}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3363, false, 7906, -1, 7906, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3366, false, -1, 7909, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3369}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3371, false, 7908, -1, 7908, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3374, false, -1, 7911, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3377}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3379, false, 7910, -1, 7910, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3382, false, -1, 7913, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3385}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3387, false, 7912, -1, 7912, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3390, false, -1, 7915, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3393}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3395, false, 7914, -1, 7914, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3398, false, -1, 7917, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3401}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3403, false, 7916, -1, 7916, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3406, false, -1, 7919, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3409}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3411, false, 7918, -1, 7918, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3414, false, -1, 7921, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3417}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3419, false, 7920, -1, 7920, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3422, false, -1, 7923, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3425}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3427, false, 7922, -1, 7922, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3430, false, -1, 7925, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3433}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3435, false, 7924, -1, 7924, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3438, false, -1, 7927, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3441}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3443, false, 7926, -1, 7926, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3446, false, -1, 7929, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3449}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3451, false, 7928, -1, 7928, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3454, false, 7944, -1, 7944, 11940, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3457, false, 7945, -1, 7945, 12000, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3460, false, 7946, -1, 7946, 13560, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3463, false, 7947, -1, 7947, 13620, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3466, false, 7948, -1, 7948, 13680, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3469, false, 7949, -1, 7949, 13740, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3472, false, 7950, -1, 7950, 13800, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3475, false, 7951, -1, 7951, 13860, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3478, false, -1, 7936, -1, 12060, -1, false, false, false, false, utf8proc_sequences + 3481}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3483, false, -1, 7937, -1, 12120, -1, false, false, false, false, utf8proc_sequences + 3486}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3488, false, -1, 7938, -1, 13920, -1, false, false, false, false, utf8proc_sequences + 3491}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3493, false, -1, 7939, -1, 13980, -1, false, false, false, false, utf8proc_sequences + 3496}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3498, false, -1, 7940, -1, 14040, -1, false, false, false, false, utf8proc_sequences + 3501}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3503, false, -1, 7941, -1, 14100, -1, false, false, false, false, utf8proc_sequences + 3506}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3508, false, -1, 7942, -1, 14160, -1, false, false, false, false, utf8proc_sequences + 3511}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3513, false, -1, 7943, -1, 14220, -1, false, false, false, false, utf8proc_sequences + 3516}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3518, false, 7960, -1, 7960, 12180, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3521, false, 7961, -1, 7961, 12240, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3524, false, 7962, -1, 7962, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3527, false, 7963, -1, 7963, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3530, false, 7964, -1, 7964, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3533, false, 7965, -1, 7965, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3536, false, -1, 7952, -1, 12300, -1, false, false, false, false, utf8proc_sequences + 3539}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3541, false, -1, 7953, -1, 12360, -1, false, false, false, false, utf8proc_sequences + 3544}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3546, false, -1, 7954, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3549}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3551, false, -1, 7955, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3554}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3556, false, -1, 7956, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3559}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3561, false, -1, 7957, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3564}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3566, false, 7976, -1, 7976, 12420, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3569, false, 7977, -1, 7977, 12480, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3572, false, 7978, -1, 7978, 14280, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3575, false, 7979, -1, 7979, 14340, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3578, false, 7980, -1, 7980, 14400, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3581, false, 7981, -1, 7981, 14460, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3584, false, 7982, -1, 7982, 14520, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3587, false, 7983, -1, 7983, 14580, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3590, false, -1, 7968, -1, 12540, -1, false, false, false, false, utf8proc_sequences + 3593}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3595, false, -1, 7969, -1, 12600, -1, false, false, false, false, utf8proc_sequences + 3598}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3600, false, -1, 7970, -1, 14640, -1, false, false, false, false, utf8proc_sequences + 3603}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3605, false, -1, 7971, -1, 14700, -1, false, false, false, false, utf8proc_sequences + 3608}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3610, false, -1, 7972, -1, 14760, -1, false, false, false, false, utf8proc_sequences + 3613}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3615, false, -1, 7973, -1, 14820, -1, false, false, false, false, utf8proc_sequences + 3618}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3620, false, -1, 7974, -1, 14880, -1, false, false, false, false, utf8proc_sequences + 3623}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3625, false, -1, 7975, -1, 14940, -1, false, false, false, false, utf8proc_sequences + 3628}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3630, false, 7992, -1, 7992, 12660, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3633, false, 7993, -1, 7993, 12720, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3636, false, 7994, -1, 7994, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3639, false, 7995, -1, 7995, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3642, false, 7996, -1, 7996, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3645, false, 7997, -1, 7997, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3648, false, 7998, -1, 7998, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3651, false, 7999, -1, 7999, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3654, false, -1, 7984, -1, 12780, -1, false, false, false, false, utf8proc_sequences + 3657}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3659, false, -1, 7985, -1, 12840, -1, false, false, false, false, utf8proc_sequences + 3662}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3664, false, -1, 7986, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3667}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3669, false, -1, 7987, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3672}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3674, false, -1, 7988, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3677}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3679, false, -1, 7989, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3682}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3684, false, -1, 7990, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3687}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3689, false, -1, 7991, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3692}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3694, false, 8008, -1, 8008, 12900, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3697, false, 8009, -1, 8009, 12960, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3700, false, 8010, -1, 8010, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3703, false, 8011, -1, 8011, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3706, false, 8012, -1, 8012, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3709, false, 8013, -1, 8013, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3712, false, -1, 8000, -1, 13020, -1, false, false, false, false, utf8proc_sequences + 3715}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3717, false, -1, 8001, -1, 13080, -1, false, false, false, false, utf8proc_sequences + 3720}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3722, false, -1, 8002, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3725}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3727, false, -1, 8003, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3730}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3732, false, -1, 8004, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3735}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3737, false, -1, 8005, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3740}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3742, false, -1, -1, -1, 13140, -1, false, false, false, false, utf8proc_sequences + 3742}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3745, false, 8025, -1, 8025, 13200, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3748, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3751}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3755, false, 8027, -1, 8027, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3758, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3761}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3765, false, 8029, -1, 8029, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3768, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3771}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3775, false, 8031, -1, 8031, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3778, false, -1, 8017, -1, 13260, -1, false, false, false, false, utf8proc_sequences + 3781}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3783, false, -1, 8019, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3786}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3788, false, -1, 8021, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3791}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3793, false, -1, 8023, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3796}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3798, false, 8040, -1, 8040, 13320, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3801, false, 8041, -1, 8041, 13380, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3804, false, 8042, -1, 8042, 15000, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3807, false, 8043, -1, 8043, 15060, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3810, false, 8044, -1, 8044, 15120, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3813, false, 8045, -1, 8045, 15180, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3816, false, 8046, -1, 8046, 15240, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3819, false, 8047, -1, 8047, 15300, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3822, false, -1, 8032, -1, 13440, -1, false, false, false, false, utf8proc_sequences + 3825}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3827, false, -1, 8033, -1, 13500, -1, false, false, false, false, utf8proc_sequences + 3830}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3832, false, -1, 8034, -1, 15360, -1, false, false, false, false, utf8proc_sequences + 3835}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3837, false, -1, 8035, -1, 15420, -1, false, false, false, false, utf8proc_sequences + 3840}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3842, false, -1, 8036, -1, 15480, -1, false, false, false, false, utf8proc_sequences + 3845}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3847, false, -1, 8037, -1, 15540, -1, false, false, false, false, utf8proc_sequences + 3850}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3852, false, -1, 8038, -1, 15600, -1, false, false, false, false, utf8proc_sequences + 3855}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3857, false, -1, 8039, -1, 15660, -1, false, false, false, false, utf8proc_sequences + 3860}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3862, false, 8122, -1, 8122, 15720, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1341, false, 8123, -1, 8123, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3865, false, 8136, -1, 8136, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1348, false, 8137, -1, 8137, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3868, false, 8138, -1, 8138, 15900, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1353, false, 8139, -1, 8139, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3871, false, 8154, -1, 8154, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1358, false, 8155, -1, 8155, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3874, false, 8184, -1, 8184, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1363, false, 8185, -1, 8185, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3877, false, 8170, -1, 8170, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1368, false, 8171, -1, 8171, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3880, false, 8186, -1, 8186, 16320, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1373, false, 8187, -1, 8187, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3883, false, 8072, -1, 8072, -1, -1, false, false, false, false, utf8proc_sequences + 3886}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3889, false, 8073, -1, 8073, -1, -1, false, false, false, false, utf8proc_sequences + 3892}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3895, false, 8074, -1, 8074, -1, -1, false, false, false, false, utf8proc_sequences + 3898}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3901, false, 8075, -1, 8075, -1, -1, false, false, false, false, utf8proc_sequences + 3904}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3907, false, 8076, -1, 8076, -1, -1, false, false, false, false, utf8proc_sequences + 3910}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3913, false, 8077, -1, 8077, -1, -1, false, false, false, false, utf8proc_sequences + 3916}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3919, false, 8078, -1, 8078, -1, -1, false, false, false, false, utf8proc_sequences + 3922}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3925, false, 8079, -1, 8079, -1, -1, false, false, false, false, utf8proc_sequences + 3928}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3931, false, -1, 8064, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3934}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3936, false, -1, 8065, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3939}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3941, false, -1, 8066, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3944}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3946, false, -1, 8067, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3949}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3951, false, -1, 8068, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3954}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3956, false, -1, 8069, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3959}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3961, false, -1, 8070, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3964}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3966, false, -1, 8071, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3969}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3971, false, 8088, -1, 8088, -1, -1, false, false, false, false, utf8proc_sequences + 3974}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3977, false, 8089, -1, 8089, -1, -1, false, false, false, false, utf8proc_sequences + 3980}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3983, false, 8090, -1, 8090, -1, -1, false, false, false, false, utf8proc_sequences + 3986}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3989, false, 8091, -1, 8091, -1, -1, false, false, false, false, utf8proc_sequences + 3992}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3995, false, 8092, -1, 8092, -1, -1, false, false, false, false, utf8proc_sequences + 3998}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4001, false, 8093, -1, 8093, -1, -1, false, false, false, false, utf8proc_sequences + 4004}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4007, false, 8094, -1, 8094, -1, -1, false, false, false, false, utf8proc_sequences + 4010}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4013, false, 8095, -1, 8095, -1, -1, false, false, false, false, utf8proc_sequences + 4016}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4019, false, -1, 8080, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4022}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4024, false, -1, 8081, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4027}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4029, false, -1, 8082, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4032}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4034, false, -1, 8083, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4037}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4039, false, -1, 8084, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4042}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4044, false, -1, 8085, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4047}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4049, false, -1, 8086, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4052}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4054, false, -1, 8087, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4057}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4059, false, 8104, -1, 8104, -1, -1, false, false, false, false, utf8proc_sequences + 4062}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4065, false, 8105, -1, 8105, -1, -1, false, false, false, false, utf8proc_sequences + 4068}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4071, false, 8106, -1, 8106, -1, -1, false, false, false, false, utf8proc_sequences + 4074}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4077, false, 8107, -1, 8107, -1, -1, false, false, false, false, utf8proc_sequences + 4080}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4083, false, 8108, -1, 8108, -1, -1, false, false, false, false, utf8proc_sequences + 4086}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4089, false, 8109, -1, 8109, -1, -1, false, false, false, false, utf8proc_sequences + 4092}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4095, false, 8110, -1, 8110, -1, -1, false, false, false, false, utf8proc_sequences + 4098}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4101, false, 8111, -1, 8111, -1, -1, false, false, false, false, utf8proc_sequences + 4104}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4107, false, -1, 8096, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4110}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4112, false, -1, 8097, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4115}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4117, false, -1, 8098, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4120}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4122, false, -1, 8099, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4125}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4127, false, -1, 8100, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4130}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4132, false, -1, 8101, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4135}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4137, false, -1, 8102, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4140}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4142, false, -1, 8103, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4145}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4147, false, 8120, -1, 8120, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4150, false, 8121, -1, 8121, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4153, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4156}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4159, false, 8124, -1, 8124, -1, -1, false, false, false, false, utf8proc_sequences + 4162}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4165, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4168}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4171, false, -1, -1, -1, 15840, -1, false, false, false, false, utf8proc_sequences + 4171}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4174, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4177}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4181, false, -1, 8112, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4184}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4186, false, -1, 8113, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4189}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4191, false, -1, 8048, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4194}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4196, false, -1, 8049, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4198}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4200, false, -1, 8115, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4203}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4205, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1326, false, 921, -1, 921, -1, -1, false, false, false, false, utf8proc_sequences + 1326}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4205, false, -1, -1, -1, 16080, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4208, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4211, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4214, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4217}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4220, false, 8140, -1, 8140, -1, -1, false, false, false, false, utf8proc_sequences + 4223}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4226, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4229}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4232, false, -1, -1, -1, 16020, -1, false, false, false, false, utf8proc_sequences + 4232}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4235, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4238}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4242, false, -1, 8050, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4245}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4247, false, -1, 8051, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4249}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4251, false, -1, 8052, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4254}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4256, false, -1, 8053, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4258}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4260, false, -1, 8131, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4263}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4265, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4268, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4271, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4274, false, 8152, -1, 8152, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4277, false, 8153, -1, 8153, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4280, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4283}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4287, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1378}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4289, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4289}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4292, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4295}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4299, false, -1, 8144, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4302}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4304, false, -1, 8145, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4307}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4309, false, -1, 8054, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4312}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4314, false, -1, 8055, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4316}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4318, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4321, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4324, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4327, false, 8168, -1, 8168, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4330, false, 8169, -1, 8169, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4333, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4336}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4340, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1451}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4342, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4342}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4345, false, 8172, -1, 8172, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4348, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4348}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4351, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4354}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4358, false, -1, 8160, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4361}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4363, false, -1, 8161, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4366}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4368, false, -1, 8058, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4371}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4373, false, -1, 8059, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4375}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4377, false, -1, 8165, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4380}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4387, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4389, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4392}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4395, false, 8188, -1, 8188, -1, -1, false, false, false, false, utf8proc_sequences + 4398}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4401, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4404}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4407, false, -1, -1, -1, 16440, -1, false, false, false, false, utf8proc_sequences + 4407}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4410, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4413}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4417, false, -1, 8056, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4420}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4422, false, -1, 8057, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4424}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4426, false, -1, 8060, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4429}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4431, false, -1, 8061, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4433}, + {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4435, false, -1, 8179, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4438}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4442, false, -1, -1, -1, 16140, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, utf8proc_sequences + 4445, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, utf8proc_sequences + 4447, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 52, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_NOBREAK, utf8proc_sequences + 52, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, true, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NOBREAK, utf8proc_sequences + 4449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4451, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4456, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4459, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ZL, 0, UTF8PROC_BIDI_CLASS_WS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL}, + {UTF8PROC_CATEGORY_ZP, 0, UTF8PROC_BIDI_CLASS_B, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRE, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLE, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_PDF, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRO, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLO, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4463, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4466, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4473, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4477, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4480, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_CS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4483, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4489, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4492, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 16, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4513, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4517, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4519, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 26, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4513, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4517, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4519, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 0, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 8, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 28, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 46, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4521, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4528, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4534, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4537, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4541, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4545, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4547, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 12, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 14, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 22, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2402, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4550, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2408, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4553, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4555, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4558, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4562, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4565, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4567, false, -1, 969, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1424}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2396, false, -1, 107, -1, -1, -1, false, false, false, false, utf8proc_sequences + 20}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4569, false, -1, 229, -1, -1, -1, false, false, false, false, utf8proc_sequences + 114}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4571, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 8526, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4573}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 28, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4577, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4579, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4581, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 16, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4583, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1408, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4589, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4591, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 6, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 18, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 8498, -1, 8498, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4593, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4597, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4601, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4605, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4609, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4613, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4617, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4621, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4625, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4629, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4633, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4637, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4641, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2392, false, -1, 8560, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4644}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4646, false, -1, 8561, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4649}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4651, false, -1, 8562, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4655}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4657, false, -1, 8563, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4660}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4662, false, -1, 8564, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4664}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4666, false, -1, 8565, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4669}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4671, false, -1, 8566, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4675}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4677, false, -1, 8567, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4682}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4684, false, -1, 8568, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4687}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4689, false, -1, 8569, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4691}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4693, false, -1, 8570, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4696}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4698, false, -1, 8571, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4702}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2398, false, -1, 8572, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4704}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4532, false, -1, 8573, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4706}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2382, false, -1, 8574, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4708}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2400, false, -1, 8575, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4710}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 16, false, 8544, -1, 8544, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4712, false, 8545, -1, 8545, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4715, false, 8546, -1, 8546, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4719, false, 8547, -1, 8547, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 42, false, 8548, -1, 8548, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4722, false, 8549, -1, 8549, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4725, false, 8550, -1, 8550, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4729, false, 8551, -1, 8551, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4734, false, 8552, -1, 8552, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 46, false, 8553, -1, 8553, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4737, false, 8554, -1, 8554, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4740, false, 8555, -1, 8555, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 22, false, 8556, -1, 8556, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4, false, 8557, -1, 8557, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6, false, 8558, -1, 8558, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 24, false, 8559, -1, 8559, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 8580, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4744}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 8579, -1, 8579, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16500, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16560, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16620, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4746, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4749, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4752, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4755, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4758, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4761, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16680, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16800, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16740, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 16860, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4764, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 16920, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4767, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 16980, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4770, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17040, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4773, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17100, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4776, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4779, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4782, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4786, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4789, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17160, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4793, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17220, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4796, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17280, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4799, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17340, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4802, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17520, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4805, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17460, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4808, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17700, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17760, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4811, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4814, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4817, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4820, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4823, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17820, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17880, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4826, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4829, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17940, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18000, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4832, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4835, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18060, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18120, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18660, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18720, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4838, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4841, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18180, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18240, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4844, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4847, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18300, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18360, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4850, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4853, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18780, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18840, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18420, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18480, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18540, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18600, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4856, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4859, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4862, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4865, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18900, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18960, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 19020, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 19080, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4868, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4871, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4874, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4877, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4880, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4883, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4886, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4889, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4892, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4894, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4896, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4905, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4911, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4917, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4929, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4933, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4937, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4941, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4949, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4957, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4970, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4975, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4990, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4995, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5005, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5010, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5015, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5051, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5055, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5063, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5067, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5075, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5111, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5151, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5159, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5163, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5171, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5175, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5183, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5187, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2376, false, -1, 9424, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5195}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2380, false, -1, 9425, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5197}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4532, false, -1, 9426, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5199}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2382, false, -1, 9427, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5201}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2384, false, -1, 9428, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5203}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4571, false, -1, 9429, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5205}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2388, false, -1, 9430, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5207}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2390, false, -1, 9431, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5209}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2392, false, -1, 9432, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5211}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2394, false, -1, 9433, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5213}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2396, false, -1, 9434, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5215}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2398, false, -1, 9435, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5217}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2400, false, -1, 9436, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5219}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2402, false, -1, 9437, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5221}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2404, false, -1, 9438, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5223}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2408, false, -1, 9439, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5225}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4553, false, -1, 9440, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5227}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2410, false, -1, 9441, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5229}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5231, false, -1, 9442, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5233}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2412, false, -1, 9443, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5235}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2414, false, -1, 9444, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5237}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4662, false, -1, 9445, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5239}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2416, false, -1, 9446, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5241}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4689, false, -1, 9447, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5243}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5245, false, -1, 9448, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5247}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4565, false, -1, 9449, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5249}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 0, false, 9398, -1, 9398, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2, false, 9399, -1, 9399, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4, false, 9400, -1, 9400, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6, false, 9401, -1, 9401, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 8, false, 9402, -1, 9402, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 10, false, 9403, -1, 9403, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 12, false, 9404, -1, 9404, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 14, false, 9405, -1, 9405, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 16, false, 9406, -1, 9406, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 18, false, 9407, -1, 9407, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 20, false, 9408, -1, 9408, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 22, false, 9409, -1, 9409, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 24, false, 9410, -1, 9410, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 26, false, 9411, -1, 9411, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 28, false, 9412, -1, 9412, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 30, false, 9413, -1, 9413, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 32, false, 9414, -1, 9414, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 34, false, 9415, -1, 9415, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 36, false, 9416, -1, 9416, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 38, false, 9417, -1, 9417, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 40, false, 9418, -1, 9418, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 42, false, 9419, -1, 9419, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 44, false, 9420, -1, 9420, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 46, false, 9421, -1, 9421, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 48, false, 9422, -1, 9422, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 50, false, 9423, -1, 9423, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5251, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5256, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 5267, true, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 19140, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11312, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5270}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11313, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5272}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11314, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5274}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11315, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5276}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11316, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5278}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11317, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5280}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11318, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5282}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11319, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5284}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11320, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5286}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11321, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5288}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11322, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5290}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11323, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5292}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11324, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5294}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11325, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5296}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11326, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5298}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11327, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5300}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11328, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5302}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11329, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5304}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11330, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5306}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11331, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5308}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11332, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5310}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11333, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5312}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11334, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5314}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11335, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5316}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11336, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5318}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11337, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5320}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11338, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5322}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11339, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5324}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11340, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5326}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11341, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5328}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11342, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5330}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11343, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5332}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11344, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5334}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11345, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5336}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11346, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5338}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11347, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5340}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11348, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5342}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11349, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5344}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11350, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5346}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11351, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5348}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11352, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5350}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11353, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5352}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11354, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5354}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11355, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5356}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11356, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5358}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11357, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5360}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11358, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5362}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11264, -1, 11264, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11265, -1, 11265, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11266, -1, 11266, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11267, -1, 11267, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11268, -1, 11268, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11269, -1, 11269, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11270, -1, 11270, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11271, -1, 11271, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11272, -1, 11272, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11273, -1, 11273, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11274, -1, 11274, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11275, -1, 11275, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11276, -1, 11276, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11277, -1, 11277, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11278, -1, 11278, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11279, -1, 11279, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11280, -1, 11280, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11281, -1, 11281, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11282, -1, 11282, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11283, -1, 11283, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11284, -1, 11284, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11285, -1, 11285, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11286, -1, 11286, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11287, -1, 11287, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11288, -1, 11288, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11289, -1, 11289, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11290, -1, 11290, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11291, -1, 11291, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11292, -1, 11292, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11293, -1, 11293, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11294, -1, 11294, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11295, -1, 11295, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11296, -1, 11296, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11297, -1, 11297, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11298, -1, 11298, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11299, -1, 11299, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11300, -1, 11300, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11301, -1, 11301, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11302, -1, 11302, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11303, -1, 11303, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11304, -1, 11304, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11305, -1, 11305, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11306, -1, 11306, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11307, -1, 11307, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11308, -1, 11308, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11309, -1, 11309, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11310, -1, 11310, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11361, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5364}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11360, -1, 11360, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 619, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5366}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 7549, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5368}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 637, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5370}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 570, -1, 570, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 574, -1, 574, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11368, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5372}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11367, -1, 11367, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11370, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5374}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11369, -1, 11369, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11372, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5376}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11371, -1, 11371, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11382, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5378}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11381, -1, 11381, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11393, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5380}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11392, -1, 11392, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11395, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5382}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11394, -1, 11394, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11397, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5384}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11396, -1, 11396, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11399, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5386}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11398, -1, 11398, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11401, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5388}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11400, -1, 11400, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11403, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5390}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11402, -1, 11402, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11405, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5392}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11404, -1, 11404, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11407, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5394}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11406, -1, 11406, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11409, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5396}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11408, -1, 11408, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11411, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5398}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11410, -1, 11410, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11413, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5400}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11412, -1, 11412, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11415, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5402}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11414, -1, 11414, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11417, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5404}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11416, -1, 11416, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11419, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5406}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11418, -1, 11418, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11421, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5408}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11420, -1, 11420, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11423, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5410}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11422, -1, 11422, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11425, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5412}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11424, -1, 11424, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11427, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5414}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11426, -1, 11426, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11429, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5416}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11428, -1, 11428, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11431, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5418}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11430, -1, 11430, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11433, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5420}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11432, -1, 11432, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11435, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5422}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11434, -1, 11434, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11437, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5424}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11436, -1, 11436, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11439, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5426}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11438, -1, 11438, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11441, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5428}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11440, -1, 11440, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11443, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5430}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11442, -1, 11442, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11445, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5432}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11444, -1, 11444, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11447, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5434}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11446, -1, 11446, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11449, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5436}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11448, -1, 11448, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11451, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5438}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11450, -1, 11450, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11453, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5440}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11452, -1, 11452, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11455, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5442}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11454, -1, 11454, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11457, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5444}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11456, -1, 11456, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11459, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5446}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11458, -1, 11458, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11461, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5448}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11460, -1, 11460, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11463, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5450}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11462, -1, 11462, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11465, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5452}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11464, -1, 11464, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11467, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5454}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11466, -1, 11466, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11469, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5456}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11468, -1, 11468, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11471, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5458}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11470, -1, 11470, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11473, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5460}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11472, -1, 11472, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11475, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5462}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11474, -1, 11474, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11477, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5464}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11476, -1, 11476, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11479, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5466}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11478, -1, 11478, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11481, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5468}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11480, -1, 11480, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11483, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5470}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11482, -1, 11482, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11485, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5472}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11484, -1, 11484, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11487, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5474}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11486, -1, 11486, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11489, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5476}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11488, -1, 11488, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11491, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5478}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11490, -1, 11490, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4256, -1, 4256, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4257, -1, 4257, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4258, -1, 4258, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4259, -1, 4259, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4260, -1, 4260, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4261, -1, 4261, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4262, -1, 4262, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4263, -1, 4263, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4264, -1, 4264, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4265, -1, 4265, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4266, -1, 4266, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4267, -1, 4267, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4268, -1, 4268, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4269, -1, 4269, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4270, -1, 4270, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4271, -1, 4271, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4272, -1, 4272, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4273, -1, 4273, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4274, -1, 4274, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4275, -1, 4275, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4276, -1, 4276, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4277, -1, 4277, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4278, -1, 4278, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4279, -1, 4279, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4280, -1, 4280, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4281, -1, 4281, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4282, -1, 4282, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4283, -1, 4283, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4284, -1, 4284, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4285, -1, 4285, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4286, -1, 4286, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4287, -1, 4287, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4288, -1, 4288, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4289, -1, 4289, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4290, -1, 4290, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4291, -1, 4291, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4292, -1, 4292, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4293, -1, 4293, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5480, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5484, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5490, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5492, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5496, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5498, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5504, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5506, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5510, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5512, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5514, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5516, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5518, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5520, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5522, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5526, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5528, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5530, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5534, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5536, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5538, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5540, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5542, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5544, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5546, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5548, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5550, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5552, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5554, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5556, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5558, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5562, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5564, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5566, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5568, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5570, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5572, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5574, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5576, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5578, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5580, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5582, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5584, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5586, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5588, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5590, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5592, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5594, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5596, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5598, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5600, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5602, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5604, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5606, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5608, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5610, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5612, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5614, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5616, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5618, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5620, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5622, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5624, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5626, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5628, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5630, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5632, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5634, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5636, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5638, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5640, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5642, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5644, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5646, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5648, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5650, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5652, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5654, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5656, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5658, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5660, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5662, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5664, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5666, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5668, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5670, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5672, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5674, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5676, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5678, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5680, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5682, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5684, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5686, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5688, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5690, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5692, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5694, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5696, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5698, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5700, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5702, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5704, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5706, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5708, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5710, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5712, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5714, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5716, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5718, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5720, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5722, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5724, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5726, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5728, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5730, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5732, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5734, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5736, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5738, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5740, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5742, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5744, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5746, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5748, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5750, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5752, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5754, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5756, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5758, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5760, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5762, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5764, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5766, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5768, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5770, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5772, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5774, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5776, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5778, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5780, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5782, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5784, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5786, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5790, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5794, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5796, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5798, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5802, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5804, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5806, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5808, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5810, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5812, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5814, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5816, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5820, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5822, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5824, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5826, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5828, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5832, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5834, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5836, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5838, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5840, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5842, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5844, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5846, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5848, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5850, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5852, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5854, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5856, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5858, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5860, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5862, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5864, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5866, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5868, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5870, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5872, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5874, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5876, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5878, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5880, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5882, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5884, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5886, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5888, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5890, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5894, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5896, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5898, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5900, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 52, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 218, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 224, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20400, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19200, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19260, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19320, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19380, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5929, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19440, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5932, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19500, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5935, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19560, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5938, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19620, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5941, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19680, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19740, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5947, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19800, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19860, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19920, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19980, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20040, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20100, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5968, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20160, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5971, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5974, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20220, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5977, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20280, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5986, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20340, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5989, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5992, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5995, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 8, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 52, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MN, 8, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 53, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5998, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6001, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20460, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6004, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 6007, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21720, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20520, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6010, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20580, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6013, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20640, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6016, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20700, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6019, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20760, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6022, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20820, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6025, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20880, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6028, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20940, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6031, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21000, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6034, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21060, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6037, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21120, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6040, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21180, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6043, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21240, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6046, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21300, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6049, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21360, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6052, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21420, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6055, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6058, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21480, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6061, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6064, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21540, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6067, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6070, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21600, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6073, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6076, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21660, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6082, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21780, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21840, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21900, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21960, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6085, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6088, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6094, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22020, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6100, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 6103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6106, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6108, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6112, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6114, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6116, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6118, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6120, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6124, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6126, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6130, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6132, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6136, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6138, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6142, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6144, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6148, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6154, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6160, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6162, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6166, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6168, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6172, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6174, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6178, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6180, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6184, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6186, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6190, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6192, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6196, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6198, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6202, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6204, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6208, false, -1, -1, -1, -1, -1, false, true, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6210, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6212, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6214, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6216, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6218, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6220, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6222, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6224, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6226, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6228, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6230, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6232, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6234, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6236, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6238, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6240, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6242, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6244, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6246, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6250, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6252, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6254, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6256, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6258, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6262, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6264, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6266, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6268, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6270, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6274, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6276, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6278, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6280, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6282, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6284, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6286, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6288, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6290, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6292, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5498, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6294, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6296, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6298, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6302, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6304, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6306, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6308, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6310, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6312, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6314, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6318, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6322, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6326, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6330, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6334, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6338, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6342, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6346, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6350, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6354, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6358, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6362, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6366, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6370, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6375, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6395, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6405, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6415, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6430, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6435, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6445, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6453, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6460, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6468, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6480, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6484, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6492, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6496, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6504, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6512, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6516, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6520, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6528, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6536, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6540, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6544, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6548, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6552, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6556, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6564, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6568, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6572, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6576, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6580, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6584, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6588, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6592, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6596, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6600, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6604, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6608, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6614, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6617, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6620, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6623, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6626, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6629, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6632, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6638, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6641, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6644, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6647, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6650, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6106, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6112, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6118, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6138, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6160, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6162, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6653, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6656, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6659, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6662, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6665, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6668, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6671, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6674, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6677, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6680, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6683, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6686, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6689, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6692, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6695, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6701, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6706, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5498, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6294, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6296, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6709, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6711, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6713, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6715, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5632, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5656, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5654, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5634, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5548, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5628, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6717, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6719, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6721, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6723, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6725, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6727, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6729, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6731, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6733, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6737, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6739, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6741, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6743, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6745, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6747, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6749, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6751, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6298, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6302, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6753, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6755, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6757, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6759, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6761, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6763, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6765, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6767, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6769, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6771, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6773, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6776, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6779, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6782, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6785, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6791, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6794, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6797, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6803, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6806, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6809, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6812, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6815, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6821, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6824, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6827, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6833, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6836, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6839, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6842, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6845, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6849, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6853, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6857, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6860, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6864, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6867, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6871, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6873, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6875, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6877, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6879, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6881, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6883, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6885, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6887, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6889, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6891, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6893, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6895, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6897, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6901, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6903, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6905, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6907, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6909, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6911, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6913, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6915, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6917, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6919, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6921, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6925, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6927, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6929, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6931, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6933, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6935, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6937, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6939, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6941, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6943, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6947, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6949, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6951, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6955, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6957, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6970, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6975, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6984, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6989, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6993, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7008, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7012, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7016, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7025, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7030, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7034, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7045, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7055, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7058, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7064, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7081, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7093, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7102, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7106, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7126, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7130, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7138, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7144, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7154, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7168, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7183, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7186, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7189, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7195, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7210, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7216, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7219, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7223, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7227, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7231, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7235, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7244, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7255, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7259, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7268, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7276, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7280, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7286, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7294, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7308, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7313, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7317, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7321, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7325, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7330, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7337, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7342, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7345, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7351, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7355, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7358, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7361, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7364, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7367, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7370, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7373, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7376, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7379, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7389, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7393, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7397, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7405, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7409, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7413, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7417, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7421, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7429, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7433, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7437, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7441, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7445, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7455, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7459, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7462, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7465, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7468, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7491, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7496, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7514, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7517, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7520, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7529, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7535, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7538, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7541, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7544, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7547, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7550, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7554, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7558, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7562, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7566, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7569, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7572, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7578, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7581, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7584, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7590, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7593, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7596, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7600, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7604, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7607, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7615, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7619, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7622, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7626, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7630, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7638, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7642, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7646, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7650, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7654, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7660, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7667, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7670, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7673, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7676, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7679, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7682, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7685, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7688, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7691, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7694, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7697, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7700, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7703, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7706, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7709, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7712, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7715, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7718, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7721, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7726, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7729, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7732, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7740, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7744, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7747, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7750, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7753, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7756, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7759, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7762, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7765, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7768, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7771, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7774, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7778, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7781, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7784, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7795, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7804, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7807, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7810, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7813, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7816, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7820, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7824, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7827, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7833, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7836, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7839, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7842, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7845, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7848, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7851, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7855, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7859, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7863, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7867, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7871, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7875, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7879, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7883, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7887, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7891, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7895, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7903, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7907, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7911, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7915, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7919, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7927, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7931, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7935, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7939, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_CS, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, true, false, false, NULL}, + {UTF8PROC_CATEGORY_CO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7943, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5802, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7947, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7949, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7951, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7955, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7957, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7967, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7969, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7971, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7973, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7975, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7977, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7979, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7981, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7987, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7989, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7991, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7993, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7995, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7999, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8001, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8005, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8007, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8009, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8011, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8013, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8015, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8019, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8021, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8025, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8027, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8031, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8033, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8037, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5734, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8039, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8043, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8045, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8049, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8051, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8055, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8057, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5880, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8061, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8063, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8067, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8069, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8073, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8075, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8081, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8085, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8093, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8105, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8109, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8111, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8149, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8151, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8153, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5806, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8157, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8159, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8163, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8165, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8169, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8171, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8175, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8177, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8181, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8183, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8187, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8189, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8193, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8195, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8197, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8199, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5522, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8201, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8205, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8207, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8209, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8211, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8213, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8215, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8217, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8219, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8223, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8225, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8227, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8229, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8231, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8233, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8235, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8237, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8241, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8243, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8247, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8249, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8253, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8255, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8257, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8259, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8261, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8265, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8267, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8271, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8273, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8277, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8279, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8281, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8283, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8285, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8287, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8289, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8293, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8295, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8297, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8299, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8301, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8305, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8307, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8309, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8311, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8313, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8315, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8317, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8319, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8321, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8323, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8325, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8327, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8329, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8331, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6711, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8335, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8337, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8339, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8341, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8343, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8345, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8347, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8349, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8351, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8353, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8355, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8357, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8359, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8361, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8363, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8365, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8367, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8369, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8371, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8373, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8375, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5816, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8377, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8379, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8381, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8383, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8387, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8389, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8391, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8393, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8395, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8397, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8399, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5718, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8403, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8405, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8407, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8409, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8411, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8413, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8415, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8417, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8419, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8421, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8423, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8427, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8429, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8431, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8433, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5772, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8435, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5778, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8437, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8439, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8441, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8443, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8445, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8447, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8451, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8453, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8455, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8457, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8459, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8461, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8463, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5732, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8465, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8467, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8469, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8471, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8473, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8475, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8477, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8481, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8483, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8487, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8489, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8491, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8493, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8495, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5574, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8513, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8517, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8519, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8521, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8523, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8525, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8527, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8529, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8531, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8533, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6721, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8535, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8537, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8539, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8541, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6729, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8543, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8545, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8547, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8549, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8551, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8553, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8555, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8557, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8559, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8561, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8563, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8565, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8567, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8569, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8571, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8573, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8577, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8579, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8581, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8583, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8585, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8589, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8591, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8593, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8595, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8597, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8599, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8601, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8603, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8605, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8607, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8609, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8613, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8615, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8617, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8619, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8621, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8623, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8625, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8627, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8629, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8631, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8633, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8637, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8639, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8641, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8643, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8645, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8647, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5640, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8649, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8651, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8653, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8655, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8657, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8659, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8661, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8663, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8665, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8667, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8669, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8671, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8673, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8675, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8677, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8679, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8681, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8683, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8685, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8687, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8689, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8691, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8693, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8695, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8697, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8699, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8701, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8703, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8705, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8707, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8709, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8711, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8713, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8715, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8717, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8719, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8721, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8723, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8725, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8727, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8729, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8731, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8733, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8737, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8739, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8741, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8743, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8745, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8745}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8748, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8748}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8751, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8751}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8754, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8754}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8758, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8758}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8762, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8765}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8765, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8765}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8768, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8768}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8771, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8771}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8774, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8774}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8777, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8777}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8780, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8780}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8783, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MN, 26, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8786, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8789, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4581, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8791, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8793, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8795, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8797, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8799, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8801, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8803, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8806, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8809, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8812, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8815, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8818, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8821, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8824, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8827, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8830, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8833, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8836, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8839, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8842, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8845, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8848, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8851, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8854, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8857, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8860, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8863, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8866, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8869, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8872, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8875, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8878, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8881, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8884, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8887, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8890, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8893, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8896, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8928, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8928, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8930, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8930, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8932, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8932, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8934, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8934, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8936, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8936, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8938, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8938, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8948, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8948, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8952, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8952, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8958, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8958, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8960, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8960, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8964, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8964, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8966, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8966, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8968, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8968, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8970, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8972, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8972, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8974, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8974, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8976, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8976, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8982, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8982, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8988, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8988, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8991, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8991, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8994, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8994, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9008, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9011, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9056, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9068, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9074, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9080, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9086, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9104, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9116, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9149, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9197, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9209, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9212, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9215, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9218, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9224, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9227, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9230, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9233, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9236, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9242, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9254, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9257, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9266, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9278, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9281, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9284, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9287, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9295, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9299, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9307, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9311, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9314, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9317, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9320, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9323, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9326, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9329, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9332, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9335, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9338, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9341, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9344, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9209, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9347, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9350, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9353, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9356, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9242, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9284, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9359, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9362, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9365, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9008, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9011, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9368, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9371, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9374, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9377, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9068, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9074, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9080, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9086, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9104, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9116, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9149, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9197, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9383, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9212, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9215, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9218, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9230, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9233, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9236, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9389, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9266, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9371, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9374, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9377, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9395, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9407, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9411, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9415, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9419, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9428, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9431, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9434, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9437, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9443, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9446, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9455, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9458, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9461, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9467, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9473, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9491, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9419, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9428, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9431, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9434, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9437, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9443, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9446, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9455, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9458, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9461, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9467, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9473, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9491, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9519, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9523, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9527, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9531, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9531, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9535, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9539, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9543, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9547, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9551, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9555, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9555, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9559, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9563, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9563, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9567, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9567, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9571, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9579, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9583, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9583, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9591, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9595, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9595, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9599, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9599, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9603, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9607, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9615, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9615, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9619, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9623, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9627, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9631, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9639, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9643, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9647, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9651, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9655, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9659, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9659, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9663, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9663, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9667, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9667, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9671, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9675, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9679, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9683, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9687, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9691, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9695, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9699, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9703, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9707, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9711, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9715, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9719, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9719, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9723, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9727, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9731, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9739, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9743, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9747, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9751, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9755, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9759, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9763, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9767, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9771, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9775, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9779, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9783, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9787, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9791, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9795, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9799, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9803, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9807, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9811, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9815, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9819, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9823, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9639, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9647, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9827, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9831, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9835, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9839, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9843, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9847, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9843, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9835, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9851, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9855, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9859, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9863, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9867, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9847, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9571, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9871, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9875, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9879, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9883, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9887, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9897, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9907, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9917, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 1333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9967, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9969, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9971, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9973, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9975, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9977, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9979, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9981, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 4517, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 4519, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9987, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9989, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9991, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9993, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9995, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9999, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 4892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 4894, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10001, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10005, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10007, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10009, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10011, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 10013, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 9983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 1333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9969, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9967, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9979, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4517, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4519, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9985, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9987, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9989, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9991, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10015, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10019, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10021, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10023, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10025, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10027, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10031, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10033, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10056, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10068, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10074, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10081, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10081, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10085, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10085, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10093, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10093, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10105, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10105, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10109, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10109, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10111, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10111, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10153, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10153, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9967, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10159, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10015, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10031, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4517, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4519, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10019, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10021, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10163, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 1333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10023, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10025, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9969, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10033, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2376, false, -1, 65345, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10165}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2380, false, -1, 65346, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10167}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4532, false, -1, 65347, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10169}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2382, false, -1, 65348, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10171}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2384, false, -1, 65349, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10173}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4571, false, -1, 65350, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10175}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2388, false, -1, 65351, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10177}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2390, false, -1, 65352, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10179}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2392, false, -1, 65353, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10181}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2394, false, -1, 65354, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10183}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2396, false, -1, 65355, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10185}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2398, false, -1, 65356, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10187}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2400, false, -1, 65357, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10189}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2402, false, -1, 65358, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10191}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2404, false, -1, 65359, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10193}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2408, false, -1, 65360, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10195}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4553, false, -1, 65361, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10197}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2410, false, -1, 65362, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10199}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 5231, false, -1, 65363, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10201}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2412, false, -1, 65364, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10203}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2414, false, -1, 65365, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10205}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4662, false, -1, 65366, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10207}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2416, false, -1, 65367, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10209}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4689, false, -1, 65368, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10211}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 5245, false, -1, 65369, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10213}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4565, false, -1, 65370, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10215}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10009, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10027, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10011, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10217, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4387, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 0, false, 65313, -1, 65313, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2, false, 65314, -1, 65314, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4, false, 65315, -1, 65315, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 6, false, 65316, -1, 65316, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 8, false, 65317, -1, 65317, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10, false, 65318, -1, 65318, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 12, false, 65319, -1, 65319, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 14, false, 65320, -1, 65320, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 16, false, 65321, -1, 65321, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 18, false, 65322, -1, 65322, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 20, false, 65323, -1, 65323, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 22, false, 65324, -1, 65324, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 24, false, 65325, -1, 65325, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 26, false, 65326, -1, 65326, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 28, false, 65327, -1, 65327, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 30, false, 65328, -1, 65328, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 32, false, 65329, -1, 65329, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 34, false, 65330, -1, 65330, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 36, false, 65331, -1, 65331, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 38, false, 65332, -1, 65332, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 40, false, 65333, -1, 65333, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 42, false, 65334, -1, 65334, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 44, false, 65335, -1, 65335, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 46, false, 65336, -1, 65336, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 48, false, 65337, -1, 65337, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 50, false, 65338, -1, 65338, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9985, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10219, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9987, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10223, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10225, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 9963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10001, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10003, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 9961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10227, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10229, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10231, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10233, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10235, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10237, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10241, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10243, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10247, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6871, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6873, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6875, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6877, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6879, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6881, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6883, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6885, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6887, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6889, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6891, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6893, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6895, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6897, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6901, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6903, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6905, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6907, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6909, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6911, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6913, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6915, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6917, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6919, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6921, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6925, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6927, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6929, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6931, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6933, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6935, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6937, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6939, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6941, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6943, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6947, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6949, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6951, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6955, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6957, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10249, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10253, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10255, false, -1, -1, -1, -1, -1, false, true, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10257, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10259, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10261, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10265, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10267, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10271, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10273, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10277, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10279, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10281, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10283, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10285, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10287, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10289, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10293, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10295, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10297, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10299, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10301, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10305, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10307, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10309, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10311, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10313, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10315, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10317, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10319, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10321, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10323, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10325, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10327, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10329, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10331, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10335, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10337, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10339, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10341, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10343, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10345, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10347, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10349, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10351, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10353, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10355, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10357, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10359, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10361, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10363, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10365, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10367, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10369, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10371, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10373, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10375, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10377, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10379, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10381, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10383, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL}, + {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66600, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10387}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66601, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10389}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66602, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10391}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66603, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10393}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66604, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10395}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66605, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10397}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66606, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10399}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66607, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10401}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66608, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10403}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66609, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10405}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66610, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10407}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66611, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10409}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66612, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10411}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66613, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10413}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66614, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10415}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66615, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10417}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66616, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10419}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66617, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10421}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66618, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10423}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66619, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10425}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66620, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10427}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66621, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10429}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66622, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10431}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66623, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10433}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66624, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10435}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66625, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10437}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66626, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10439}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66627, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10441}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66628, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10443}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66629, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10445}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66630, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10447}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66631, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10449}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66632, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10451}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66633, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10453}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66634, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10455}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66635, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10457}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66636, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10459}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66637, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10461}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66638, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10463}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66639, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10465}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66560, -1, 66560, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66561, -1, 66561, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66562, -1, 66562, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66563, -1, 66563, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66564, -1, 66564, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66565, -1, 66565, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66566, -1, 66566, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66567, -1, 66567, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66568, -1, 66568, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66569, -1, 66569, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66570, -1, 66570, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66571, -1, 66571, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66572, -1, 66572, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66573, -1, 66573, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66574, -1, 66574, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66575, -1, 66575, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66576, -1, 66576, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66577, -1, 66577, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66578, -1, 66578, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66579, -1, 66579, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66580, -1, 66580, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66581, -1, 66581, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66582, -1, 66582, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66583, -1, 66583, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66584, -1, 66584, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66585, -1, 66585, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66586, -1, 66586, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66587, -1, 66587, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66588, -1, 66588, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66589, -1, 66589, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66590, -1, 66590, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66591, -1, 66591, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66592, -1, 66592, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66593, -1, 66593, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66594, -1, 66594, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66595, -1, 66595, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66596, -1, 66596, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66597, -1, 66597, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66598, -1, 66598, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66599, -1, 66599, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22080, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22140, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10467, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10470, false, -1, -1, -1, 22200, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10473, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10476, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10479, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10482, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10485, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 54, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 226, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 55, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 56, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 57, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 58, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 59, false, false, false, true, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22260, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22320, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10488, false, -1, -1, -1, 22380, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10491, false, -1, -1, -1, 22440, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10494, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10497, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10500, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10503, false, -1, -1, -1, -1, -1, true, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2376, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2394, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 5231, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2412, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2414, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4662, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2416, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4689, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 5245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 0, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 20, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 24, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 26, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 30, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 32, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 34, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 36, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 38, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 40, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 42, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 44, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 46, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 48, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 50, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10506, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10510, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10512, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10514, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10516, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10518, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10520, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1504, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10522, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10526, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10528, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10530, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10534, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10536, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10538, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10540, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10542, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10544, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10546, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4567, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10548, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1394, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1326, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 67, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1402, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1406, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1412, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1414, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1416, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1424, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10550, true, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10552, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10554, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10556, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10558, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10562, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10564, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10566, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10568, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10570, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10572, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10574, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10576, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10578, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10580, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10582, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10584, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10586, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10588, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10590, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10592, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10594, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10596, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10598, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10600, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10602, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10604, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10606, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10608, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10610, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10612, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10614, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5518, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10616, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10618, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10620, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10622, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10624, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10626, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10628, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10630, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10632, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10634, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10636, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10638, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10640, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10642, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10644, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10646, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10648, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10650, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10652, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10654, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10656, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10658, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10660, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10662, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10664, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10666, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10668, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10670, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10672, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10674, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10676, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10678, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10680, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10682, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10684, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10686, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10688, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10690, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10692, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10694, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10696, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10698, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10700, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10702, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10704, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10706, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10708, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10710, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10712, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10714, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10716, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10718, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10720, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10722, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10724, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10726, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10728, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10730, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10732, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10734, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10736, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10738, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10740, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10742, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10744, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10746, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10748, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10750, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10752, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10754, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10756, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10758, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10760, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5570, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10762, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10764, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10766, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10768, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10770, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10772, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10774, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10776, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10778, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10780, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10782, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10784, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10786, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10790, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10794, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10796, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10798, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10802, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10804, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10806, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10808, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5594, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10810, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10812, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10814, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10816, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10820, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10822, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10824, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10826, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10828, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10832, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10834, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10836, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10838, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10840, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10842, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10844, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10846, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10848, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10850, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10852, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10854, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10856, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10858, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10860, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10862, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10864, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10866, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10868, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10870, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10872, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10874, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10876, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10878, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10880, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10882, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10884, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10886, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10888, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10890, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10894, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10896, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10898, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10900, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10928, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10930, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10932, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10934, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10936, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10938, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10948, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10952, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10958, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10960, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10964, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10966, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10968, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10970, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10972, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10974, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10976, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10982, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10984, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10986, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10988, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10990, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10992, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10994, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10996, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10998, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11002, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11004, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11008, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11010, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11012, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11016, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11018, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11022, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11024, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11028, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11030, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11034, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11036, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11040, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11042, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11046, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11048, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11052, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11054, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11056, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11058, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11060, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11064, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11066, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11068, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11070, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11072, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11074, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11076, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11078, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11080, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11082, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11084, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11086, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11088, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11090, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11094, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11096, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11100, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11102, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11104, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11106, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11108, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11112, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11114, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11116, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11118, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11120, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11124, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11126, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11130, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11132, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11136, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11138, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11142, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11144, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11148, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11154, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11160, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11162, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11166, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11168, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11172, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11174, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11178, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11180, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11184, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11186, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11190, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11192, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11196, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11198, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11202, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11204, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11208, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11210, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11212, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11214, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11216, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11218, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11220, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11222, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11224, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11226, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11228, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11230, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11232, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11234, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11236, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11238, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11240, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11242, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11244, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11246, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11250, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11252, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11254, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11256, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11258, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11262, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11264, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11266, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11268, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11270, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11274, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11276, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11278, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11280, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11282, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11284, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11286, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11288, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11290, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11292, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11294, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11296, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11298, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11302, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11304, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11306, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11308, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11310, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11312, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11314, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11316, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11318, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11320, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11322, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11324, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11326, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11328, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11330, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11332, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11334, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11336, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11338, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11340, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11342, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11344, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5774, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11346, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11348, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11350, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11352, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11354, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11356, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11358, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11360, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11362, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11364, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11366, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11368, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11370, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11372, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11374, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11376, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11378, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11394, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11402, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11406, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11408, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11412, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11414, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11416, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11424, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11426, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11428, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11430, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11432, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11434, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11436, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11438, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11442, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11444, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11446, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11448, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11450, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11456, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11458, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11460, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11462, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11466, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11468, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11474, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11478, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11480, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11484, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11490, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5884, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11492, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11496, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11498, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, + {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL}, +}; + +const int32_t utf8proc_combinations[] = { + 192, 193, 194, 195, 196, 197, -1, + 256, 258, 260, 550, 461, -1, -1, 512, + 514, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7680, 7840, -1, -1, -1, -1, -1, 7842, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 262, 264, + -1, -1, -1, 199, -1, -1, -1, 266, + 268, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 200, 201, 202, 7868, 203, -1, 552, + 274, 276, 280, 278, 282, -1, -1, 516, + 518, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7864, -1, 7704, 7706, -1, -1, 7866, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 204, 205, 206, + 296, 207, -1, -1, 298, 300, 302, 304, + 463, -1, -1, 520, 522, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7882, -1, -1, + 7724, -1, -1, 7880, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 504, 323, -1, 209, -1, -1, 325, + -1, -1, -1, 7748, 327, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7750, 7752, 7754, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 210, 211, 212, + 213, 214, -1, -1, 332, 334, 490, 558, + 465, 336, 416, 524, 526, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7884, -1, -1, + -1, -1, -1, 7886, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 217, 218, 219, 360, 220, 366, -1, + 362, 364, 370, -1, 467, 368, 431, 532, + 534, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7908, -1, 7798, 7796, -1, 7794, 7910, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7922, 221, 374, + 7928, 376, -1, -1, 562, -1, -1, 7822, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7924, -1, -1, + -1, -1, -1, 7926, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 224, 225, 226, 227, 228, 229, -1, + 257, 259, 261, 551, 462, -1, -1, 513, + 515, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7681, 7841, -1, -1, -1, -1, -1, 7843, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 263, 265, + -1, -1, -1, 231, -1, -1, -1, 267, + 269, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 232, 233, 234, 7869, 235, -1, 553, + 275, 277, 281, 279, 283, -1, -1, 517, + 519, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7865, -1, 7705, 7707, -1, -1, 7867, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 236, 237, 238, + 297, 239, -1, -1, 299, 301, 303, -1, + 464, -1, -1, 521, 523, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7883, -1, -1, + 7725, -1, -1, 7881, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 505, 324, -1, 241, -1, -1, 326, + -1, -1, -1, 7749, 328, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7751, 7753, 7755, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 242, 243, 244, + 245, 246, -1, -1, 333, 335, 491, 559, + 466, 337, 417, 525, 527, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7885, -1, -1, + -1, -1, -1, 7887, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 249, 250, 251, 361, 252, 367, -1, + 363, 365, 371, -1, 468, 369, 432, 533, + 535, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7909, -1, 7799, 7797, -1, 7795, 7911, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7923, 253, 375, + 7929, 255, 7833, -1, 563, -1, -1, 7823, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7925, -1, -1, + -1, -1, -1, 7927, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7696, + -1, -1, -1, 7690, 270, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7692, 7694, 7698, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7697, -1, -1, -1, 7691, + 271, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7693, 7695, 7699, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 500, 284, -1, -1, -1, 290, + 7712, 286, -1, 288, 486, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 501, 285, + -1, -1, -1, 291, 7713, 287, -1, 289, + 487, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 292, -1, 7718, -1, 7720, + -1, -1, -1, 7714, 542, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7716, -1, -1, -1, 7722, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 293, + -1, 7719, -1, 7721, -1, -1, -1, 7715, + 543, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7717, 7830, -1, + -1, 7723, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 308, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 309, + -1, -1, -1, -1, -1, -1, -1, -1, + 496, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7728, -1, -1, -1, -1, 310, + -1, -1, -1, -1, 488, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7730, 7732, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7729, -1, + -1, -1, -1, 311, -1, -1, -1, -1, + 489, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7731, 7733, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 313, -1, -1, -1, -1, 315, + -1, -1, -1, -1, 317, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7734, 7738, 7740, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 314, -1, + -1, -1, -1, 316, -1, -1, -1, -1, + 318, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7735, 7739, 7741, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 340, -1, -1, -1, -1, 342, + -1, -1, -1, 7768, 344, -1, -1, 528, + 530, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7770, 7774, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 341, -1, + -1, -1, -1, 343, -1, -1, -1, 7769, + 345, -1, -1, 529, 531, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7771, 7775, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 346, 348, -1, -1, -1, 350, + -1, -1, -1, 7776, 352, -1, -1, -1, + -1, 536, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7778, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 347, 349, + -1, -1, -1, 351, -1, -1, -1, 7777, + 353, -1, -1, -1, -1, 537, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7779, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, + -1, -1, -1, 7786, 356, -1, -1, -1, + -1, 538, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7788, 7790, 7792, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7831, -1, 355, -1, -1, -1, 7787, + 357, -1, -1, -1, -1, 539, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7789, 7791, 7793, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7808, 7810, 372, -1, 7812, -1, -1, + -1, -1, -1, 7814, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7816, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7809, 7811, 373, + -1, 7813, 7832, -1, -1, -1, -1, 7815, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7817, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 377, 7824, -1, -1, -1, -1, + -1, -1, -1, 379, 381, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7826, 7828, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 378, 7825, + -1, -1, -1, -1, -1, -1, -1, 380, + 382, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7827, 7829, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 475, 471, -1, -1, -1, -1, -1, + 469, -1, -1, -1, 473, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 476, 472, -1, + -1, -1, -1, -1, 470, -1, -1, -1, + 474, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 478, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 479, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 480, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 481, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 508, -1, -1, -1, -1, -1, + 482, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 509, -1, + -1, -1, -1, -1, 483, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 492, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 493, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 494, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 495, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 506, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 507, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 510, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 511, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 554, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 555, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7756, -1, -1, 7758, -1, -1, + 556, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7757, -1, + -1, 7759, -1, -1, 557, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 560, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 561, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8173, 901, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8129, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8122, 902, -1, + -1, -1, -1, -1, 8121, 8120, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7944, 7945, -1, 8124, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8136, 904, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7960, 7961, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8138, 905, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7976, 7977, -1, 8140, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8154, 906, -1, -1, 938, -1, -1, + 8153, 8152, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7992, 7993, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8184, 908, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8008, 8009, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8170, 910, -1, -1, 939, -1, -1, + 8169, 8168, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8025, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8186, 911, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8040, 8041, -1, 8188, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8146, 912, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8151, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8048, 940, -1, + -1, -1, -1, -1, 8113, 8112, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7936, 7937, 8118, 8115, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8050, 941, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7952, 7953, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8052, 942, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7968, 7969, 8134, 8131, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8054, 943, -1, -1, 970, -1, -1, + 8145, 8144, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7984, 7985, 8150, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8162, 944, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8167, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8058, 973, -1, -1, 971, -1, -1, + 8161, 8160, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8016, 8017, 8166, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8056, 972, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8000, 8001, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8060, 974, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8032, 8033, 8182, 8179, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 979, -1, + -1, 980, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1024, -1, -1, -1, 1025, -1, -1, + -1, 1238, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 1027, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1031, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 1036, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1037, -1, -1, -1, 1252, -1, -1, + 1250, 1049, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1264, -1, -1, 1262, 1038, -1, -1, + -1, 1266, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1117, -1, -1, -1, 1253, -1, -1, + 1251, 1081, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1104, -1, -1, + -1, 1105, -1, -1, -1, 1239, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 1107, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1111, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 1116, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1265, -1, -1, 1263, 1118, -1, -1, + -1, 1267, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1142, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1143, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1244, -1, -1, + -1, 1217, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1245, -1, -1, -1, 1218, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1234, -1, -1, + -1, 1232, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1235, -1, -1, -1, 1233, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1242, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1243, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1246, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1247, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1254, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1255, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1258, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1259, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1260, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1261, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1268, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1269, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1272, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1273, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 1570, 1571, 1573, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1572, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1574, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1728, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1730, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1747, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 2345, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2353, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 2356, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2507, 2508, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 2888, 2891, 2892, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2964, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 3020, 3018, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 3019, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 3144, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 3264, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3271, 3272, + 3274, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 3275, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3402, 3404, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 3403, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 3546, 3548, 3550, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3549, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 4134, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 6918, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 6920, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 6922, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 6924, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 6926, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 6930, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 6971, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 6973, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 6976, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 6977, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 6979, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7682, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7684, 7686, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7683, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7685, 7687, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7688, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7689, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7700, 7702, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7701, 7703, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7708, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7709, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7710, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7711, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7726, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7727, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7736, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7737, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7742, -1, -1, -1, -1, -1, + -1, -1, -1, 7744, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7746, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7743, -1, + -1, -1, -1, -1, -1, -1, -1, 7745, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7747, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7760, 7762, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7761, 7763, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7764, -1, -1, -1, -1, -1, + -1, -1, -1, 7766, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7765, -1, + -1, -1, -1, -1, -1, -1, -1, 7767, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7772, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7773, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7780, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7781, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7782, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7783, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7784, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7785, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7800, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7801, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7802, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7803, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7804, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7806, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7805, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7807, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7820, -1, -1, + -1, -1, -1, 7818, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7821, -1, -1, -1, -1, -1, 7819, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7835, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7846, 7844, -1, + 7850, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7848, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7847, 7845, -1, 7851, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7849, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7852, + -1, -1, -1, -1, -1, 7862, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7853, -1, -1, -1, -1, + -1, 7863, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7856, 7854, -1, + 7860, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7858, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7857, 7855, -1, 7861, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7859, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7872, 7870, -1, + 7876, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7874, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7873, 7871, -1, 7877, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7875, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7878, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7879, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7890, 7888, -1, + 7894, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7892, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7891, 7889, -1, 7895, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7893, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7896, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7897, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7900, 7898, -1, + 7904, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7906, -1, -1, + -1, -1, -1, 7902, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7901, 7899, -1, 7905, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7907, -1, -1, -1, -1, -1, 7903, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7914, 7912, -1, + 7918, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7920, -1, -1, + -1, -1, -1, 7916, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7915, 7913, -1, 7919, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7921, -1, -1, -1, -1, -1, 7917, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7938, 7940, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7942, 8064, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7939, 7941, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7943, 8065, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7946, 7948, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7950, 8072, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7947, 7949, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7951, 8073, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7954, 7956, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7955, 7957, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7962, 7964, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7963, 7965, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7970, 7972, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7974, 8080, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7971, 7973, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7975, 8081, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7978, 7980, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7982, 8088, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7979, 7981, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7983, 8089, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7986, 7988, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7990, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7987, 7989, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7991, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7994, 7996, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7998, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7995, 7997, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7999, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8002, 8004, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8003, 8005, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8010, 8012, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8011, 8013, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8018, 8020, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8022, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8019, 8021, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8023, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8027, 8029, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8031, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8034, 8036, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8038, 8096, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8035, 8037, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8039, 8097, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8042, 8044, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8046, 8104, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8043, 8045, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8047, 8105, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8066, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8067, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8068, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8069, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8070, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8071, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8074, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8075, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8076, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8077, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8078, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8079, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8082, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8083, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8084, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8085, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8086, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8087, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8090, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8091, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8092, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8093, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8094, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8095, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8098, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8099, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8100, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8101, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8102, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8103, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8106, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8107, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8108, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8109, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8110, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8111, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8114, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8116, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8119, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8130, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8132, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8135, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8141, 8142, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8143, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8157, 8158, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8159, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8164, 8165, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8172, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8178, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8180, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8183, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8602, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8603, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8622, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8653, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8654, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8655, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8708, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8713, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8716, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8740, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8742, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8769, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8772, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8775, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8777, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8800, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8802, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8813, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8814, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8815, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8816, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8817, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8820, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8821, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8824, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8825, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8832, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8833, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8836, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8837, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8840, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8841, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8876, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8877, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8878, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8879, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8928, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8929, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8930, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8931, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8938, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8939, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8940, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8941, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 10972, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12364, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12366, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12368, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12370, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12372, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12374, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12376, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12378, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12380, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12382, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12384, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12386, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12389, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12391, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12393, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12400, 12401, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12403, 12404, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12406, 12407, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12409, 12410, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12412, 12413, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12436, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12446, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12460, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12462, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12464, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12466, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12468, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12470, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12472, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12474, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12476, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12478, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12480, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12482, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12485, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12487, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12489, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12496, 12497, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12499, 12500, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12502, 12503, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12505, 12506, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12508, 12509, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12532, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12535, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12536, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12537, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 12538, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12542, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 119134, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 119135, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 119136, 119137, 119138, 119139, 119140, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 119227, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 119228, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 119229, 119231, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 119230, 119232, -1, -1, -1, }; + diff --git a/extern/src_netcdf4/v1hpg.c b/extern/src_netcdf4/v1hpg.c new file mode 100644 index 0000000000000000000000000000000000000000..11550fc0082d07c59beb6b9b978c362139299d0f --- /dev/null +++ b/extern/src_netcdf4/v1hpg.c @@ -0,0 +1,1400 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: v1hpg.c,v 1.70 2010/05/26 21:43:34 dmh Exp $ */ + +#include "config.h" +#include "nc.h" +#include +#include +#include +#include +#include "rnd.h" +#include "ncx.h" + +/* + * This module defines the external representation + * of the "header" of a netcdf version one file and + * the version two variant that uses 64-bit file + * offsets instead of the 32-bit file offsets in version + * one files. + * For each of the components of the NC structure, + * There are (static) ncx_len_XXX(), v1h_put_XXX() + * and v1h_get_XXX() functions. These define the + * external representation of the components. + * The exported entry points for the whole NC structure + * are built up from these. + */ + + +/* + * "magic number" at beginning of file: 0x43444601 (big endian) + * assert(sizeof(ncmagic) % X_ALIGN == 0); + */ +static const schar ncmagic[] = {'C', 'D', 'F', 0x02}; +static const schar ncmagic1[] = {'C', 'D', 'F', 0x01}; + + +/* + * v1hs == "Version 1 Header Stream" + * + * The netcdf file version 1 header is + * of unknown and potentially unlimited size. + * So, we don't know how much to get() on + * the initial read. We build a stream, 'v1hs' + * on top of ncio to do the header get. + */ +typedef struct v1hs { + ncio *nciop; + off_t offset; /* argument to nciop->get() */ + size_t extent; /* argument to nciop->get() */ + int flags; /* set to RGN_WRITE for write */ + int version; /* format variant: NC_FORMAT_CLASSIC or NC_FORMAT_64BIT */ + void *base; /* beginning of current buffer */ + void *pos; /* current position in buffer */ + void *end; /* end of current buffer = base + extent */ +} v1hs; + + +/* + * Release the stream, invalidate buffer + */ +static int +rel_v1hs(v1hs *gsp) +{ + int status; + if(gsp->offset == OFF_NONE || gsp->base == NULL) + return ENOERR; + status = ncio_rel(gsp->nciop, gsp->offset, + gsp->flags == RGN_WRITE ? RGN_MODIFIED : 0); + gsp->end = NULL; + gsp->pos = NULL; + gsp->base = NULL; + return status; +} + + +/* + * Release the current chunk and get the next one. + * Also used for initialization when gsp->base == NULL. + */ +static int +fault_v1hs(v1hs *gsp, size_t extent) +{ + int status; + + if(gsp->base != NULL) + { + const ptrdiff_t incr = (char *)gsp->pos - (char *)gsp->base; + status = rel_v1hs(gsp); + if(status) + return status; + gsp->offset += incr; + } + + if(extent > gsp->extent) + gsp->extent = extent; + + status = ncio_get(gsp->nciop, + gsp->offset, gsp->extent, + gsp->flags, &gsp->base); + if(status) + return status; + + gsp->pos = gsp->base; + gsp->end = (char *)gsp->base + gsp->extent; + + return ENOERR; +} + + +/* + * Ensure that 'nextread' bytes are available. + */ +static int +check_v1hs(v1hs *gsp, size_t nextread) +{ + +#if 0 /* DEBUG */ +fprintf(stderr, "nextread %lu, remaining %lu\n", + (unsigned long)nextread, + (unsigned long)((char *)gsp->end - (char *)gsp->pos)); +#endif + + if((char *)gsp->pos + nextread <= (char *)gsp->end) + return ENOERR; + return fault_v1hs(gsp, nextread); +} + +/* End v1hs */ + +/* Write a size_t to the header */ +static int +v1h_put_size_t(v1hs *psp, const size_t *sp) +{ + int status = check_v1hs(psp, X_SIZEOF_SIZE_T); + if(status != ENOERR) + return status; + return ncx_put_size_t(&psp->pos, sp); +} + + +/* Read a size_t from the header */ +static int +v1h_get_size_t(v1hs *gsp, size_t *sp) +{ + int status = check_v1hs(gsp, X_SIZEOF_SIZE_T); + if(status != ENOERR) + return status; + return ncx_get_size_t((const void **)(&gsp->pos), sp); +} + + +/* Begin nc_type */ + +#define X_SIZEOF_NC_TYPE X_SIZEOF_INT + +/* Write a nc_type to the header */ +static int +v1h_put_nc_type(v1hs *psp, const nc_type *typep) +{ + const int itype = (int) *typep; + int status = check_v1hs(psp, X_SIZEOF_INT); + if(status != ENOERR) + return status; + status = ncx_put_int_int(psp->pos, &itype); + psp->pos = (void *)((char *)psp->pos + X_SIZEOF_INT); + return status; +} + + +/* Read a nc_type from the header */ +static int +v1h_get_nc_type(v1hs *gsp, nc_type *typep) +{ + int type = 0; + int status = check_v1hs(gsp, X_SIZEOF_INT); + if(status != ENOERR) + return status; + status = ncx_get_int_int(gsp->pos, &type); + gsp->pos = (void *)((char *)gsp->pos + X_SIZEOF_INT); + if(status != ENOERR) + return status; + + assert(type == NC_BYTE + || type == NC_CHAR + || type == NC_SHORT + || type == NC_INT + || type == NC_FLOAT + || type == NC_DOUBLE); + + /* else */ + *typep = (nc_type) type; + + return ENOERR; +} + +/* End nc_type */ +/* Begin NCtype (internal tags) */ + +#define X_SIZEOF_NCTYPE X_SIZEOF_INT + +/* Write a NCtype to the header */ +static int +v1h_put_NCtype(v1hs *psp, NCtype type) +{ + const int itype = (int) type; + int status = check_v1hs(psp, X_SIZEOF_INT); + if(status != ENOERR) + return status; + status = ncx_put_int_int(psp->pos, &itype); + psp->pos = (void *)((char *)psp->pos + X_SIZEOF_INT); + return status; +} + +/* Read a NCtype from the header */ +static int +v1h_get_NCtype(v1hs *gsp, NCtype *typep) +{ + int type = 0; + int status = check_v1hs(gsp, X_SIZEOF_INT); + if(status != ENOERR) + return status; + status = ncx_get_int_int(gsp->pos, &type); + gsp->pos = (void *)((char *)gsp->pos + X_SIZEOF_INT); + if(status != ENOERR) + return status; + /* else */ + *typep = (NCtype) type; + return ENOERR; +} + +/* End NCtype */ +/* Begin NC_string */ + +/* + * How much space will the xdr'd string take. + * Formerly +NC_xlen_string(cdfstr) + */ +static size_t +ncx_len_NC_string(const NC_string *ncstrp) +{ + size_t sz = X_SIZEOF_SIZE_T; /* nchars */ + + assert(ncstrp != NULL); + + if(ncstrp->nchars != 0) + { +#if 0 + assert(ncstrp->nchars % X_ALIGN == 0); + sz += ncstrp->nchars; +#else + sz += _RNDUP(ncstrp->nchars, X_ALIGN); +#endif + } + return sz; +} + + +/* Write a NC_string to the header */ +static int +v1h_put_NC_string(v1hs *psp, const NC_string *ncstrp) +{ + int status; + +#if 0 + assert(ncstrp->nchars % X_ALIGN == 0); +#endif + + status = v1h_put_size_t(psp, &ncstrp->nchars); + if(status != ENOERR) + return status; + status = check_v1hs(psp, _RNDUP(ncstrp->nchars, X_ALIGN)); + if(status != ENOERR) + return status; + status = ncx_pad_putn_text(&psp->pos, ncstrp->nchars, ncstrp->cp); + if(status != ENOERR) + return status; + + return ENOERR; +} + + +/* Read a NC_string from the header */ +static int +v1h_get_NC_string(v1hs *gsp, NC_string **ncstrpp) +{ + int status; + size_t nchars = 0; + NC_string *ncstrp; + + status = v1h_get_size_t(gsp, &nchars); + if(status != ENOERR) + return status; + + ncstrp = new_NC_string(nchars, NULL); + if(ncstrp == NULL) + { + return NC_ENOMEM; + } + + +#if 0 +/* assert(ncstrp->nchars == nchars || ncstrp->nchars - nchars < X_ALIGN); */ + assert(ncstrp->nchars % X_ALIGN == 0); + status = check_v1hs(gsp, ncstrp->nchars); +#else + + status = check_v1hs(gsp, _RNDUP(ncstrp->nchars, X_ALIGN)); +#endif + if(status != ENOERR) + goto unwind_alloc; + + status = ncx_pad_getn_text((const void **)(&gsp->pos), + nchars, ncstrp->cp); + if(status != ENOERR) + goto unwind_alloc; + + *ncstrpp = ncstrp; + + return ENOERR; + +unwind_alloc: + free_NC_string(ncstrp); + return status; + +} + +/* End NC_string */ +/* Begin NC_dim */ + +/* + * How much space will the xdr'd dim take. + * Formerly +NC_xlen_dim(dpp) + */ +static size_t +ncx_len_NC_dim(const NC_dim *dimp) +{ + size_t sz; + + assert(dimp != NULL); + + sz = ncx_len_NC_string(dimp->name); + sz += X_SIZEOF_SIZE_T; + + return(sz); +} + + +/* Write a NC_dim to the header */ +static int +v1h_put_NC_dim(v1hs *psp, const NC_dim *dimp) +{ + int status; + + status = v1h_put_NC_string(psp, dimp->name); + if(status != ENOERR) + return status; + + status = v1h_put_size_t(psp, &dimp->size); + if(status != ENOERR) + return status; + + return ENOERR; +} + +/* Read a NC_dim from the header */ +static int +v1h_get_NC_dim(v1hs *gsp, NC_dim **dimpp) +{ + int status; + NC_string *ncstrp; + NC_dim *dimp; + + status = v1h_get_NC_string(gsp, &ncstrp); + if(status != ENOERR) + return status; + + dimp = new_x_NC_dim(ncstrp); + if(dimp == NULL) + { + status = NC_ENOMEM; + goto unwind_name; + } + + status = v1h_get_size_t(gsp, &dimp->size); + if(status != ENOERR) + { + free_NC_dim(dimp); /* frees name */ + return status; + } + + *dimpp = dimp; + + return ENOERR; + +unwind_name: + free_NC_string(ncstrp); + return status; +} + + +/* How much space in the header is required for this NC_dimarray? */ +static size_t +ncx_len_NC_dimarray(const NC_dimarray *ncap) +{ + size_t xlen = X_SIZEOF_NCTYPE; /* type */ + xlen += X_SIZEOF_SIZE_T; /* count */ + if(ncap == NULL) + return xlen; + /* else */ + { + const NC_dim **dpp = (const NC_dim **)ncap->value; + const NC_dim *const *const end = &dpp[ncap->nelems]; + for( /*NADA*/; dpp < end; dpp++) + { + xlen += ncx_len_NC_dim(*dpp); + } + } + return xlen; +} + + +/* Write a NC_dimarray to the header */ +static int +v1h_put_NC_dimarray(v1hs *psp, const NC_dimarray *ncap) +{ + int status; + + assert(psp != NULL); + + if(ncap == NULL +#if 1 + /* Backward: + * This clause is for 'byte for byte' + * backward compatibility. + * Strickly speaking, it is 'bug for bug'. + */ + || ncap->nelems == 0 +#endif + ) + { + /* + * Handle empty netcdf + */ + const size_t nosz = 0; + + status = v1h_put_NCtype(psp, NC_UNSPECIFIED); + if(status != ENOERR) + return status; + status = v1h_put_size_t(psp, &nosz); + if(status != ENOERR) + return status; + return ENOERR; + } + /* else */ + + status = v1h_put_NCtype(psp, NC_DIMENSION); + if(status != ENOERR) + return status; + status = v1h_put_size_t(psp, &ncap->nelems); + if(status != ENOERR) + return status; + + { + const NC_dim **dpp = (const NC_dim **)ncap->value; + const NC_dim *const *const end = &dpp[ncap->nelems]; + for( /*NADA*/; dpp < end; dpp++) + { + status = v1h_put_NC_dim(psp, *dpp); + if(status) + return status; + } + } + return ENOERR; +} + + +/* Read a NC_dimarray from the header */ +static int +v1h_get_NC_dimarray(v1hs *gsp, NC_dimarray *ncap) +{ + int status; + NCtype type = NC_UNSPECIFIED; + + assert(gsp != NULL && gsp->pos != NULL); + assert(ncap != NULL); + assert(ncap->value == NULL); + + status = v1h_get_NCtype(gsp, &type); + if(status != ENOERR) + return status; + + status = v1h_get_size_t(gsp, &ncap->nelems); + if(status != ENOERR) + return status; + + if(ncap->nelems == 0) + return ENOERR; + /* else */ + if(type != NC_DIMENSION) + return EINVAL; + + ncap->value = (NC_dim **) malloc(ncap->nelems * sizeof(NC_dim *)); + if(ncap->value == NULL) + return NC_ENOMEM; + ncap->nalloc = ncap->nelems; + + { + NC_dim **dpp = ncap->value; + NC_dim *const *const end = &dpp[ncap->nelems]; + for( /*NADA*/; dpp < end; dpp++) + { + status = v1h_get_NC_dim(gsp, dpp); + if(status) + { + ncap->nelems = (size_t)(dpp - ncap->value); + free_NC_dimarrayV(ncap); + return status; + } + } + } + + return ENOERR; +} + + +/* End NC_dim */ +/* Begin NC_attr */ + + +/* + * How much space will 'attrp' take in external representation? + * Formerly +NC_xlen_attr(app) + */ +static size_t +ncx_len_NC_attr(const NC_attr *attrp) +{ + size_t sz; + + assert(attrp != NULL); + + sz = ncx_len_NC_string(attrp->name); + sz += X_SIZEOF_NC_TYPE; /* type */ + sz += X_SIZEOF_SIZE_T; /* nelems */ + sz += attrp->xsz; + + return(sz); +} + + +#undef MIN +#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn)) + +/* + * Put the values of an attribute + * The loop is necessary since attrp->nelems + * could potentially be quite large. + */ +static int +v1h_put_NC_attrV(v1hs *psp, const NC_attr *attrp) +{ + int status; + const size_t perchunk = psp->extent; + size_t remaining = attrp->xsz; + void *value = attrp->xvalue; + size_t nbytes; + + assert(psp->extent % X_ALIGN == 0); + + do { + nbytes = MIN(perchunk, remaining); + + status = check_v1hs(psp, nbytes); + if(status != ENOERR) + return status; + + (void) memcpy(psp->pos, value, nbytes); + + psp->pos = (void *)((char *)psp->pos + nbytes); + value = (void *)((char *)value + nbytes); + remaining -= nbytes; + + } while(remaining != 0); + + return ENOERR; +} + +/* Write a NC_attr to the header */ +static int +v1h_put_NC_attr(v1hs *psp, const NC_attr *attrp) +{ + int status; + + status = v1h_put_NC_string(psp, attrp->name); + if(status != ENOERR) + return status; + + status = v1h_put_nc_type(psp, &attrp->type); + if(status != ENOERR) + return status; + + status = v1h_put_size_t(psp, &attrp->nelems); + if(status != ENOERR) + return status; + + status = v1h_put_NC_attrV(psp, attrp); + if(status != ENOERR) + return status; + + return ENOERR; +} + + +/* + * Get the values of an attribute + * The loop is necessary since attrp->nelems + * could potentially be quite large. + */ +static int +v1h_get_NC_attrV(v1hs *gsp, NC_attr *attrp) +{ + int status; + const size_t perchunk = gsp->extent; + size_t remaining = attrp->xsz; + void *value = attrp->xvalue; + size_t nget; + + do { + nget = MIN(perchunk, remaining); + + status = check_v1hs(gsp, nget); + if(status != ENOERR) + return status; + + (void) memcpy(value, gsp->pos, nget); + + gsp->pos = (void *)((char *)gsp->pos + nget); + value = (void *)((char *)value + nget); + remaining -= nget; + + } while(remaining != 0); + + return ENOERR; +} + + +/* Read a NC_attr from the header */ +static int +v1h_get_NC_attr(v1hs *gsp, NC_attr **attrpp) +{ + NC_string *strp; + int status; + nc_type type; + size_t nelems; + NC_attr *attrp; + + status = v1h_get_NC_string(gsp, &strp); + if(status != ENOERR) + return status; + + status = v1h_get_nc_type(gsp, &type); + if(status != ENOERR) + goto unwind_name; + + status = v1h_get_size_t(gsp, &nelems); + if(status != ENOERR) + goto unwind_name; + + attrp = new_x_NC_attr(strp, type, nelems); + if(attrp == NULL) + { + status = NC_ENOMEM; + goto unwind_name; + } + + status = v1h_get_NC_attrV(gsp, attrp); + if(status != ENOERR) + { + free_NC_attr(attrp); /* frees strp */ + return status; + } + + *attrpp = attrp; + + return ENOERR; + +unwind_name: + free_NC_string(strp); + return status; +} + + +/* How much space in the header is required for this NC_attrarray? */ +static size_t +ncx_len_NC_attrarray(const NC_attrarray *ncap) +{ + size_t xlen = X_SIZEOF_NCTYPE; /* type */ + xlen += X_SIZEOF_SIZE_T; /* count */ + if(ncap == NULL) + return xlen; + /* else */ + { + const NC_attr **app = (const NC_attr **)ncap->value; + const NC_attr *const *const end = &app[ncap->nelems]; + for( /*NADA*/; app < end; app++) + { + xlen += ncx_len_NC_attr(*app); + } + } + return xlen; +} + + +/* Write a NC_attrarray to the header */ +static int +v1h_put_NC_attrarray(v1hs *psp, const NC_attrarray *ncap) +{ + int status; + + assert(psp != NULL); + + if(ncap == NULL +#if 1 + /* Backward: + * This clause is for 'byte for byte' + * backward compatibility. + * Strickly speaking, it is 'bug for bug'. + */ + || ncap->nelems == 0 +#endif + ) + { + /* + * Handle empty netcdf + */ + const size_t nosz = 0; + + status = v1h_put_NCtype(psp, NC_UNSPECIFIED); + if(status != ENOERR) + return status; + status = v1h_put_size_t(psp, &nosz); + if(status != ENOERR) + return status; + return ENOERR; + } + /* else */ + + status = v1h_put_NCtype(psp, NC_ATTRIBUTE); + if(status != ENOERR) + return status; + status = v1h_put_size_t(psp, &ncap->nelems); + if(status != ENOERR) + return status; + + { + const NC_attr **app = (const NC_attr **)ncap->value; + const NC_attr *const *const end = &app[ncap->nelems]; + for( /*NADA*/; app < end; app++) + { + status = v1h_put_NC_attr(psp, *app); + if(status) + return status; + } + } + return ENOERR; +} + + +/* Read a NC_attrarray from the header */ +static int +v1h_get_NC_attrarray(v1hs *gsp, NC_attrarray *ncap) +{ + int status; + NCtype type = NC_UNSPECIFIED; + + assert(gsp != NULL && gsp->pos != NULL); + assert(ncap != NULL); + assert(ncap->value == NULL); + + status = v1h_get_NCtype(gsp, &type); + if(status != ENOERR) + return status; + status = v1h_get_size_t(gsp, &ncap->nelems); + if(status != ENOERR) + return status; + + if(ncap->nelems == 0) + return ENOERR; + /* else */ + if(type != NC_ATTRIBUTE) + return EINVAL; + + ncap->value = (NC_attr **) malloc(ncap->nelems * sizeof(NC_attr *)); + if(ncap->value == NULL) + return NC_ENOMEM; + ncap->nalloc = ncap->nelems; + + { + NC_attr **app = ncap->value; + NC_attr *const *const end = &app[ncap->nelems]; + for( /*NADA*/; app < end; app++) + { + status = v1h_get_NC_attr(gsp, app); + if(status) + { + ncap->nelems = (size_t)(app - ncap->value); + free_NC_attrarrayV(ncap); + return status; + } + } + } + + return ENOERR; +} + +/* End NC_attr */ +/* Begin NC_var */ + +/* + * How much space will the xdr'd var take. + * Formerly +NC_xlen_var(vpp) + */ +static size_t +ncx_len_NC_var(const NC_var *varp, size_t sizeof_off_t) +{ + size_t sz; + + assert(varp != NULL); + assert(sizeof_off_t != 0); + + sz = ncx_len_NC_string(varp->name); + sz += X_SIZEOF_SIZE_T; /* ndims */ + sz += ncx_len_int(varp->ndims); /* dimids */ + sz += ncx_len_NC_attrarray(&varp->attrs); + sz += X_SIZEOF_NC_TYPE; /* type */ + sz += X_SIZEOF_SIZE_T; /* len */ + sz += sizeof_off_t; /* begin */ + + return(sz); +} + + +/* Write a NC_var to the header */ +static int +v1h_put_NC_var(v1hs *psp, const NC_var *varp) +{ + int status; + + status = v1h_put_NC_string(psp, varp->name); + if(status != ENOERR) + return status; + + status = v1h_put_size_t(psp, &varp->ndims); + if(status != ENOERR) + return status; + + status = check_v1hs(psp, ncx_len_int(varp->ndims)); + if(status != ENOERR) + return status; + status = ncx_putn_int_int(&psp->pos, + varp->ndims, varp->dimids); + if(status != ENOERR) + return status; + + status = v1h_put_NC_attrarray(psp, &varp->attrs); + if(status != ENOERR) + return status; + + status = v1h_put_nc_type(psp, &varp->type); + if(status != ENOERR) + return status; + + status = v1h_put_size_t(psp, &varp->len); + if(status != ENOERR) + return status; + + status = check_v1hs(psp, psp->version == 1 ? 4 : 8); + if(status != ENOERR) + return status; + status = ncx_put_off_t(&psp->pos, &varp->begin, psp->version == 1 ? 4 : 8); + if(status != ENOERR) + return status; + + return ENOERR; +} + + +/* Read a NC_var from the header */ +static int +v1h_get_NC_var(v1hs *gsp, NC_var **varpp) +{ + NC_string *strp; + int status; + size_t ndims; + NC_var *varp; + + status = v1h_get_NC_string(gsp, &strp); + if(status != ENOERR) + return status; + + status = v1h_get_size_t(gsp, &ndims); + if(status != ENOERR) + goto unwind_name; + + varp = new_x_NC_var(strp, ndims); + if(varp == NULL) + { + status = NC_ENOMEM; + goto unwind_name; + } + + status = check_v1hs(gsp, ncx_len_int(ndims)); + if(status != ENOERR) + goto unwind_alloc; + status = ncx_getn_int_int((const void **)(&gsp->pos), + ndims, varp->dimids); + if(status != ENOERR) + goto unwind_alloc; + + status = v1h_get_NC_attrarray(gsp, &varp->attrs); + if(status != ENOERR) + goto unwind_alloc; + + status = v1h_get_nc_type(gsp, &varp->type); + if(status != ENOERR) + goto unwind_alloc; + + status = v1h_get_size_t(gsp, &varp->len); + if(status != ENOERR) + goto unwind_alloc; + + status = check_v1hs(gsp, gsp->version == 1 ? 4 : 8); + if(status != ENOERR) + goto unwind_alloc; + status = ncx_get_off_t((const void **)&gsp->pos, + &varp->begin, gsp->version == 1 ? 4 : 8); + if(status != ENOERR) + goto unwind_alloc; + + *varpp = varp; + return ENOERR; + +unwind_alloc: + free_NC_var(varp); /* frees name */ + return status; + +unwind_name: + free_NC_string(strp); + return status; +} + + +/* How much space in the header is required for this NC_vararray? */ +static size_t +ncx_len_NC_vararray(const NC_vararray *ncap, size_t sizeof_off_t) +{ + size_t xlen = X_SIZEOF_NCTYPE; /* type */ + xlen += X_SIZEOF_SIZE_T; /* count */ + if(ncap == NULL) + return xlen; + /* else */ + { + const NC_var **vpp = (const NC_var **)ncap->value; + const NC_var *const *const end = &vpp[ncap->nelems]; + for( /*NADA*/; vpp < end; vpp++) + { + xlen += ncx_len_NC_var(*vpp, sizeof_off_t); + } + } + return xlen; +} + + +/* Write a NC_vararray to the header */ +static int +v1h_put_NC_vararray(v1hs *psp, const NC_vararray *ncap) +{ + int status; + + assert(psp != NULL); + + if(ncap == NULL +#if 1 + /* Backward: + * This clause is for 'byte for byte' + * backward compatibility. + * Strickly speaking, it is 'bug for bug'. + */ + || ncap->nelems == 0 +#endif + ) + { + /* + * Handle empty netcdf + */ + const size_t nosz = 0; + + status = v1h_put_NCtype(psp, NC_UNSPECIFIED); + if(status != ENOERR) + return status; + status = v1h_put_size_t(psp, &nosz); + if(status != ENOERR) + return status; + return ENOERR; + } + /* else */ + + status = v1h_put_NCtype(psp, NC_VARIABLE); + if(status != ENOERR) + return status; + status = v1h_put_size_t(psp, &ncap->nelems); + if(status != ENOERR) + return status; + + { + const NC_var **vpp = (const NC_var **)ncap->value; + const NC_var *const *const end = &vpp[ncap->nelems]; + for( /*NADA*/; vpp < end; vpp++) + { + status = v1h_put_NC_var(psp, *vpp); + if(status) + return status; + } + } + return ENOERR; +} + + +/* Read a NC_vararray from the header */ +static int +v1h_get_NC_vararray(v1hs *gsp, NC_vararray *ncap) +{ + int status; + NCtype type = NC_UNSPECIFIED; + + assert(gsp != NULL && gsp->pos != NULL); + assert(ncap != NULL); + assert(ncap->value == NULL); + + status = v1h_get_NCtype(gsp, &type); + if(status != ENOERR) + return status; + + status = v1h_get_size_t(gsp, &ncap->nelems); + if(status != ENOERR) + return status; + + if(ncap->nelems == 0) + return ENOERR; + /* else */ + if(type != NC_VARIABLE) + return EINVAL; + + ncap->value = (NC_var **) malloc(ncap->nelems * sizeof(NC_var *)); + if(ncap->value == NULL) + return NC_ENOMEM; + ncap->nalloc = ncap->nelems; + + { + NC_var **vpp = ncap->value; + NC_var *const *const end = &vpp[ncap->nelems]; + for( /*NADA*/; vpp < end; vpp++) + { + status = v1h_get_NC_var(gsp, vpp); + if(status) + { + ncap->nelems = (size_t)(vpp - ncap->value); + free_NC_vararrayV(ncap); + return status; + } + } + } + + return ENOERR; +} + + +/* End NC_var */ +/* Begin NC */ + +/* + * Recompute the shapes of all variables + * Sets ncp->begin_var to start of first variable. + * Sets ncp->begin_rec to start of first record variable. + * Returns -1 on error. The only possible error is a reference + * to a non existent dimension, which could occur for a corrupted + * netcdf file. + */ +static int +NC_computeshapes(NC *ncp) +{ + NC_var **vpp = (NC_var **)ncp->vars.value; + NC_var *const *const end = &vpp[ncp->vars.nelems]; + NC_var *first_var = NULL; /* first "non-record" var */ + NC_var *first_rec = NULL; /* first "record" var */ + int status; + + ncp->begin_var = (off_t) ncp->xsz; + ncp->begin_rec = (off_t) ncp->xsz; + ncp->recsize = 0; + + if(ncp->vars.nelems == 0) + return(0); + + for( /*NADA*/; vpp < end; vpp++) + { + status = NC_var_shape(*vpp, &ncp->dims); + if(status != ENOERR) + return(status); + + if(IS_RECVAR(*vpp)) + { + if(first_rec == NULL) + first_rec = *vpp; + if((*vpp)->len == UINT32_MAX) + ncp->recsize += (*vpp)->dsizes[0]; + else + ncp->recsize += (*vpp)->len; + } + else + { + if(first_var == NULL) + first_var = *vpp; + /* + * Overwritten each time thru. + * Usually overwritten in first_rec != NULL clause below. + */ + ncp->begin_rec = (*vpp)->begin + (off_t)(*vpp)->len; + } + } + + if(first_rec != NULL) + { + assert(ncp->begin_rec <= first_rec->begin); + ncp->begin_rec = first_rec->begin; + /* + * for special case of exactly one record variable, pack value + */ + if(ncp->recsize == first_rec->len) + ncp->recsize = *first_rec->dsizes * first_rec->xsz; + } + + if(first_var != NULL) + { + ncp->begin_var = first_var->begin; + } + else + { + ncp->begin_var = ncp->begin_rec; + } + + assert(ncp->begin_var > 0); + assert(ncp->xsz <= (size_t)ncp->begin_var); + assert(ncp->begin_rec > 0); + assert(ncp->begin_var <= ncp->begin_rec); + + return(ENOERR); +} + +/* How much space in the header is required for the NC data structure? */ +size_t +ncx_len_NC(const NC *ncp, size_t sizeof_off_t) +{ + size_t xlen = sizeof(ncmagic); + + assert(ncp != NULL); + + xlen += X_SIZEOF_SIZE_T; /* numrecs */ + xlen += ncx_len_NC_dimarray(&ncp->dims); + xlen += ncx_len_NC_attrarray(&ncp->attrs); + xlen += ncx_len_NC_vararray(&ncp->vars, sizeof_off_t); + + return xlen; +} + + +/* Write the file header */ +int +ncx_put_NC(const NC *ncp, void **xpp, off_t offset, size_t extent) +{ + int status = ENOERR; + v1hs ps; /* the get stream */ + + assert(ncp != NULL); + + /* Initialize stream ps */ + + ps.nciop = ncp->nciop; + ps.flags = RGN_WRITE; + + if (ncp->flags & NC_64BIT_OFFSET) + ps.version = 2; + else + ps.version = 1; + + if(xpp == NULL) + { + /* + * Come up with a reasonable stream read size. + */ + extent = ncp->xsz; + if(extent <= MIN_NC_XSZ) + { + /* first time read */ + extent = ncp->chunk; + /* Protection for when ncp->chunk is huge; + * no need to read hugely. */ + if(extent > 4096) + extent = 4096; + } + else if(extent > ncp->chunk) + extent = ncp->chunk; + + ps.offset = 0; + ps.extent = extent; + ps.base = NULL; + ps.pos = ps.base; + + status = fault_v1hs(&ps, extent); + if(status) + return status; + } + else + { + ps.offset = offset; + ps.extent = extent; + ps.base = *xpp; + ps.pos = ps.base; + ps.end = (char *)ps.base + ps.extent; + } + + if (ps.version == 2) + status = ncx_putn_schar_schar(&ps.pos, sizeof(ncmagic), ncmagic); + else + status = ncx_putn_schar_schar(&ps.pos, sizeof(ncmagic1), ncmagic1); + if(status != ENOERR) + goto release; + + { + const size_t nrecs = NC_get_numrecs(ncp); + status = ncx_put_size_t(&ps.pos, &nrecs); + if(status != ENOERR) + goto release; + } + + assert((char *)ps.pos < (char *)ps.end); + + status = v1h_put_NC_dimarray(&ps, &ncp->dims); + if(status != ENOERR) + goto release; + + status = v1h_put_NC_attrarray(&ps, &ncp->attrs); + if(status != ENOERR) + goto release; + + status = v1h_put_NC_vararray(&ps, &ncp->vars); + if(status != ENOERR) + goto release; + +release: + (void) rel_v1hs(&ps); + + return status; +} + + +/* Make the in-memory NC structure from reading the file header */ +int +nc_get_NC(NC *ncp) +{ + int status; + v1hs gs; /* the get stream */ + + assert(ncp != NULL); + + /* Initialize stream gs */ + + gs.nciop = ncp->nciop; + gs.offset = 0; /* beginning of file */ + gs.extent = 0; + gs.flags = 0; + gs.version = 0; + gs.base = NULL; + gs.pos = gs.base; + + { + /* + * Come up with a reasonable stream read size. + */ + off_t filesize; + size_t extent = MIN_NC_XSZ; + + extent = ncp->xsz; + if(extent <= MIN_NC_XSZ) + { + status = ncio_filesize(ncp->nciop, &filesize); + if(status) + return status; + if(filesize < sizeof(ncmagic)) { /* too small, not netcdf */ + + status = NC_ENOTNC; + return status; + } + /* first time read */ + extent = ncp->chunk; + /* Protection for when ncp->chunk is huge; + * no need to read hugely. */ + if(extent > 4096) + extent = 4096; + if(extent > filesize) + extent = filesize; + } + else if(extent > ncp->chunk) + extent = ncp->chunk; + + /* + * Invalidate the I/O buffers to force a read of the header + * region. + */ + status = ncio_sync(gs.nciop); + if(status) + return status; + + status = fault_v1hs(&gs, extent); + if(status) + return status; + } + + /* get the header from the stream gs */ + + { + /* Get & check magic number */ + schar magic[sizeof(ncmagic)]; + (void) memset(magic, 0, sizeof(magic)); + + status = ncx_getn_schar_schar( + (const void **)(&gs.pos), sizeof(magic), magic); + if(status != ENOERR) + goto unwind_get; + + if(memcmp(magic, ncmagic, sizeof(ncmagic)-1) != 0) + { + status = NC_ENOTNC; + goto unwind_get; + } + /* Check version number in last byte of magic */ + if (magic[sizeof(ncmagic)-1] == 0x1) { + gs.version = 1; + } else if (magic[sizeof(ncmagic)-1] == 0x2) { + gs.version = 2; + fSet(ncp->flags, NC_64BIT_OFFSET); + /* Now we support version 2 file access on non-LFS systems -- rkr */ +#if 0 + if (sizeof(off_t) != 8) { + fprintf(stderr, "NETCDF WARNING: Version 2 file on 32-bit system.\n"); + } +#endif + } else { + status = NC_ENOTNC; + goto unwind_get; + } + } + + { + size_t nrecs = 0; + status = ncx_get_size_t((const void **)(&gs.pos), &nrecs); + if(status != ENOERR) + goto unwind_get; + NC_set_numrecs(ncp, nrecs); + } + + assert((char *)gs.pos < (char *)gs.end); + + status = v1h_get_NC_dimarray(&gs, &ncp->dims); + if(status != ENOERR) + goto unwind_get; + + status = v1h_get_NC_attrarray(&gs, &ncp->attrs); + if(status != ENOERR) + goto unwind_get; + + status = v1h_get_NC_vararray(&gs, &ncp->vars); + if(status != ENOERR) + goto unwind_get; + + ncp->xsz = ncx_len_NC(ncp, (gs.version == 1) ? 4 : 8); + + status = NC_computeshapes(ncp); + if(status != ENOERR) + goto unwind_get; + +unwind_get: + (void) rel_v1hs(&gs); + return status; +} diff --git a/extern/src_netcdf4/var.c b/extern/src_netcdf4/var.c new file mode 100644 index 0000000000000000000000000000000000000000..8bcbb8b9b98707804a1bb2a708915bb2b9a5034f --- /dev/null +++ b/extern/src_netcdf4/var.c @@ -0,0 +1,740 @@ +/* + * Copyright 1996, University Corporation for Atmospheric Research + * See netcdf/COPYRIGHT file for copying and redistribution conditions. + */ +/* $Id: var.c,v 1.144 2010/05/30 00:50:35 russ Exp $ */ + +#include "nc.h" +#include +#include +#include +#include +#include "ncx.h" +#include "rnd.h" +#include "utf8proc.h" + +#ifndef OFF_T_MAX +#define OFF_T_MAX (~ (off_t) 0 - (~ (off_t) 0 << (CHAR_BIT * sizeof (off_t) - 1))) +#endif + +/* + * Free var + * Formerly +NC_free_var(var) + */ +void +free_NC_var(NC_var *varp) +{ + if(varp == NULL) + return; + free_NC_attrarrayV(&varp->attrs); + free_NC_string(varp->name); +#ifndef MALLOCHACK + if(varp->dimids != NULL) free(varp->dimids); + if(varp->shape != NULL) free(varp->shape); + if(varp->dsizes != NULL) free(varp->dsizes); +#endif /*!MALLOCHACK*/ + free(varp); +} + + +/* + * Common code for new_NC_var() + * and ncx_get_NC_var() + */ +NC_var * +new_x_NC_var( + NC_string *strp, + size_t ndims) +{ + NC_var *varp; + const size_t o1 = M_RNDUP(ndims * sizeof(int)); + const size_t o2 = M_RNDUP(ndims * sizeof(size_t)); + +#ifdef MALLOCHACK + const size_t sz = M_RNDUP(sizeof(NC_var)) + + o1 + o2 + ndims * sizeof(off_t); +#else /*!MALLOCHACK*/ + const size_t o3 = ndims * sizeof(off_t); + const size_t sz = sizeof(NC_var); +#endif /*!MALLOCHACK*/ + + varp = (NC_var *) malloc(sz); + if(varp == NULL ) + return NULL; + (void) memset(varp, 0, sz); + varp->name = strp; + varp->ndims = ndims; + varp->hash = hash_fast(strp->cp, strlen(strp->cp)); + + if(ndims != 0) + { +#ifdef MALLOCHACK + /* + * NOTE: lint may complain about the next 3 lines: + * "pointer cast may result in improper alignment". + * We use the M_RNDUP() macro to get the proper alignment. + */ + varp->dimids = (int *)((char *)varp + M_RNDUP(sizeof(NC_var))); + varp->shape = (size_t *)((char *)varp->dimids + o1); + varp->dsizes = (off_t *)((char *)varp->shape + o2); +#else /*!MALLOCHACK*/ + varp->dimids = (int*)malloc(o1); + varp->shape = (size_t*)malloc(o2); + varp->dsizes = (off_t*)malloc(o3); +#endif /*!MALLOCHACK*/ + } + + varp->xsz = 0; + varp->len = 0; + varp->begin = 0; + + return varp; +} + + +/* + * Formerly +NC_new_var() + */ +static NC_var * +new_NC_var(const char *uname, nc_type type, + size_t ndims, const int *dimids) +{ + NC_string *strp; + NC_var *varp; + + char *name = (char *)utf8proc_NFC((const unsigned char *)uname); + if(name == NULL) + return NULL; + strp = new_NC_string(strlen(name), name); + free(name); + if(strp == NULL) + return NULL; + + varp = new_x_NC_var(strp, ndims); + if(varp == NULL ) + { + free_NC_string(strp); + return NULL; + } + + varp->type = type; + + if( ndims != 0 && dimids != NULL) + (void) memcpy(varp->dimids, dimids, ndims * sizeof(int)); + + return(varp); +} + + +static NC_var * +dup_NC_var(const NC_var *rvarp) +{ + NC_var *varp = new_NC_var(rvarp->name->cp, rvarp->type, + rvarp->ndims, rvarp->dimids); + if(varp == NULL) + return NULL; + + + if(dup_NC_attrarrayV(&varp->attrs, &rvarp->attrs) != NC_NOERR) + { + free_NC_var(varp); + return NULL; + } + + (void) memcpy(varp->shape, rvarp->shape, + rvarp->ndims * sizeof(size_t)); + (void) memcpy(varp->dsizes, rvarp->dsizes, + rvarp->ndims * sizeof(size_t)); + varp->xsz = rvarp->xsz; + varp->len = rvarp->len; + varp->begin = rvarp->begin; + + return varp; +} + + +/* vararray */ + + +/* + * Free the stuff "in" (referred to by) an NC_vararray. + * Leaves the array itself allocated. + */ +void +free_NC_vararrayV0(NC_vararray *ncap) +{ + assert(ncap != NULL); + + if(ncap->nelems == 0) + return; + + assert(ncap->value != NULL); + + { + NC_var **vpp = ncap->value; + NC_var *const *const end = &vpp[ncap->nelems]; + for( /*NADA*/; vpp < end; vpp++) + { + free_NC_var(*vpp); + *vpp = NULL; + } + } + ncap->nelems = 0; +} + + +/* + * Free NC_vararray values. + * formerly +NC_free_array() + */ +void +free_NC_vararrayV(NC_vararray *ncap) +{ + assert(ncap != NULL); + + if(ncap->nalloc == 0) + return; + + assert(ncap->value != NULL); + + free_NC_vararrayV0(ncap); + + free(ncap->value); + ncap->value = NULL; + ncap->nalloc = 0; +} + + +int +dup_NC_vararrayV(NC_vararray *ncap, const NC_vararray *ref) +{ + int status = NC_NOERR; + + assert(ref != NULL); + assert(ncap != NULL); + + if(ref->nelems != 0) + { + const size_t sz = ref->nelems * sizeof(NC_var *); + ncap->value = (NC_var **) malloc(sz); + if(ncap->value == NULL) + return NC_ENOMEM; + (void) memset(ncap->value, 0, sz); + ncap->nalloc = ref->nelems; + } + + ncap->nelems = 0; + { + NC_var **vpp = ncap->value; + const NC_var **drpp = (const NC_var **)ref->value; + NC_var *const *const end = &vpp[ref->nelems]; + for( /*NADA*/; vpp < end; drpp++, vpp++, ncap->nelems++) + { + *vpp = dup_NC_var(*drpp); + if(*vpp == NULL) + { + status = NC_ENOMEM; + break; + } + } + } + + if(status != NC_NOERR) + { + free_NC_vararrayV(ncap); + return status; + } + + assert(ncap->nelems == ref->nelems); + + return NC_NOERR; +} + + +/* + * Add a new handle on the end of an array of handles + * Formerly +NC_incr_array(array, tail) + */ +static int +incr_NC_vararray(NC_vararray *ncap, NC_var *newelemp) +{ + NC_var **vp; + + assert(ncap != NULL); + + if(ncap->nalloc == 0) + { + assert(ncap->nelems == 0); + vp = (NC_var **) malloc(NC_ARRAY_GROWBY * sizeof(NC_var *)); + if(vp == NULL) + return NC_ENOMEM; + ncap->value = vp; + ncap->nalloc = NC_ARRAY_GROWBY; + } + else if(ncap->nelems +1 > ncap->nalloc) + { + vp = (NC_var **) realloc(ncap->value, + (ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_var *)); + if(vp == NULL) + return NC_ENOMEM; + ncap->value = vp; + ncap->nalloc += NC_ARRAY_GROWBY; + } + + if(newelemp != NULL) + { + ncap->value[ncap->nelems] = newelemp; + ncap->nelems++; + } + return NC_NOERR; +} + + +static NC_var * +elem_NC_vararray(const NC_vararray *ncap, size_t elem) +{ + assert(ncap != NULL); + /* cast needed for braindead systems with signed size_t */ + if(ncap->nelems == 0 || (unsigned long)elem >= ncap->nelems) + return NULL; + + assert(ncap->value != NULL); + + return ncap->value[elem]; +} + + +/* End vararray per se */ + + +/* + * Step thru NC_VARIABLE array, seeking match on name. + * Return varid or -1 on not found. + * *varpp is set to the appropriate NC_var. + * Formerly (sort of) +NC_hvarid + */ +int +NC_findvar(const NC_vararray *ncap, const char *uname, NC_var **varpp) +{ + NC_var **loc; + uint32_t shash; + int varid; + char *name; + + assert(ncap != NULL); + + if(ncap->nelems == 0) + return -1; + + loc = (NC_var **) ncap->value; + + /* normalized version of uname */ + name = (char *)utf8proc_NFC((const unsigned char *)uname); + if(name == NULL) + return NC_ENOMEM; + shash = hash_fast(name, strlen(name)); + + for(varid = 0; (size_t) varid < ncap->nelems; varid++, loc++) + { + if((*loc)->hash == shash && + strncmp((*loc)->name->cp, name, strlen(name)) == 0) + { + if(varpp != NULL) + *varpp = *loc; + free(name); + return(varid); /* Normal return */ + } + } + free(name); + return(-1); /* not found */ +} + +/* + * For a netcdf type + * return the size of one element in the external representation. + * Note that arrays get rounded up to X_ALIGN boundaries. + * Formerly +NC_xtypelen + * See also ncx_len() + */ +size_t +ncx_szof(nc_type type) +{ + switch(type){ + case NC_BYTE: + case NC_CHAR: + return(1); + case NC_SHORT : + return(2); + case NC_INT: + return X_SIZEOF_INT; + case NC_FLOAT: + return X_SIZEOF_FLOAT; + case NC_DOUBLE : + return X_SIZEOF_DOUBLE; + default: + assert("ncx_szof invalid type" == 0); + return 0; + } +} + + +/* + * 'compile' the shape and len of a variable + * Formerly +NC_var_shape(var, dims) + */ +int +NC_var_shape(NC_var *varp, const NC_dimarray *dims) +{ + size_t *shp, *op; + off_t *dsp; + int *ip; + const NC_dim *dimp; + off_t product = 1; + + varp->xsz = ncx_szof(varp->type); + + if(varp->ndims == 0) + { + goto out; + } + + /* + * use the user supplied dimension indices + * to determine the shape + */ + for(ip = varp->dimids, op = varp->shape + ; ip < &varp->dimids[varp->ndims]; ip++, op++) + { + if(*ip < 0 || (size_t) (*ip) >= ((dims != NULL) ? dims->nelems : 1) ) + return NC_EBADDIM; + + dimp = elem_NC_dimarray(dims, (size_t)*ip); + *op = dimp->size; + if(*op == NC_UNLIMITED && ip != varp->dimids) + return NC_EUNLIMPOS; + } + + /* + * Compute the dsizes + */ + /* ndims is > 0 here */ + for(shp = varp->shape + varp->ndims -1, + dsp = varp->dsizes + varp->ndims -1; + shp >= varp->shape; + shp--, dsp--) + { + if(!(shp == varp->shape && IS_RECVAR(varp))) + { + if( (off_t)(*shp) <= OFF_T_MAX / product ) + { + product *= *shp; + } else + { + product = OFF_T_MAX ; + } + } + *dsp = product; + } + + +out : + if( varp->xsz <= (X_UINT_MAX - 1) / product ) /* if integer multiply will not overflow */ + { + varp->len = product * varp->xsz; + switch(varp->type) { + case NC_BYTE : + case NC_CHAR : + case NC_SHORT : + if( varp->len%4 != 0 ) + { + varp->len += 4 - varp->len%4; /* round up */ + /* *dsp += 4 - *dsp%4; */ + } + break; + default: + /* already aligned */ + break; + } + } else + { /* OK for last var to be "too big", indicated by this special len */ + varp->len = X_UINT_MAX; + } +#if 0 + arrayp("\tshape", varp->ndims, varp->shape); + arrayp("\tdsizes", varp->ndims, varp->dsizes); +#endif + return NC_NOERR; +} + +/* + * Check whether variable size is less than or equal to vlen_max, + * without overflowing in arithmetic calculations. If OK, return 1, + * else, return 0. For CDF1 format or for CDF2 format on non-LFS + * platforms, vlen_max should be 2^31 - 4, but for CDF2 format on + * systems with LFS it should be 2^32 - 4. + */ +int +NC_check_vlen(NC_var *varp, size_t vlen_max) { + size_t prod=varp->xsz; /* product of xsz and dimensions so far */ + + int ii; + + assert(varp != NULL); + for(ii = IS_RECVAR(varp) ? 1 : 0; ii < varp->ndims; ii++) { + if (varp->shape[ii] > vlen_max / prod) { + return 0; /* size in bytes won't fit in a 32-bit int */ + } + prod *= varp->shape[ii]; + } + return 1; /* OK */ +} + + +/* + * Given valid ncp and varid, return var + * else NULL on error + * Formerly +NC_hlookupvar() + */ +NC_var * +NC_lookupvar(NC *ncp, int varid) +{ + NC_var *varp; + + if(varid == NC_GLOBAL) + { + /* Global is error in this context */ + return(NULL); + } + + varp = elem_NC_vararray(&ncp->vars, (size_t)varid); + if(varp == NULL) + { + return NULL; + } + + assert(varp != NULL); + + return(varp); +} + + +/* Public */ + +int +NC3_def_var( int ncid, const char *name, nc_type type, + int ndims, const int *dimids, int *varidp) +{ + int status; + NC *ncp; + int varid; + NC_var *varp; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(!NC_indef(ncp)) + { + return NC_ENOTINDEFINE; + } + + status = NC_check_name(name); + if(status != NC_NOERR) + return status; + + status = nc_cktype(type); + if(status != NC_NOERR) + return status; + + /* cast needed for braindead systems with signed size_t */ + if((unsigned long) ndims > X_INT_MAX) /* Backward compat */ + { + return NC_EINVAL; + } + + if(ncp->vars.nelems >= NC_MAX_VARS) + { + return NC_EMAXVARS; + } + + varid = NC_findvar(&ncp->vars, name, &varp); + if(varid != -1) + { + return NC_ENAMEINUSE; + } + + varp = new_NC_var(name, type, ndims, dimids); + if(varp == NULL) + return NC_ENOMEM; + + status = NC_var_shape(varp, &ncp->dims); + if(status != NC_NOERR) + { + free_NC_var(varp); + return status; + } + + status = incr_NC_vararray(&ncp->vars, varp); + if(status != NC_NOERR) + { + free_NC_var(varp); + return status; + } + + if(varidp != NULL) + *varidp = (int)ncp->vars.nelems -1; /* varid */ + return NC_NOERR; +} + + +int +NC3_inq_varid(int ncid, const char *name, int *varid_ptr) +{ + int status; + NC *ncp; + NC_var *varp; + int varid; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + varid = NC_findvar(&ncp->vars, name, &varp); + if(varid == -1) + { + return NC_ENOTVAR; + } + + *varid_ptr = varid; + return NC_NOERR; +} + + +int +NC3_inq_var(int ncid, + int varid, + char *name, + nc_type *typep, + int *ndimsp, + int *dimids, + int *nattsp) +{ + int status; + NC *ncp; + NC_var *varp; + size_t ii; + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + varp = elem_NC_vararray(&ncp->vars, (size_t)varid); + if(varp == NULL) + return NC_ENOTVAR; + + if(name != NULL) + { + (void) strncpy(name, varp->name->cp, varp->name->nchars); + name[varp->name->nchars] = 0; + } + + if(typep != 0) + *typep = varp->type; + if(ndimsp != 0) + { + *ndimsp = (int) varp->ndims; + } + if(dimids != 0) + { + for(ii = 0; ii < varp->ndims; ii++) + { + dimids[ii] = varp->dimids[ii]; + } + } + if(nattsp != 0) + { + *nattsp = (int) varp->attrs.nelems; + } + + return NC_NOERR; +} + +int +NC3_rename_var(int ncid, int varid, const char *unewname) +{ + int status; + NC *ncp; + NC_var *varp; + NC_string *old, *newStr; + int other; + char *newname; /* normalized */ + + status = NC_check_id(ncid, &ncp); + if(status != NC_NOERR) + return status; + + if(NC_readonly(ncp)) + { + return NC_EPERM; + } + + status = NC_check_name(unewname); + if(status != NC_NOERR) + return status; + + /* check for name in use */ + other = NC_findvar(&ncp->vars, unewname, &varp); + if(other != -1) + { + return NC_ENAMEINUSE; + } + + varp = NC_lookupvar(ncp, varid); + if(varp == NULL) + { + /* invalid varid */ + return NC_ENOTVAR; /* TODO: is this the right error code? */ + } + + old = varp->name; + newname = (char *)utf8proc_NFC((const unsigned char *)unewname); + if(newname == NULL) + return NC_ENOMEM; + if(NC_indef(ncp)) + { + newStr = new_NC_string(strlen(newname),newname); + free(newname); + if(newStr == NULL) + return(-1); + varp->name = newStr; + varp->hash = hash_fast(newStr->cp, strlen(newStr->cp)); + free_NC_string(old); + return NC_NOERR; + } + + /* else, not in define mode */ + status = set_NC_string(varp->name, newname); + varp->hash = hash_fast(newname, strlen(newname)); + free(newname); + if(status != NC_NOERR) + return status; + + set_NC_hdirty(ncp); + + if(NC_doHsync(ncp)) + { + status = NC_sync(ncp); + if(status != NC_NOERR) + return status; + } + + return NC_NOERR; +} diff --git a/extern/src_netcdf4/xxdr.c b/extern/src_netcdf4/xxdr.c new file mode 100644 index 0000000000000000000000000000000000000000..9a93038ef6ef9cb9d762ff62a30335b9ac58c85d --- /dev/null +++ b/extern/src_netcdf4/xxdr.c @@ -0,0 +1,463 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. */ + +/* + * Copyright (c) 2009, 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: + * - 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 Sun Microsystems, 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 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. + * + * from: @(#)xdr.h 1.19 87/04/22 SMI + * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/xdr.h,v 1.23 2003/03/07 13:19:40 nectar Exp $ + * $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ + */ + +/* Define our own implementation of the needed + elements of XDR. Assumes read-only +*/ + +#undef XXDRTRACE + +#include "config.h" +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "xxdr.h" + +int xxdr_network_order; /* network order is big endian */ +static int xxdr_big_endian; /* what is this machine? */ + +#ifdef XXDRTRACE +static void +xxdrtrace(XXDR* xdr, char* where, off_t arg) +{ +fprintf(stderr,"xxdr: %s: arg=%ld ; pos=%ld len=%ld\n", + where,arg,(long)xdr->pos,(long)xdr->length); +fflush(stderr); +} +#else +#define xxdrtrace(x,y,z) +#endif + +/* Read-only operations */ + +int xxdr_getbytes(XXDR* xdrs, char* memory, off_t count) +{ + if(!memory) return 0; + if(!xdrs->getbytes(xdrs,memory,count)) + return 0; + return 1; +} + + +/* get a unsigned int from underlying stream*/ +int +xxdr_uint(XXDR* xdr, unsigned int* ip) +{ + if(!ip) return 0; + if(!xdr->getbytes(xdr,(char*)ip,sizeof(*ip))) + return 0; + /*convert from network order*/ + if(!xxdr_network_order) { + swapinline32(ip); + } + return 1; +} + +/* get a long long from underlying stream*/ +int +xxdr_ulonglong(XXDR* xdr, unsigned long* llp) +{ + /* Pull two units */ + if(!llp) return 0; + if(!xdr->getbytes(xdr,(char*)llp,sizeof(*llp))) + return 0; + /* Convert to signed/unsigned */ + /*convert from network order*/ + if(!xxdr_network_order) { + swapinline64(llp); + } + return 1; +} + +/* get some bytes from underlying stream; + will move xdrs pointer to next XDRUNIT boundary*/ +int +xxdr_opaque(XXDR* xdr, char* mem, off_t count) +{ + off_t pos,rounded; + if(!xdr->getbytes(xdr,mem,count)) + return 0; + pos = xxdr_getpos(xdr); + rounded = RNDUP(pos); + return xxdr_skip(xdr,(rounded - pos)); +} + +/* get counted string from underlying stream*/ +int +xxdr_string(XXDR* xdrs, char** sp, off_t* lenp) +{ + char* s; + unsigned int len; + if(!xxdr_uint(xdrs,&len)) return 0; + s = (char*)malloc((off_t)len+1); + if(s == NULL) return 0; + if(!xxdr_opaque(xdrs,s,len)) { + free((void*)s); + return 0; + } + s[len] = '\0'; /* make sure it is null terminated */ + if(sp) *sp = s; + if(lenp) *lenp = len; + /* xxdr_opaque will have skippped any trailing bytes */ + return 1; +} + +/* returns bytes off from beginning*/ +off_t +xxdr_getpos(XXDR* xdr) +{ + return xdr->getpos(xdr); +} + +/* reposition the stream*/ +int +xxdr_setpos(XXDR* xdr, off_t pos) +{ + return xdr->setpos(xdr,pos); +} + +/* returns total available starting at current position */ +off_t +xxdr_getavail(XXDR* xdr) +{ + return xdr->getavail(xdr); +} + +/* free up XXDR structure */ +void +xxdr_free(XXDR* xdr) +{ + xdr->free(xdr); +} + +/***********************************/ + +/* Skip exacly "len" bytes in the input; any rounding must be done by the caller*/ +int +xxdr_skip(XXDR* xdrs, off_t len) +{ + unsigned int pos; + pos = xxdr_getpos(xdrs); + pos = (pos + len); + if(pos < 0) pos = 0; + return xxdr_setpos(xdrs,pos); +} + +/* skip "n" string/bytestring instances in the input*/ +int +xxdr_skip_strings(XXDR* xdrs, off_t n) +{ + while(n-- > 0) { + unsigned int slen; + if(!xxdr_uint(xdrs,&slen)) return 0; + slen = RNDUP(slen); + if(xxdr_skip(xdrs,slen)) return 0; + } + return 1; +} + +unsigned int +xdr_roundup(unsigned int n) +{ + unsigned int rounded; + rounded = RNDUP(n); + return rounded; +} + +unsigned int +ocbyteswap(unsigned int i) +{ + unsigned int swap,b0,b1,b2,b3; + b0 = (i>>24) & 0x000000ff; + b1 = (i>>16) & 0x000000ff; + b2 = (i>>8) & 0x000000ff; + b3 = (i) & 0x000000ff; + swap = (b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)); + return swap; +} + +/**************************************************/ +/* File based xdr */ +static void +xxdr_filefree(XXDR* xdrs) +{ + if(xdrs != NULL) { + (void)fflush((FILE *)xdrs->data); + free(xdrs); + } +} + +static int +xxdr_filegetbytes(XXDR* xdrs, char* addr, off_t len) +{ + int ok = 1; + int count; + +xxdrtrace(xdrs,"getbytes",len); + if(len < 0) len = 0; + if(!xdrs->valid) + { + if(fseek((FILE *)xdrs->data, xdrs->pos + xdrs->base, 0) != 0) { + ok=0; + goto done; + } + xdrs->valid = 1; + } + if(xdrs->pos + len > xdrs->length) + return 0; + if(len > 0) { + count = fread(addr, len, 1, (FILE*)xdrs->data); + if(count <= 0) { + ok=0; + goto done; + } + } + xdrs->pos += len; +done: + return ok; +} + +static off_t +xxdr_filegetpos(XXDR* xdrs) +{ +xxdrtrace(xdrs,"getpos",0); + return xdrs->pos; +} + +static off_t +xxdr_filegetavail(XXDR* xdrs) +{ +xxdrtrace(xdrs,"getavail",0); + return (xdrs->length - xdrs->pos); +} + +static int +xxdr_filesetpos(XXDR* xdrs, off_t pos) +{ + int ok = 1; +xxdrtrace(xdrs,"setpos",pos); + if(pos == xdrs->pos) goto done; + if(pos < 0) pos = 0; + if(pos > xdrs->length) {ok=0;goto done;} + xdrs->pos = pos; + xdrs->valid = 0; +done: + return ok; +} + + +/* +Modified to track the current position to avoid the file io +operation. Not sure if this worth the effort because I +don't actually know the cost to doing an fseek +*/ + +/* + * Initialize a stdio xdr stream. + * Sets the xdr stream handle xdrs for use on the stream file. + * Operation flag is set to op. + */ +XXDR* +xxdr_filecreate(FILE* file, off_t base) +{ + XXDR* xdrs = (XXDR*)calloc(1,sizeof(XXDR)); + if(xdrs != NULL) { + xdrs->data = (void*)file; + xdrs->base = base; + xdrs->pos = 0; + xdrs->valid = 0; + if(fseek(file,0L,SEEK_END)) return NULL; + xdrs->length = (off_t)ftell(file); + xdrs->length -= xdrs->base; + xdrs->getbytes = xxdr_filegetbytes; + xdrs->setpos = xxdr_filesetpos; + xdrs->getpos = xxdr_filegetpos; + xdrs->getavail = xxdr_filegetavail; + xdrs->free = xxdr_filefree; + } +xxdrtrace(xdrs,"create",base); + return xdrs; +} + +/**************************************************/ +/* memory based xdr */ + +static void +xxdr_memfree(XXDR* xdrs) +{ + if(xdrs != NULL) { + free(xdrs); + } +} + +static int +xxdr_memgetbytes(XXDR* xdrs, char* addr, off_t len) +{ + int ok = 1; + +xxdrtrace(xdrs,"getbytes",len); + if(len < 0) len = 0; + if(xdrs->pos+len > xdrs->length) {ok=0; goto done;} + if(len > 0) { + memcpy(addr,(char*)xdrs->data+xdrs->base+xdrs->pos, len); + } + xdrs->pos += len; +done: + return ok; +} + +static off_t +xxdr_memgetpos(XXDR* xdrs) +{ +xxdrtrace(xdrs,"getpos",0); + return xdrs->pos; +} + +static off_t +xxdr_memgetavail(XXDR* xdrs) +{ +xxdrtrace(xdrs,"getavail",0); + return (xdrs->length - xdrs->pos); +} + + +static int +xxdr_memsetpos(XXDR* xdrs, off_t pos) +{ + int ok = 1; +xxdrtrace(xdrs,"setpos",pos); + if(pos == xdrs->pos) goto done; + if(pos > xdrs->length) {ok=0; goto done;} + xdrs->pos = pos; +done: + return ok; +} + +/* +Modified to track the current position to avoid the file io +operation. Not sure if this worth the effort because I +don't actually know the cost to doing an fseek +*/ + +/* + * Initialize a stdio xdr stream. + * Sets the xdr stream handle xdrs for use on the + * given memory starting at base offset. + */ +XXDR* +xxdr_memcreate(char* mem, off_t memsize, off_t base) +{ + XXDR* xdrs = (XXDR*)calloc(1,sizeof(XXDR)); + if(xdrs != NULL) { + /* zero base memory */ + xdrs->data = (void*)(mem + base); + xdrs->base = 0; + xdrs->length = memsize - base; + xdrs->pos = 0; + xdrs->getbytes = xxdr_memgetbytes; + xdrs->setpos = xxdr_memsetpos; + xdrs->getpos = xxdr_memgetpos; + xdrs->getavail = xxdr_memgetavail; + xdrs->free = xxdr_memfree; + } +xxdrtrace(xdrs,"create",base); + return xdrs; +} + +/* Float utility types */ + +/* get a float from underlying stream*/ +int +xxdr_float(XXDR* xdr, float* fp) +{ + int status = 0; + float f; + unsigned int* data = (unsigned int*)&f; + /* Pull one unit directly into a float */ + status = xxdr_uint(xdr,data); + if(status && fp) + *fp = f; + return status; +} + +/* Get a double from underlying stream */ +int +xxdr_double(XXDR* xdr, double* dp) +{ + int status = 0; + char data[2*XDRUNIT]; + /* Pull two units */ + status = xxdr_opaque(xdr,data,2*XDRUNIT); + if(status && dp) { + xxdrntohdouble(data,dp); + } + return status; +} + +/* Double needs special handling */ +void +xxdrntohdouble(char* c8, double* dp) +{ + unsigned int ii[2]; + memcpy(ii,c8,2*XDRUNIT); + if(!xxdr_big_endian) { + unsigned int tmp; + /* reverse byte order */ + swapinline32(&ii[0]); + swapinline32(&ii[1]); + /* interchange ii[0] and ii[1] */ + tmp = ii[0]; + ii[0] = ii[1]; + ii[1] = tmp; + } + if(dp) *dp = *(double*)ii; +} + +void +xxdr_init() +{ + /* Compute if we are same as network order v-a-v xdr */ + int testint = 0x00000001; + char *byte = (char *)&testint; + xxdr_big_endian = (byte[0] == 0 ? 1 : 0); + xxdr_network_order = xxdr_big_endian; +} diff --git a/extern/src_netcdf4/xxdr.h b/extern/src_netcdf4/xxdr.h new file mode 100644 index 0000000000000000000000000000000000000000..d669c6e0217aca28c5195c5efb37a5fd4dc30221 --- /dev/null +++ b/extern/src_netcdf4/xxdr.h @@ -0,0 +1,183 @@ +/* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. + See the COPYRIGHT file for more information. +*/ + +/* + * Copyright (c) 2009, 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: + * - 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 Sun Microsystems, 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 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. + * + * from: @(#)xdr.h 1.19 87/04/22 SMI + * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/xdr.h,v 1.23 2003/03/07 13:19:40 nectar Exp $ + * $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ + */ + +/* Define our own implementation of the needed + elements of XDR. Assumes read-only +*/ + +#ifndef XXDR_H +#define XXDR_H + +/* + * This is the number of bytes per unit of external data. + */ +#define XDRUNIT (4) + +#if 1 +/* faster version when XDRUNIT is a power of two */ +# define RNDUP(x) (((x) + XDRUNIT - 1) & ~(XDRUNIT - 1)) +#else /* old version */ +#define RNDUP(x) ((((x) + XDRUNIT - 1) / XDRUNIT) \ + * XDRUNIT) +#endif + +/* signature: void swapinline32(unsigned int* ip) */ +#define swapinline32(ip) \ +{ \ + char dst[4]; \ + char* src = (char*)(ip); \ + dst[0] = src[3]; \ + dst[1] = src[2]; \ + dst[2] = src[1]; \ + dst[3] = src[0]; \ + *(ip) = *((unsigned int*)dst); \ +} + +/* signature: void swapinline64(unsigned long long* ip) */ +#define swapinline64(ip) \ +{ \ + char dst[8]; \ + char* src = (char*)(ip); \ + dst[0] = src[7]; \ + dst[1] = src[6]; \ + dst[2] = src[5]; \ + dst[3] = src[4]; \ + dst[4] = src[3]; \ + dst[5] = src[2]; \ + dst[6] = src[1]; \ + dst[7] = src[0]; \ + *ip = *((unsigned long long*)dst); \ +} + + +#ifdef OCIGNORE +/* Warning dst and src should not be the same memory (assert &iswap != &i) */ +#define xxdrntoh(dst,src) if(xxdr_network_order){dst=src;}else{swapinline32(dst,src);} +#define xxdrntohll(dst,src) if(xxdr_network_order){dst=src;}else{swapinline64(dst,src);} +#define xxdrhton(dst,src) xxdrntoh(dst,src) +#define xxdrhtonll(dst,src) xxdrntohll(dst,src) +#endif + +/* Double needs special handling */ +extern void xxdrntohdouble(char*,double*); + +/* + * The XDR handle. + * Contains operation which is being applied to the stream, + * an operations vector for the particular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular implementation. + */ +typedef struct XXDR XXDR; /* forward */ + +/* Assume |off_t| == |void*| */ +struct XXDR { + char* data; + off_t pos; /* relative to data; + may be a cache of underlying stream pos */ + int valid; /* 1=>underlying stream pos == pos */ + off_t base; /* beginning of data in case bod != 0*/ + off_t length; /* total size of available data (relative to base)*/ + /* Define minimum needed case specific operators */ + int (*getbytes)(XXDR*,char*,off_t); + int (*setpos)(XXDR*,off_t); + off_t (*getpos)(XXDR*); + off_t (*getavail)(XXDR*); + void (*free)(XXDR*); /* xdr kind specific free function */ +}; + +/* Track network order */ +extern int xxdr_network_order; /* does this machine match network order? */ + +/* Read-only operations */ + +/* Get exactly count bytes from underlying + stream; unlike opaque, this will + not round up to the XDRUNIT boundary +*/ +extern int xxdr_getbytes(XXDR*,char*,off_t); + +/* get an int from underlying stream*/ +extern int xxdr_uint(XXDR* , unsigned int*); + +/* get an int from underlying stream*/ +extern int xxdr_ulonglong(XXDR* , unsigned long*); + +/* get a float from underlying stream*/ +extern int xxdr_float(XXDR* , float*); + +/* get a double from underlying stream*/ +extern int xxdr_double(XXDR* , double*); + +/* get some bytes from underlying stream; + Warning: will read upto the next XDRUNIT boundary +*/ +extern int xxdr_opaque(XXDR*, char*, off_t); + +/* get counted string from underlying stream*/ +extern int xxdr_string(XXDR*, char**, off_t*); + +/* returns bytes off from beginning*/ +extern off_t xxdr_getpos(XXDR*); + +/* reposition the stream*/ +extern int xxdr_setpos(XXDR*, off_t); + +/* get remaining data available starting at current position */ +extern off_t xxdr_getavail(XXDR*); + +/* free up XXDR structure */ +void xxdr_free(XXDR*); + +/* File and memory creators */ +extern XXDR* xxdr_filecreate(FILE* file, off_t bod); +extern XXDR* xxdr_memcreate(char* mem, off_t memsize, off_t bod); + +/* Misc */ +extern int xxdr_skip(XXDR* xdrs, off_t len); /* WARNING: will skip exactly len bytes; + any rounding must be done by caller */ + +extern int xxdr_skip_strings(XXDR* xdrs, off_t n); + +extern unsigned int xxdr_roundup(off_t n); /* procedural version of RNDUP macro */ + +extern void xxdr_init(); + +/* Define some inlines */ +#define xxdr_length(xdrs) ((xdrs)->length) + +#endif /*XXDR_H*/ + diff --git a/header_licence b/header_licence new file mode 100644 index 0000000000000000000000000000000000000000..0ef6d769c8495af77bff63e6a141ed03b12e34bc --- /dev/null +++ b/header_licence @@ -0,0 +1,10 @@ +Software name : XIOS (Xml I/O Server) + http://forge.ipsl.jussieu.fr/ioserver +Creation date : January 2009 +Licence : CeCCIL version2 + see license file in root directory : Licence_CeCILL_V2-en.txt + or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html +Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement) + CNRS/IPSL (Institut Pierre Simon Laplace) +Project Manager : Yann Meurdesoif + yann.meurdesoif@cea.fr diff --git a/inputs/COMPLETE/context_atmosphere.xml b/inputs/COMPLETE/context_atmosphere.xml new file mode 100644 index 0000000000000000000000000000000000000000..aa7cd7b2ed65e10232ec566d2d27c94bd2c4b3e1 --- /dev/null +++ b/inputs/COMPLETE/context_atmosphere.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputs/COMPLETE/context_surface.xml b/inputs/COMPLETE/context_surface.xml new file mode 100644 index 0000000000000000000000000000000000000000..d82b14a0c2d9f42812e10128d872f50eb46cefa3 --- /dev/null +++ b/inputs/COMPLETE/context_surface.xml @@ -0,0 +1,57 @@ + + + + + + + + field_A_srf + 273.15 + + + field_A_srf + field_C_srf + + + + + + surf_att + 10 + 6.8 + 100.201 + + + + field_A_srf_K + @field_A_srf_K + + + + + @field_A_srf_max + file_6h + + + + + surf_att + 10 + 6.8 + 100.201 + + + + + + @field_A_srf_max + + + + + + + + + + + + diff --git a/inputs/COMPLETE/iodef.xml b/inputs/COMPLETE/iodef.xml new file mode 100644 index 0000000000000000000000000000000000000000..78dfc3f1aec2a72095d274d6f28ba2dc65e56784 --- /dev/null +++ b/inputs/COMPLETE/iodef.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + buffer_size = 80000000 + buffer_server_factor_size = 2 + + + + 100 + true + + + + + diff --git a/inputs/iodef.xml b/inputs/iodef.xml new file mode 100644 index 0000000000000000000000000000000000000000..dbbefa194e6fe969f33d8699554c2507de935356 --- /dev/null +++ b/inputs/iodef.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + buffer_size = 80000000 + buffer_server_factor_size = 2 + + + + false + 50 + + + + + + diff --git a/make_xios b/make_xios new file mode 100755 index 0000000000000000000000000000000000000000..17a5ec248ad70ad5fa5b209a802197c2c46db243 --- /dev/null +++ b/make_xios @@ -0,0 +1,202 @@ +#!/bin/bash + +install_dir=$PWD +compil_full="false" +use_oasis="false" +oasis="oasis3_mct" +use_memtrack="false" +job="1" +netcdf_lib="netcdf4_par" +compil_mode="prod" + +# Traitement de la ligne de commande +while (($# > 0)) + do + case $1 in + "-h"|"--help"|"-help") + echo "make_xios - installs XIOS on your architecture" + echo "make_xios [options]" + echo "options :" + echo " [--prod] : compilation in production mode (default)" + echo " [--dev] : compilation in development mode" + echo " [--debug] : compilation in debug mode" + echo " --arch arch : to choose target architecture" + echo " [--avail] : to know available target architectures " + echo " [--full] : to generate dependencies and recompile from scratch" + echo " [--use_oasis 'oasis3' 'oasis3_mct' : default oasis3_mct] : to use Oasis coupler" + echo " [--doc] : to generate Doxygen documentation (not available yet)" + echo " [--job ntasks] : to use parallel compilation with ntasks" + echo " [--netcdf_lib 'netcdf4_par'/'netcdf4_seq'/'netcdf4_internal' : default netcdf4_par] : choice of netcdf library" + echo " [--memtrack] : tracking memory leak - developper only" + echo "Example : ./make_xios --prod --arch PW6_VARGAS" + echo "Example : ./make_xios --avail" + exit;; + "--prod") compil_mode="prod" ; shift ;; + "--dev") compil_mode="dev" ; shift ;; + "--debug") compil_mode="debug" ; shift ;; + "--arch") arch=$2 ; shift ; shift ;; + "--avail") ls arch/*.fcm | cut -d"-" -f2 | cut -d"." -f1 ; exit ;; + "--full") compil_full="true" ; shift ;; + "--use_oasis") use_oasis="true" oasis=$2 ; shift ; shift ;; + "--doc") doc="true" ; shift ;; + "--job") job=$2 ; shift ; shift ;; + "--netcdf_lib") netcdf_lib=$2 ; shift ; shift ;; + "--memtrack") use_memtrack="true" ; shift ;; + *) code="$1" ; shift ;; + esac + done + +# Installation des sources +nb_files_gz=`ls $install_dir/tools/archive | grep tar.gz | wc -l` +if [ ${nb_files_gz} -ne 0 ] +then + echo -e "- uncompress archives ..." + for tarname in `ls $install_dir/tools/archive/*.tar.gz` ; do + gunzip -f "$tarname" + tar -xf ${tarname%.gz} + done +fi + +# Vérification de la présence d'un identifiant d'architecture. + +############################################################### +# lecture des chemins propres a l'architecture de la machine # +# et configuration de l'environnement # +############################################################### + +rm -f .void_file +echo > .void_file +rm -rf .void_dir +mkdir .void_dir + +if [[ !(-z $arch) ]] + then + rm -f $install_dir/arch.path + rm -f $install_dir/arch.fcm + rm -f $install_dir/arch.env + ln -s $install_dir/arch/arch-${arch}.path $install_dir/arch.path + ln -s $install_dir/arch/arch-${arch}.fcm $install_dir/arch.fcm + + if test -f $install_dir/arch/arch-${arch}.env + then + ln -s $install_dir/arch/arch-${arch}.env arch.env + else + ln -s $install_dir/.void_file arch.env + fi + + source $install_dir/arch.env + source $install_dir/arch.path + else + echo "Please choose a target achitecture --> list all available architecture using make_xios --avail!" + exit 1 +fi + +# Vérification de la présence d'un mode de compilation. + +if [[ "$compil_mode" == "prod" ]] + then + COMPIL_CFLAGS="%PROD_CFLAGS" + COMPIL_FFLAGS="%PROD_FFLAGS" +elif [[ "$compil_mode" == "dev" ]] + then + COMPIL_CFLAGS="%DEV_CFLAGS" + COMPIL_FFLAGS="%DEV_FFLAGS" +elif [[ "$compil_mode" == "debug" ]] + then + COMPIL_CFLAGS="%DEBUG_CFLAGS" + COMPIL_FFLAGS="%DEBUG_FFLAGS" +fi + +rm -r $PWD/extern/netcdf4 + +if [[ "$netcdf_lib" == "netcdf4_par" ]] + then + ln -s $PWD/.void_dir $PWD/extern/netcdf4 + XMLIO_CPPKEY="$XMLIO_CPPKEY USING_NETCDF_PAR" +elif [[ "$netcdf_lib" == "netcdf4_seq" ]] + then + ln -s $PWD/.void_dir $PWD/extern/netcdf4 +elif [[ "$netcdf_lib" == "netcdf4_internal" ]] + then + ln -s $PWD/extern/src_netcdf4 $PWD/extern/netcdf4 + XMLIO_CPPKEY="$XMLIO_CPPKEY USING_NETCDF_PAR USING_NETCDF_INTERNAL" + export NETCDF_INCDIR="-I${PWD}/extern/netcdf4" + export NETCDF_LIBDIR="" + export NETCDF_LIB="" +else + echo "Bad choice for --netcdf_lib argument : choose between 'netcdf4_par','netcdf4_seq' or 'netcdf4_internal'" + exit +fi + +if [[ "$use_oasis" == "true" ]] + then + if [[ "$oasis" == "oasis3_mct" ]] + then + XMLIO_CPPKEY="$XMLIO_CPPKEY USE_OMCT" + elif [[ "$oasis" == "oasis3" ]] + then + XMLIO_CPPKEY="$XMLIO_CPPKEY USE_OASIS" + OASIS_INCDIR="-I$PWD/../../prism/X64/build/lib/psmile.MPI1" + OASIS_LIBDIR="-L$PWD/../../prism/X64/lib" + OASIS_LIB="-lpsmile.MPI1 -lmpp_io" + else + echo "Bad choice for --use_oasis argument : choose between 'oasis3','oasis3_mct'" + exit + fi + NETCDF_LIB="-lnetcdff -lnetcdf" + XMLIO_FINCDIR="$OASIS_INCDIR $XMLIO_FINCDIR" + XMLIO_LIB="$OASIS_LIBDIR $OASIS_LIB $XMLIO_LIB" +fi + +if [[ "$use_memtrack" == "true" ]] + then + XMLIO_LIB="$ADDR2LINE_LIBDIR $ADDR2LINE_LIB $XMLIO_LIB" + XMLIO_CPPKEY="$XMLIO_CPPKEY XIOS_MEMTRACK" +fi + +XMLIO_CINCDIR="$NETCDF_INCDIR $HDF5_INCDIR $MPI_INCDIR" +XMLIO_FINCDIR="$XMLIO_FINCDIR $MPI_INCDIR" + +XMLIO_LIB="$XMLIO_LIB $NETCDF_LIBDIR $HDF5_LIBDIR $MPI_LIBDIR $NETCDF_LIB $HDF5_LIB $MPI_LIB" + +rm -f config.fcm +echo "%COMPIL_CFLAGS $COMPIL_CFLAGS" >> config.fcm +echo "%COMPIL_FFLAGS $COMPIL_FFLAGS" >> config.fcm +echo "%CPP_KEY $XMLIO_CPPKEY" >> config.fcm + +echo "%CBASE_INC $XMLIO_CINCDIR" >> config.fcm +echo "%FBASE_INC $XMLIO_FINCDIR" >> config.fcm +echo "%ARCH_LD $XMLIO_LIB" >> config.fcm + +echo "=> Using "$compil_mode" mode for compiling under architecture \""$arch"\" !" + +# Création de la documentation doxygen. +if [[ !(-z $doc) ]] + then + echo -e "- Create Doxygen documentation (disabled)..." + #doxygen -s +fi + +make_dir=$PWD + +export PATH=$PWD/tools/FCM/bin:$PATH + +#$make_dir/tools/preprocess_cpp $make_dir/src/xmlio/iface/interface.cpp $make_dir/src/xmlio/iface/interface.cpp.in +#$make_dir/tools/preprocess_f03 $make_dir/src/xmlio/fortran/ixmlioserver.f90 $make_dir/src/xmlio/fortran/ixmlioserver.f03.in + +if [[ "$compil_full" == "true" ]] + then + fcm build --clean --ignore-lock + fcm build -f --ignore-lock -j $job +else + fcm build --ignore-lock -j $job +fi + + +if [[ $? == 0 ]] + then + set nothing +# cd $WORKDIR/XMLIO_NEMO_COUPLE/modeles/NEMO/WORK +# cd $WORKDIR/XMLIO_NEMO/modeles/NEMO/WORK +# make +fi diff --git a/src/array.hpp b/src/array.hpp new file mode 100644 index 0000000000000000000000000000000000000000..03351d06d20bc0ae1cfe401b73c1e15505fa48e0 --- /dev/null +++ b/src/array.hpp @@ -0,0 +1,93 @@ +#ifndef __XMLIO_CArray__ +#define __XMLIO_CArray__ + +/// boost headers /// +#include +#include +#include + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" + + +namespace xios +{ + template + inline detail::multi_array::extent_gen getExtentNull(void) { return getExtentNull()[0];} + + template<> + inline detail::multi_array::extent_gen<1> getExtentNull<1>(void) { return extents[0]; } + + /// ////////////////////// Déclarations ////////////////////// /// + + template > + class CArray : public boost::multi_array + { + /// Définition de type /// + typedef boost::multi_array SuperClass; + + public: + + typedef ValueType ValType; + + /// Constructeurs /// +// template +// explicit CArray(const ExtentList & sizes); + template CArray(const ExtentList & sizes) + : boost::multi_array + (sizes, boost::fortran_storage_order()) + { /* Ne rien faire de plus */ } + + + explicit CArray(); + +// template +// CArray(const ExtentList & sizes, const boost::general_storage_order & store); + template CArray(const ExtentList & sizes, const boost::general_storage_order & store) + : boost::multi_array (sizes, store) + { /* Ne rien faire de plus */ } + + CArray(const CArray & array); // NEVER IMPLEMENTED. + CArray(const CArray * const array); // NEVER IMPLEMENTED. + + public: + + /// Flux /// + template + friend StdOStream & operator << + (StdOStream & os, const CArray & array); + + template + friend StdIStream & operator >> + (StdIStream & is, CArray & array); + + public: + + void toBinary (StdOStream & os) const; + void fromBinary(StdIStream & is); + + size_t getSize(void) const ; + bool toBuffer (CBufferOut& buffer) const; + bool fromBuffer(CBufferIn& buffer); + + + /// Destructeur /// + virtual ~CArray(void); + + }; // class CArray + + ///--------------------------------------------------------------- + +} // namespace xios + +//#include "array_impl.hpp" +#include "array_mac.hpp" +namespace xios +{ + template void FromBinary(StdIStream & is, ARRAY(ValueType, 1) & array) ; + template void FromBinary(StdIStream & is, ARRAY(ValueType, 2) & array) ; + template void FromBinary(StdIStream & is, ARRAY(ValueType, 3) & array) ; +} +#endif // __XMLIO_CArray__ diff --git a/src/array_mac.hpp b/src/array_mac.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9aff175f86143f2b00dc24d3258375797b9ab673 --- /dev/null +++ b/src/array_mac.hpp @@ -0,0 +1,26 @@ +#ifndef __XMLIO_CArray_mac__ +#define __XMLIO_CArray_mac__ + +/// ////////////////////// Macros ////////////////////// /// + +// Type Fortran +#define ARRAY(valuetype, numdims) boost::shared_ptr > + +#define ARRAY_ASSIGN(value, valuetype, numdims, extent)\ + value.reset(new CArray(boost::extents extent)) + +#define ARRAY_CREATE(value, valuetype, numdims, extent)\ + ARRAY(valuetype, numdims) value = \ + ARRAY(valuetype, numdims)(new CArray(boost::extents extent)) + +// Type C +#define ARRAY_C_ASSIGN(value, valuetype, numdims, extent)\ + value = ARRAY(valuetype, numdims) \ + (new CArray(boost::extents extent, c_storage_order())) + +#define ARRAY_C_CREATE(value, valuetype, numdims, extent)\ + ARRAY_C_ASSIGN(ARRAY(valuetype, numdims) value, valuetype, numdims, extent) + +///--------------------------------------------------------------- + +#endif // __XMLIO_CArray_mac__ diff --git a/src/array_new.hpp b/src/array_new.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2f454259b538bfe4eece6faccff339c93fce897c --- /dev/null +++ b/src/array_new.hpp @@ -0,0 +1,225 @@ +#ifndef __XIOS_ARRAY_HPP__ +#define __XIOS_ARRAY_HPP__ + +#define BZ_COLUMN_MAJOR_ARRAY +#include +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "message.hpp" +#include + +using namespace blitz ; +BZ_DECLARE_FUNCTION(round) +namespace xios +{ + +template +class CArray : public Array, public virtual CBaseType +{ + public : + using Array::operator = ; + typedef typename Array::T_default_storage T_default_storage; + + template explicit CArray(_bz_ArrayExpr expr) : Array(expr) {} + + CArray(GeneralArrayStorage storage=T_default_storage()) : Array(storage) {} + + explicit CArray(int length0,GeneralArrayStorage storage=T_default_storage() ) : Array(length0,storage ) {} + + CArray(int length0, int length1, GeneralArrayStorage storage=T_default_storage() ) : Array(length0, length1, storage ) {} + + CArray(int length0, int length1, int length2, GeneralArrayStorage storage=T_default_storage() ) : Array(length0, length1, length2, storage ) {} + + CArray(int length0, int length1, int length2, int length3, GeneralArrayStorage storage=T_default_storage() ) + : Array(length0, length1, length2, length3, storage ) {} + + CArray(int length0, int length1, int length2, int length3, int length4, GeneralArrayStorage storage=T_default_storage() ) + : Array(length0,length1, length2, length3, length4, storage ) {} + + CArray(int length0, int length1, int length2, int length3, int length4, int length5, GeneralArrayStorage storage=T_default_storage() ) + : Array(length0, length1, length2, length3, length4, length5, storage ) {} + + CArray(int length0, int length1, int length2, int length3, int length4, int length5, int length6, GeneralArrayStorage storage=T_default_storage() ) + : Array(length0, length1, length2, length3, length4, length5, length6, storage ) {} + + CArray(int length0, int length1, int length2, int length3, int length4, int length5, int length6, int length7, + GeneralArrayStorage storage=T_default_storage() ) : Array(length0, length1, length2, length3, length4, length5, length6, length7, storage ) {} + + CArray(int length0, int length1, int length2, int length3, int length4, int length5, int length6, + int length7, int length8, GeneralArrayStorage storage=T_default_storage() ) + : Array(length0, length1, length2, length3, length4, length5, length6, length7, length8, storage ) {} + + CArray(int length0, int length1, int length2, int length3, int length4, + int length5, int length6, int length7, int length8, int length9, GeneralArrayStorage storage=T_default_storage() ) + : Array(length0, length1, length2, length3, length4, length5, length6, length7, length8, length9, storage ) {} + + CArray(int length0, int length1, int length2, int length3, int length4, int length5, int length6, + int length7, int length8, int length9, int length10, GeneralArrayStorage storage=T_default_storage() ) + : Array(length0, length1, length2, length3, length4, length5, length6, length7, length8, + length9, length10, storage ) {} + + + CArray(T_numtype* restrict dataFirst, TinyVector shape, GeneralArrayStorage storage=T_default_storage() ) + : Array(dataFirst, shape, storage ) {} + + CArray(T_numtype* restrict dataFirst, TinyVector shape, TinyVector stride, + GeneralArrayStorage storage=T_default_storage()) : Array(dataFirst, shape, stride, storage ) {} + + CArray(T_numtype* restrict dataFirst, TinyVector shape, preexistingMemoryPolicy deletionPolicy, + GeneralArrayStorage storage=T_default_storage()) : Array(dataFirst, shape, deletionPolicy, storage) {} + + CArray(T_numtype* restrict dataFirst, TinyVector shape, TinyVector stride, + preexistingMemoryPolicy deletionPolicy, GeneralArrayStorage storage=T_default_storage()) + : Array(dataFirst, shape, stride, deletionPolicy, storage) {} + + CArray(const TinyVector& extent, GeneralArrayStorage storage=T_default_storage()) + : Array(extent, storage) {} + + CArray(const TinyVector& lbounds, const TinyVector& extent, + const GeneralArrayStorage& storage ) : Array(lbounds, extent, storage ) {} + + CArray(Range r0, GeneralArrayStorage storage=T_default_storage() ) : CArray(r0, storage ) {} + + CArray(Range r0, Range r1, GeneralArrayStorage storage=T_default_storage() ) : Array(r0, r1, storage ) {} + + CArray(Range r0, Range r1, Range r2, GeneralArrayStorage storage=T_default_storage() ) + : Array(r0, r1, r2, storage ) {} + + CArray(Range r0, Range r1, Range r2, Range r3, GeneralArrayStorage storage=T_default_storage() ) + : Array(r0, r1, r2, r3, storage ) {} + + CArray(Range r0, Range r1, Range r2, Range r3, Range r4, GeneralArrayStorage storage=T_default_storage() ) + : Array(r0, r1, r2, r3, r4, storage ) {} + + CArray(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, GeneralArrayStorage storage=T_default_storage() ) + : Array(r0, r1, r2, r3, r4, r5, storage ) {} + + CArray(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, + GeneralArrayStorage storage=T_default_storage() ) : Array(r0, r1, r2, r3, r4, r5, r6, storage ) {} + + CArray(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, + GeneralArrayStorage storage=T_default_storage() ) : Array(r0, r1, r2, r3, r4, r5, r6, r7, storage ) {} + + CArray(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, + Range r6, Range r7, Range r8, GeneralArrayStorage storage=T_default_storage() ) + : Array(r0, r1, r2, r3, r4, r5, r6, r7, r8, storage ) {} + + CArray(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, + Range r6, Range r7, Range r8, Range r9, GeneralArrayStorage storage=T_default_storage() ) + : Array(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, storage ) {} + + CArray(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, + Range r8, Range r9, Range r10, GeneralArrayStorage storage=T_default_storage() ) + : Array(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, storage ) {} + + CArray(const Array& array) : Array(array) {} + + CArray(const TinyVector& shape, int lastExtent, const GeneralArrayStorage& storage) + : Array(shape, lastExtent, storage) {} + + CArray(Array& array, Range r0) : Array(array, r0) {} + + CArray(Array& array, Range r0, Range r1) : Array(array, r0, r1) {} + + CArray(Array& array, Range r0, Range r1, Range r2) : Array( array, r0, r1, r2) {} + + CArray(Array& array, Range r0, Range r1, Range r2, Range r3) : Array(array, r0, r1, r2, r3) {} + + CArray(Array& array, Range r0, Range r1, Range r2, + Range r3, Range r4) : Array(array, r0, r1, r2, r3, r4) {} + + CArray(Array& array, Range r0, Range r1, Range r2, + Range r3, Range r4, Range r5) : Array( array, r0, r1, r2, r3, r4, r5) {} + + CArray(Array& array, Range r0, Range r1, Range r2, Range r3, + Range r4, Range r5, Range r6) : Array( array, r0, r1, r2, r3, r4, r5, r6) {} + + CArray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, + Range r5, Range r6, Range r7) : Array(array, r0, r1, r2, r3, r4, r5, r6, r7) {} + + CArray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, + Range r6, Range r7, Range r8) : Array(array, r0, r1, r2, r3, r4, r5, r6, r7, r8) {} + + CArray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, + Range r6, Range r7, Range r8, Range r9) : Array(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9) {} + + CArray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, + Range r7, Range r8, Range r9, Range r10) : Array(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10) {} + + CArray(Array& array, const RectDomain& subdomain) : Array(array, subdomain) {} + + CArray(Array& array, const StridedDomain& subdomain) : Array(array, subdomain) {} + + template + CArray(Array& array, R0 r0, R1 r1, R2 r2, R3 r3, R4 r4, R5 r5, R6 r6, R7 r7, R8 r8, R9 r9, R10 r10) + : Array(array, r0,r1, r2, r3, r4, r5, r6, r7, r8, r9, r10) {} + + virtual ~CArray() {} + virtual void fromString(const string& str) { istringstream iss(str) ; iss>>*this ; } + virtual string toString(void) const { ostringstream oss ; oss<<*this ; return oss.str() ; } + virtual void reset(void) { this->free(); } + virtual bool isEmpty(void) const { if (this->numElements()==0) return true; else return false; } + virtual size_t size(void) const { return (this->dimensions()+1)*sizeof(int)+sizeof(size_t) + this->numElements()*sizeof(T_numtype) ;} + + virtual CBaseType* clone(void) const { return new CArray(*this); } + + virtual bool toBuffer(CBufferOut& buffer) const + { + bool ret ; + ret=buffer.put(this->dimensions()) ; + ret&=buffer.put(this->shape().data(),this->dimensions()) ; + ret&=buffer.put(this->numElements()) ; + ret&=buffer.put(this->dataFirst(),this->numElements()) ; + return ret ; + } + + + virtual bool fromBuffer(CBufferIn& buffer) + { + + bool ret ; + int numDim ; + TinyVector vect; + size_t ne; + + ret=buffer.get(numDim) ; + ret&=buffer.get(vect.data(),N_rank) ; + this->resize(vect) ; + ret&=buffer.get(ne) ; + ret&=buffer.get(this->dataFirst(),ne) ; + return ret ; + } + +} ; + + template inline CBufferOut& operator<<(CBufferOut& buffer, const CArray& array) + { + if (!array.toBuffer(buffer)) ERROR(" template inline CBufferOut& operator<<(CBufferOut& buffer, const CArray& array)", + << "Buffer remain size is to low for size type") ; + return buffer ; + } + + template inline CBufferIn& operator>>(CBufferIn& buffer, CArray& array) + { + if (!array.fromBuffer(buffer)) ERROR("template inline CBufferIn& operator>>(CBufferIn& buffer, CArray& array)", + <<"Buffer remain size is to low for size type"); + return buffer ; + } + + template inline CMessage& operator<<(CMessage& msg, const CArray& array) + { + msg.push(array) ; + return msg ; + } + + template inline CMessage& operator<<(CMessage& msg, CArray& array) + { + msg.push(array) ; + return msg ; + } + + +} + +#endif diff --git a/src/attribute.cpp b/src/attribute.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6e07c34edd080626390a63e7e3a27ea623ceffd --- /dev/null +++ b/src/attribute.cpp @@ -0,0 +1,111 @@ +#include "attribute.hpp" +#include "base_type.hpp" +#include "generate_interface.hpp" + + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + CAttribute::CAttribute(const StdString & id) + : CObject(id), CBaseType() +// , value() + { /* Ne rien faire de plus */ } +/* + CAttribute::CAttribute(const CAttribute & attribut) + : CObject(attribut.getId()),CBaseType() + { + // this->value = attribut.getAnyValue(); + } +*/ + CAttribute::~CAttribute(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- +/* + const boost::any & CAttribute::getAnyValue(void) const + { + return (this->value); + } + + + void CAttribute::setAnyValue(const boost::any & value) + { + this->value = value; + } + + void CAttribute::clear(void) + { + this->value = boost::any(); + } + + //--------------------------------------------------------------- + + bool CAttribute::isEmpty(void) const + { + return (this->value.empty()); + } +*/ + const StdString & CAttribute::getName(void) const + { + return (this->getId()); + } + + void CAttribute::generateCInterfaceIsDefined(ostream& oss, const string& className) + { + CInterface::AttributeIsDefinedCInterface(oss, className, this->getName()) ; + } + + void CAttribute::generateFortran2003InterfaceIsDefined(ostream& oss, const string& className) + { + CInterface::AttributeIsDefinedFortran2003Interface(oss, className, this->getName()) ; + } + + + void CAttribute::generateFortranInterfaceIsDefinedDeclaration_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceIsDefinedDeclaration(oss, className, this->getName()+"_") ; + } + + void CAttribute::generateFortranInterfaceIsDefinedDeclaration(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceIsDefinedDeclaration(oss, className, this->getName()) ; + } + + void CAttribute::generateFortranInterfaceIsDefinedBody_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceIsDefinedBody(oss, className, this->getName()) ; + } + + ///-------------------------------------------------------------- + + + CMessage& operator<<(CMessage& msg,CAttribute& type) + { + msg.push(type) ; + return msg ; + } + + CMessage& operator<<(CMessage& msg, const CAttribute& type) + { +// msg.push(*type.clone()) ; + return msg ; + } + + CBufferOut& operator<<(CBufferOut& buffer, CAttribute& type) + { + + if (!type.toBuffer(buffer)) ERROR("CBufferOut& operator<<(CBufferOut& buffer, CAttribute& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + CBufferIn& operator>>(CBufferIn& buffer, CAttribute& type) + { + + if (!type.fromBuffer(buffer)) ERROR("CBufferInt& operator>>(CBufferIn& buffer, CAttribute& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + +} // namespace xios diff --git a/src/attribute.hpp b/src/attribute.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ef7d92bc70c466ee763a13e56bcad31056c84b7b --- /dev/null +++ b/src/attribute.hpp @@ -0,0 +1,118 @@ +#ifndef __XMLIO_CAttribute__ +#define __XMLIO_CAttribute__ + +/// boost headers /// +#include + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "object.hpp" +#include "base_type.hpp" +#include "message.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CAttribute : public CObject, public virtual CBaseType + { + typedef CObject SuperClass; + + public : + + /// Constructeurs /// + explicit CAttribute(const StdString & id); +// CAttribute(const CAttribute & attribut); +// CAttribute(const CAttribute * const attribut); // Not implemented. + + /// Accesseurs /// + const StdString & getName(void) const; +// const boost::any & getAnyValue(void) const; +// template inline T getValue(void) const; +// template inline T* getRef(void); + +// /// Mutateurs /// +// template inline void setValue(const T & value); +// void setAnyValue(const boost::any & value); +// void clear(void); + + /// Test /// +// bool isEmpty(void) const; +// template inline bool isType(void) const; + virtual void set(const CAttribute& ) =0 ; + virtual void reset(void ) =0 ; + /// Destructeur /// + virtual ~CAttribute(void); + + /// Autres /// + virtual StdString toString(void) const = 0; + virtual void fromString(const StdString & str) = 0; + +// virtual void toBinary (StdOStream & os) const = 0; +// virtual void fromBinary(StdIStream & is) = 0; + + virtual void generateCInterface(ostream& oss, const string& className) = 0 ; + virtual void generateCInterfaceIsDefined(ostream& oss, const string& className) ; + virtual void generateFortran2003Interface(ostream& oss, const string& className) = 0 ; + virtual void generateFortran2003InterfaceIsDefined(ostream& oss, const string& className) ; + virtual void generateFortranInterfaceDeclaration_(ostream& oss,const string& className) = 0 ; + virtual void generateFortranInterfaceDeclaration(ostream& oss,const string& className) = 0 ; + virtual void generateFortranInterfaceBody_(ostream& oss,const string& className) = 0 ; + virtual void generateFortranInterfaceGetDeclaration_(ostream& oss,const string& className) = 0 ; + virtual void generateFortranInterfaceGetDeclaration(ostream& oss,const string& className) = 0 ; + virtual void generateFortranInterfaceGetBody_(ostream& oss,const string& className) = 0 ; + virtual void generateFortranInterfaceIsDefinedDeclaration_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceIsDefinedDeclaration(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceIsDefinedBody_(ostream& oss,const string& className) ; + + virtual void setInheritedValue(const CAttribute& ) = 0 ; + virtual bool hasInheritedValue(void) const = 0; + + protected : + + /// Constructeurs /// +// CAttribute(void); // Not implemented. + + /// Propriété /// +// boost::any value; + + }; // class CAttribute + + /// ////////////////////// Définitions ////////////////////// /// +/* + template + T CAttribute::getValue(void) const + { + return (boost::any_cast(this->value)); + } + + template + T* CAttribute::getRef(void) + { + return (boost::any_cast(&value)); + } + + template + void CAttribute::setValue(const T & value) + { + this->value = value; + } + + template + bool CAttribute::isType(void) const + { + return (this->value.type() == typeid(T)); + } +*/ + + CMessage& operator<<(CMessage& msg,CAttribute& type) ; + CMessage& operator<<(CMessage& msg, const CAttribute& type) ; + + CBufferOut& operator<<(CBufferOut& buffer,CAttribute& type) ; + CBufferIn& operator>>(CBufferIn& buffer, CAttribute& type) ; + +} + // namespace xios + +#endif // __XMLIO_CAttribute__ diff --git a/src/attribute_array.hpp b/src/attribute_array.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c91ccb26e6a816304b548726d90acbecd0c08bd2 --- /dev/null +++ b/src/attribute_array.hpp @@ -0,0 +1,77 @@ +#ifndef __XIOS_ATTRIBUTE_ARRAY__ +#define __XIOS_ATTRIBUTE_ARRAY__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "attribute.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "array_new.hpp" + + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + template + class CAttributeArray : public CAttribute, public CArray + { + public : + + using CArray::operator = ; +// using Array::operator = ; + + /// Constructeurs /// + explicit CAttributeArray(const StdString & id); + CAttributeArray(const StdString & id, xios_map & umap); + CAttributeArray(const StdString & id, const CArray& value); + CAttributeArray(const StdString & id, const CArray& value, + xios_map & umap); + + /// Accesseur /// + CArray getValue(void) const; + + /// Mutateurs /// + void setValue(const CArray& value); + void set(const CAttribute& attr) ; + void set(const CAttributeArray& attr) ; + void reset(void) ; + void setInheritedValue(const CAttributeArray& attr ); + void setInheritedValue(const CAttribute& attr ); + CArray getInheritedValue(void) const ; + bool hasInheritedValue(void) const; + + /// Destructeur /// + virtual ~CAttributeArray(void) { } + + + /// Autre /// + virtual string toString(void) const { return _toString();} + virtual void fromString(const StdString & str) { _fromString(str);} + virtual bool toBuffer (CBufferOut& buffer) const { return _toBuffer(buffer);} + virtual bool fromBuffer(CBufferIn& buffer) { return _fromBuffer(buffer); } + + virtual void generateCInterface(ostream& oss,const string& className) ; + virtual void generateFortran2003Interface(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceDeclaration_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceBody_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceDeclaration(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetDeclaration_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetBody_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetDeclaration(ostream& oss,const string& className) ; + + + protected : + + /// Constructeurs /// + + private : + CArray inheritedValue ; + StdString _toString(void) const; + void _fromString(const StdString & str); + bool _toBuffer (CBufferOut& buffer) const; + bool _fromBuffer(CBufferIn& buffer) ; + }; // class CAttributeEnum +} // namespace xios + +#endif // __XIOS_ATTRIBUTE_ARRAY__ diff --git a/src/attribute_array_decl.cpp b/src/attribute_array_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d60663ddb0e096bc096f4637decb936ceaa5f1a8 --- /dev/null +++ b/src/attribute_array_decl.cpp @@ -0,0 +1,13 @@ +#include "attribute_array_impl.hpp" + + + +namespace xios +{ + template class CAttributeArray ; + template class CAttributeArray ; + template class CAttributeArray ; + template class CAttributeArray ; + template class CAttributeArray ; + template class CAttributeArray ; +} diff --git a/src/attribute_array_impl.hpp b/src/attribute_array_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3950ab31813c7b8b6e638b3ca69711895032267b --- /dev/null +++ b/src/attribute_array_impl.hpp @@ -0,0 +1,181 @@ +#ifndef __XIOS_ATTRIBUTE_ARRAY_IMPL_HPP__ +#define __XIOS_ATTRIBUTE_ARRAY_IMPL_HPP__ + +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "generate_interface.hpp" +#include "attribute_array.hpp" + + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + template + CAttributeArray::CAttributeArray(const StdString & id) + : CAttribute(id) + { /* Ne rien faire de plus */ } + + template + CAttributeArray::CAttributeArray(const StdString & id, const CArray& value) + : CAttribute(id) + { + this->setValue(value); + } + + template + CAttributeArray::CAttributeArray(const StdString & id, xios_map & umap) + : CAttribute(id) + { + umap.insert(umap.end(), std::make_pair(id, this)); + } + + template + CAttributeArray::CAttributeArray (const StdString & id, const CArray& value, + xios_map & umap) + : CAttribute(id) + { + this->setValue(value); + umap.insert(umap.end(), std::make_pair(id, this)); + } + + ///-------------------------------------------------------------- + + template + void CAttributeArray::reset(void) + { + CArray::reset() ; + inheritedValue.reset() ; + } + + template + CArray CAttributeArray::getValue(void) const + { + return this->copy() ; + } + + template + void CAttributeArray::setValue(const CArray& value) + { + this->resize(value.shape()) ; + *this=value ; + } + + template + void CAttributeArray::set(const CAttribute& attr) + { + this->set(dynamic_cast& >(attr)) ; + } + + template + void CAttributeArray::set(const CAttributeArray& attr) + { + this->setValue(attr) ; + } + + + template + void CAttributeArray::setInheritedValue(const CAttribute& attr) + { + this->setInheritedValue(dynamic_cast& >(attr)) ; + } + + template + void CAttributeArray::setInheritedValue(const CAttributeArray& attr) + { + if (this->isEmpty() && attr.hasInheritedValue()) + { + inheritedValue.resize(attr.shape()) ; + inheritedValue=attr ; + } + } + + template + CArray CAttributeArray::getInheritedValue(void) const + { + if (this->isEmpty()) return inheritedValue.copy() ; + else return getValue() ; + } + + template + bool CAttributeArray::hasInheritedValue(void) const + { + return !this->isEmpty() || !inheritedValue.isEmpty() ; + } + + + template + StdString CAttributeArray::_toString(void) const + { + StdOStringStream oss; + if (! isEmpty() && this->hasId()) oss << this->getName() << "=\"" << CArray::toString() << "\""; + return (oss.str()); + } + + template + void CAttributeArray::_fromString(const StdString & str) + { + CArray::fromString(str) ; + } + + template + bool CAttributeArray::_toBuffer (CBufferOut& buffer) const + { + return CArray::toBuffer(buffer) ; + } + + template + bool CAttributeArray::_fromBuffer(CBufferIn& buffer) + { + return CArray::fromBuffer(buffer) ; + } + + template + void CAttributeArray::generateCInterface(ostream& oss,const string& className) + { + CInterface::AttributeCInterface >(oss, className, this->getName()) ; + } + + template + void CAttributeArray::generateFortran2003Interface(ostream& oss,const string& className) + { + CInterface::AttributeFortran2003Interface >(oss, className, this->getName()) ; + } + + template + void CAttributeArray::generateFortranInterfaceDeclaration_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceDeclaration >(oss, className, this->getName()+"_") ; + } + + template + void CAttributeArray::generateFortranInterfaceBody_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceBody >(oss, className, this->getName()) ; + } + + template + void CAttributeArray::generateFortranInterfaceDeclaration(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceDeclaration >(oss, className, this->getName()) ; + } + + template + void CAttributeArray::generateFortranInterfaceGetDeclaration_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetDeclaration >(oss, className, this->getName()+"_") ; + } + + template + void CAttributeArray::generateFortranInterfaceGetBody_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetBody >(oss, className, this->getName()) ; + } + + template + void CAttributeArray::generateFortranInterfaceGetDeclaration(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetDeclaration >(oss, className, this->getName()) ; + } +} // namespace xios + +#endif // __XIOS_ATTRIBUTE_ENUM_IMPL_HPP__ diff --git a/src/attribute_enum.hpp b/src/attribute_enum.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1013ab4c8c95bb2f778ec1914b9d1c897a2efec3 --- /dev/null +++ b/src/attribute_enum.hpp @@ -0,0 +1,86 @@ +#ifndef __XIOS_ATTRIBUTE_ENUM__ +#define __XIOS_ATTRIBUTE_ENUM__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "attribute.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "type.hpp" +#include "enum.hpp" + + +namespace xios +{ + /// ////////////////////// Dclarations ////////////////////// /// + template + class CAttributeEnum : public CAttribute, public CEnum + { + typedef typename T::t_enum T_enum ; + public : + + /// Constructeurs /// + explicit CAttributeEnum(const StdString & id); + CAttributeEnum(const StdString & id, + xios_map & umap); + CAttributeEnum(const StdString & id, const T_enum & value); + CAttributeEnum(const StdString & id, const T_enum & value, + xios_map & umap); + + /// Accesseur /// + T_enum getValue(void) const; + string getStringValue(void) const; + + + /// Mutateurs /// + void setValue(const T_enum & value); + + void set(const CAttribute& attr) ; + void set(const CAttributeEnum& attr) ; + void reset(void); + + void setInheritedValue(const CAttributeEnum& attr ); + void setInheritedValue(const CAttribute& attr ); + T_enum getInheritedValue(void) const; + string getInheritedStringValue(void) const; + bool hasInheritedValue(void) const; + + /// Destructeur /// + virtual ~CAttributeEnum(void) { } + + /// Operateur /// + CAttributeEnum& operator=(const T_enum & value); + + /// Autre /// + virtual StdString toString(void) const { return _toString();} + virtual void fromString(const StdString & str) { _fromString(str);} + + virtual bool toBuffer (CBufferOut& buffer) const { return _toBuffer(buffer);} + virtual bool fromBuffer(CBufferIn& buffer) { return _fromBuffer(buffer); } + + virtual void generateCInterface(ostream& oss,const string& className) ; + virtual void generateFortran2003Interface(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceDeclaration_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceBody_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceDeclaration(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetDeclaration_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetBody_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetDeclaration(ostream& oss,const string& className) ; + + + protected : + + /// Constructeurs /// +// CAttributeTemplate(void); // Not implemented. + private : + StdString _toString(void) const; + void _fromString(const StdString & str); + bool _toBuffer (CBufferOut& buffer) const; + bool _fromBuffer(CBufferIn& buffer) ; + CEnum inheritedValue ; + }; // class CAttributeEnum + +} // namespace xios + +#endif // __XIOS_ATTRIBUTE_ENUM__ diff --git a/src/attribute_enum_impl.hpp b/src/attribute_enum_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8766eedd6fd96c9ca821c82471a379d0138be0e9 --- /dev/null +++ b/src/attribute_enum_impl.hpp @@ -0,0 +1,201 @@ +#ifndef __XIOS_ATTRIBUTE_ENUM_IMPL_HPP__ +#define __XIOS_ATTRIBUTE_ENUM_IMPL_HPP__ + +#include "enum.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "generate_interface.hpp" +#include "attribute_enum.hpp" + + +namespace xios +{ + /// ////////////////////// Dfinitions ////////////////////// /// + template + CAttributeEnum::CAttributeEnum(const StdString & id) + : CAttribute(id) + { /* Ne rien faire de plus */ } + + template + CAttributeEnum::CAttributeEnum(const StdString & id, const T_enum & value) + : CAttribute(id) + { + this->setValue(value); + } + + template + CAttributeEnum::CAttributeEnum(const StdString & id, + xios_map & umap) + : CAttribute(id) + { + umap.insert(umap.end(), std::make_pair(id, this)); + } + + template + CAttributeEnum::CAttributeEnum + (const StdString & id, const T_enum & value, + xios_map & umap) + : CAttribute(id) + { + this->setValue(value); + umap.insert(umap.end(), std::make_pair(id, this)); + } + + ///-------------------------------------------------------------- + template + void CAttributeEnum::reset(void) + { + CEnum::reset(); + inheritedValue.reset(); + } + + template + typename T::t_enum CAttributeEnum::getValue(void) const + { + return CEnum::get(); + } + + template + string CAttributeEnum::getStringValue(void) const + { + return CEnum::toString(); + } + + template + void CAttributeEnum::setValue(const typename T::t_enum & value) + { + CEnum::set(value); + } + + template + void CAttributeEnum::set(const CAttribute& attr) + { + this->set(dynamic_cast& >(attr)); + } + + template + void CAttributeEnum::set(const CAttributeEnum& attr) + { + CEnum::set(attr); + } + + template + void CAttributeEnum::setInheritedValue(const CAttribute& attr) + { + this->setInheritedValue(dynamic_cast& >(attr)); + } + + template + void CAttributeEnum::setInheritedValue(const CAttributeEnum& attr) + { + if (this->isEmpty() && attr.hasInheritedValue()) inheritedValue.set(attr.getInheritedValue()); + } + + template + typename T::t_enum CAttributeEnum::getInheritedValue(void) const + { + if (this->isEmpty()) return inheritedValue.get(); + else return getValue(); + } + + template + string CAttributeEnum::getInheritedStringValue(void) const + { + if (this->isEmpty()) return inheritedValue.toString(); + else return CEnum::toString(); + } + + template + bool CAttributeEnum::hasInheritedValue(void) const + { + return !this->isEmpty() || !inheritedValue.isEmpty(); + } + + //--------------------------------------------------------------- + + template + CAttributeEnum& CAttributeEnum::operator=(const T_enum & value) + { + this->setValue(value); + return *this; + } + + //--------------------------------------------------------------- + + template + StdString CAttributeEnum::_toString(void) const + { + StdOStringStream oss; + if (!CEnum::isEmpty() && this->hasId()) + oss << this->getName() << "=\"" << CEnum::toString() << "\""; + return (oss.str()); + } + + template + void CAttributeEnum::_fromString(const StdString & str) + { + CEnum::fromString(str); + } + + template + bool CAttributeEnum::_toBuffer (CBufferOut& buffer) const + { + return CEnum::toBuffer(buffer); + } + + template + bool CAttributeEnum::_fromBuffer(CBufferIn& buffer) + { + return CEnum::fromBuffer(buffer); + } + + template + void CAttributeEnum::generateCInterface(ostream& oss,const string& className) + { + CInterface::AttributeCInterface(oss, className, this->getName()); + } + + template + void CAttributeEnum::generateFortran2003Interface(ostream& oss,const string& className) + { + CInterface::AttributeFortran2003Interface(oss, className, this->getName()); + } + + template + void CAttributeEnum::generateFortranInterfaceDeclaration_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceDeclaration(oss, className, this->getName()+"_"); + } + + template + void CAttributeEnum::generateFortranInterfaceBody_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceBody(oss, className, this->getName()); + } + + template + void CAttributeEnum::generateFortranInterfaceDeclaration(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceDeclaration(oss, className, this->getName()); + } + + template + void CAttributeEnum::generateFortranInterfaceGetDeclaration_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetDeclaration(oss, className, this->getName()+"_"); + } + + template + void CAttributeEnum::generateFortranInterfaceGetBody_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetBody(oss, className, this->getName()); + } + + template + void CAttributeEnum::generateFortranInterfaceGetDeclaration(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetDeclaration(oss, className, this->getName()); + } +} // namespace xios + +#endif // __XIOS_ATTRIBUTE_ENUM_IMPL_HPP__ diff --git a/src/attribute_map.cpp b/src/attribute_map.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ea5dd724f96efba6eea2055541c978781e827d4 --- /dev/null +++ b/src/attribute_map.cpp @@ -0,0 +1,707 @@ +#include "attribute_map.hpp" +#include "indent.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + CAttributeMap * CAttributeMap::Current = NULL; + + CAttributeMap::CAttributeMap(void) + : xios_map() + { CAttributeMap::Current = this; } + + CAttributeMap::~CAttributeMap(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + void CAttributeMap::clearAllAttributes(void) + { + typedef std::pair StdStrAttPair; + SuperClassMap::const_iterator it = SuperClassMap::begin(), end = SuperClassMap::end(); + for (; it != end; it++) + { + const StdStrAttPair & att = *it; + att.second->reset(); + } + } + + //--------------------------------------------------------------- + + bool CAttributeMap::hasAttribute(const StdString & key) const + { + return (this->find(key) != this->end()); + } + + //--------------------------------------------------------------- + + void CAttributeMap::setAttribute(const StdString & key, CAttribute * const attr) + { + if (!this->hasAttribute(key)) + ERROR("CAttributeMap::setAttribute(key, attr)", + << "[ key = " << key << "] key not found !"); + if (attr == NULL) + ERROR("CAttributeMap::setAttribute(key, attr)", + << "[ key = " << key << "] attr is null !"); + this->find(key)->second->set(*attr) ; +// this->find(key)->second->setAnyValue(attr->getAnyValue()); + } + + //--------------------------------------------------------------- + + CAttribute * CAttributeMap::operator[](const StdString & key) + { + if (!this->hasAttribute(key)) + ERROR("CAttributeMap::operator[](const StdString & key)", + << "[ key = " << key << "] key not found !"); + return (SuperClassMap::operator[](key)); + } + + //--------------------------------------------------------------- + + StdString CAttributeMap::toString(void) const + { + typedef std::pair StdStrAttPair; + StdOStringStream oss; + + SuperClassMap::const_iterator it = SuperClassMap::begin(), end = SuperClassMap::end(); + for (; it != end; it++) + { + const StdStrAttPair & att = *it; + if (!att.second->isEmpty()) + oss << *att.second << " "; + } + return (oss.str()); + } + + //--------------------------------------------------------------- + + void CAttributeMap::fromString(const StdString & str) + { + ERROR("CAttributeMap::fromString(const StdString & str)", + << "[ str = " << str << "] Not implemented yet !"); + } + + //--------------------------------------------------------------- + + //StdOStream & operator << (StdOStream & os, const CAttributeMap & attributmap) + //{ os << attributmap.toString(); return (os); } + + //--------------------------------------------------------------- + + void CAttributeMap::setAttributes(const xml::THashAttributes & attributes) + { + for (xml::THashAttributes::const_iterator it = attributes.begin(); + it != attributes.end(); + it ++) + { + if ((*it).first.compare(StdString("id")) != 0 && + (*it).first.compare(StdString("src"))!= 0) + { + //if (CAttributeMap::operator[]((*it).first)->isEmpty()) + CAttributeMap::operator[]((*it).first)->fromString((*it).second); + } + } + } + + //--------------------------------------------------------------- + + void CAttributeMap::setAttributes(const CAttributeMap * const _parent, bool apply) + { + typedef std::pair StdStrAttPair; + + SuperClassMap::const_iterator it = _parent->begin(), end = _parent->end(); + for (; it != end; it++) + { + const StdStrAttPair & el = *it; + if (this->hasAttribute(el.first)) + { + CAttribute * currentAtt = CAttributeMap::operator[](el.first); + CAttribute * parentAtt = el.second ; + if (apply) + { + if (currentAtt->isEmpty() && !el.second->isEmpty()) + { + this->setAttribute(el.first, el.second); + } + } + else currentAtt->setInheritedValue(*parentAtt) ; + } + } + } + + //--------------------------------------------------------------- +/* + void CAttributeMap::toBinary(StdOStream & os) const + { + typedef std::pair StdStrAttPair; + SuperClassMap::const_iterator it = this->begin(), end = this->end(); + + const StdSize nbatt = SuperClassMap::size(); + os.write (reinterpret_cast(&nbatt) , sizeof(StdSize)); + + for (; it != end; it++) + { + const StdString & key = it->first; + const CAttribute* value = it->second; + const StdSize size = key.size(); + + os.write (reinterpret_cast(&size) , sizeof(StdSize)); + os.write (key.data(), size * sizeof(char)); + + if (!value->isEmpty()) + { + bool b = true; + os.write (reinterpret_cast(&b) , sizeof(bool)); + value->toBinary(os); + } + else + { + bool b = false; + os.write (reinterpret_cast(&b) , sizeof(bool)); + } + } + } + + //--------------------------------------------------------------- + + void CAttributeMap::fromBinary(StdIStream & is) + { + StdSize nbatt = 0; + is.read (reinterpret_cast(&nbatt), sizeof(StdSize)); + + for (StdSize i = 0; i < nbatt; i++) + { + bool hasValue = false; + StdSize size = 0; + is.read (reinterpret_cast(&size), sizeof(StdSize)); + StdString key(size, ' '); + is.read (const_cast(key.data()), size * sizeof(char)); + + if (!this->hasAttribute(key)) + ERROR("CAttributeMap::fromBinary(StdIStream & is)", + << "[ key = " << key << "] key not found !"); + + is.read (reinterpret_cast(&hasValue), sizeof(bool)); + + if (hasValue) + this->operator[](key)->fromBinary(is); + } + } + */ + void CAttributeMap::generateCInterface(ostream& oss, const string& className) + { + SuperClassMap::const_iterator it = SuperClassMap::begin(), end = SuperClassMap::end(); + for (; it != end; it++) + { + it->second->generateCInterface(oss,className) ; + it->second->generateCInterfaceIsDefined(oss,className) ; + oss<second->generateFortran2003Interface(oss,className) ; + it->second->generateFortran2003InterfaceIsDefined(oss,className) ; + + oss<second->getName()<<"_" ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceDeclaration_(oss,className) ; + } + + oss<second->generateFortranInterfaceBody_(oss,className) ; + oss<second->getName()<<"_" ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceGetDeclaration_(oss,className) ; + } + + oss<second->generateFortranInterfaceGetBody_(oss,className) ; + oss<second->getName()<<"_" ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceIsDefinedDeclaration_(oss,className) ; + } + + oss<second->generateFortranInterfaceIsDefinedBody_(oss,className) ; + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceDeclaration(oss,className) ; + } + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str() ; + delete oss2 ; + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceGetDeclaration(oss,className) ; + } + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str() ; + delete oss2 ; + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceIsDefinedDeclaration(oss,className) ; + } + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str() ; + delete oss2 ; + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceDeclaration(oss,className) ; + } + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str() ; + delete oss2 ; + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceGetDeclaration(oss,className) ; + } + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str() ; + delete oss2 ; + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str()<second->generateFortranInterfaceIsDefinedDeclaration(oss,className) ; + } + + oss<second->getName() ; + if (oss2->str().size()>90) + { + oss<str()<<" &"<str() ; + delete oss2 ; + + oss< + { + typedef xios_map SuperClassMap; + + public : + + /// Tests /// + inline bool hasAttribute(const StdString & key) const; + + /// Accesseurs /// + CAttribute * operator[](const StdString & key); + + /// Mutateurs /// + void setAttribute(const StdString & key, CAttribute * const attr); + + void setAttributes(const xml::THashAttributes & attributes); + void setAttributes(const CAttributeMap * const _parent, bool apply=true); + + void clearAllAttributes(void); + + /// Destructeur /// + virtual ~CAttributeMap(void); + + /// Flux /// + // Debug only // + // friend StdOStream & operator << (StdOStream & os, const CAttributeMap & attributmap); + + /// Autre /// + virtual StdString toString(void) const; + virtual void fromString(const StdString & str); + +// virtual void toBinary (StdOStream & os) const; +// virtual void fromBinary(StdIStream & is); + virtual void generateCInterface(ostream& oss, const string& className) ; + virtual void generateFortran2003Interface(ostream& oss, const string& className) ; + virtual void generateFortranInterface_hdl_(ostream& oss, const string& className) ; + virtual void generateFortranInterface_hdl(ostream& oss, const string& className) ; + virtual void generateFortranInterface_id(ostream& oss, const string& className) ; + virtual void generateFortranInterfaceGet_hdl_(ostream& oss, const string& className) ; + virtual void generateFortranInterfaceGet_hdl(ostream& oss, const string& className) ; + virtual void generateFortranInterfaceGet_id(ostream& oss, const string& className) ; + virtual void generateFortranInterfaceIsDefined_hdl_(ostream& oss, const string& className) ; + virtual void generateFortranInterfaceIsDefined_hdl(ostream& oss, const string& className) ; + virtual void generateFortranInterfaceIsDefined_id(ostream& oss, const string& className) ; + + protected : + + /// Constructeurs /// + CAttributeMap(void); + CAttributeMap(const xios_map & umap); // Never implemented. + CAttributeMap(const xios_map * const umap); // Not implemented. + + /// Propriété statique /// + static CAttributeMap * Current; + + }; // class CAttributeMap + +} // namespace xios + +#endif // __XMLIO_CAttributeMap__ diff --git a/src/attribute_template.hpp b/src/attribute_template.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5c7bc978634baddce130c29c2ebd26941e394351 --- /dev/null +++ b/src/attribute_template.hpp @@ -0,0 +1,104 @@ +#ifndef __XMLIO_CAttributeTemplate__ +#define __XMLIO_CAttributeTemplate__ + +/// boost headers /// +#include + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "attribute.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "type.hpp" + + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + template + class CAttributeTemplate : public CAttribute, public CType + { + typedef CAttribute SuperClass; + + public : + + /// Typedef /// + typedef T ValueType; + + /// Constructeurs /// + explicit CAttributeTemplate(const StdString & id); + CAttributeTemplate(const StdString & id, + xios_map & umap); + CAttributeTemplate(const StdString & id, const ValueType & value); + CAttributeTemplate(const StdString & id, const ValueType & value, + xios_map & umap); +// CAttributeTemplate(const CAttribute & attribut) throw (CException); +// CAttributeTemplate(const CAttribute * const attribut); // Not implemented. + + public : + + /// Accesseur /// + ValueType getValue(void) const; +// ValueType* getRef(void) ; + + /// Mutateurs /// + void setValue(const ValueType & value); + + void set(const CAttribute& attr) ; + void set(const CAttributeTemplate& attr) ; + void reset(void) ; + + void setInheritedValue(const CAttributeTemplate& attr ); + void setInheritedValue(const CAttribute& attr ); + T getInheritedValue(void) const ; + bool hasInheritedValue(void) const; + + /// Destructeur /// + virtual ~CAttributeTemplate(void) { } + + /// Operateur /// + CAttributeTemplate& operator=(const ValueType & value); + + /// Autre /// + virtual StdString toString(void) const { return _toString();} + virtual void fromString(const StdString & str) { _fromString(str);} +// virtual CAttributeTemplate* clone() const {} +// virtual void toBinary (StdOStream & os) const; +// virtual void fromBinary(StdIStream & is); + + virtual bool toBuffer (CBufferOut& buffer) const { return _toBuffer(buffer);} + virtual bool fromBuffer(CBufferIn& buffer) { return _fromBuffer(buffer); } +// virtual size_t size(void) const; + virtual void generateCInterface(ostream& oss,const string& className) ; + virtual void generateFortran2003Interface(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceDeclaration_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceBody_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceDeclaration(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetDeclaration_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetBody_(ostream& oss,const string& className) ; + virtual void generateFortranInterfaceGetDeclaration(ostream& oss,const string& className) ; +// virtual void generateFortranInterfaceIsDefinedDeclaration_(ostream& oss,const string& className) ; +// virtual void generateFortranInterfaceIsDefinedBody_(ostream& oss,const string& className) ; +// virtual void generateFortranInterfaceIsDefinedDeclaration(ostream& oss,const string& className) ; + + + protected : + + /// Constructeurs /// +// CAttributeTemplate(void); // Not implemented. + private : + StdString _toString(void) const; + void _fromString(const StdString & str); + bool _toBuffer (CBufferOut& buffer) const; + bool _fromBuffer(CBufferIn& buffer) ; + + CType inheritedValue ; + }; // class CAttribute + + + template void FromBinary(StdIStream & is, T & obj); + +} // namespace xios + +#endif // __XMLIO_CAttributeTemplate__ diff --git a/src/attribute_template_decl.cpp b/src/attribute_template_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e903518c63ca977189f36543f7f519df7af8ff43 --- /dev/null +++ b/src/attribute_template_decl.cpp @@ -0,0 +1,11 @@ +#include "attribute_template_impl.hpp" +#include "attribute_template_specialisation.hpp" +#include + +namespace xios +{ + template class CAttributeTemplate ; + template class CAttributeTemplate ; + template class CAttributeTemplate ; + template class CAttributeTemplate ; +} diff --git a/src/attribute_template_impl.hpp b/src/attribute_template_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..68b4dec4def05610d4442c43c507496237bfc75f --- /dev/null +++ b/src/attribute_template_impl.hpp @@ -0,0 +1,359 @@ +#ifndef __XMLIO_CAttributeTemplate_impl__ +#define __XMLIO_CAttributeTemplate_impl__ + +#include "type.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "generate_interface.hpp" +#include "attribute_template.hpp" + + +namespace xios +{ + + /// ////////////////////// Définitions ////////////////////// /// + template + CAttributeTemplate::CAttributeTemplate(const StdString & id) + : CAttribute(id) + { /* Ne rien faire de plus */ } + + template + CAttributeTemplate::CAttributeTemplate(const StdString & id, const T & value) + : CAttribute(id) + { + this->setValue(value); + } +/* + template + CAttributeTemplate::CAttributeTemplate(const CAttribute & attribut) + throw (CException) + : CAttribute(attribut) + { + if (!attribut.isEmpty() && !attribut.isType()) + ERROR("CAttributeTemplate", << "Invalid instantiation !"); + } +*/ + template + CAttributeTemplate::CAttributeTemplate(const StdString & id, + xios_map & umap) + : CAttribute(id) + { + umap.insert(umap.end(), std::make_pair(id, this)); + } + + template + CAttributeTemplate::CAttributeTemplate + (const StdString & id, const T & value, + xios_map & umap) + : CAttribute(id) + { + this->setValue(value); + umap.insert(umap.end(), std::make_pair(id, this)); + } +/* + template + CAttributeTemplate::~CAttributeTemplate(void) + { +// this->CType::reset() ; +// this->clear(); + } +*/ + ///-------------------------------------------------------------- + template + void CAttributeTemplate::reset(void) + { + CType::reset() ; + inheritedValue.reset() ; + } + + + template + T CAttributeTemplate::getValue(void) const + { + return CType::get() ; +/* + if (SuperClass::isEmpty()) + { + ERROR("T CAttributeTemplate::getValue(void) const", + << "[ id = " << this->getId() << "]" + << " L'attribut est requis mais n'est pas défini !"); + } + return (SuperClass::getValue()); +*/ + } + +/* + template + T* CAttributeTemplate::getRef(void) + { + if (SuperClass::isEmpty()) + { + ERROR("T CAttributeTemplate::getValue(void) const", + << "[ id = " << this->getId() << "]" + << " L'attribut est requis mais n'est pas défini !"); + } + return (SuperClass::getRef()); + } +*/ + + template + void CAttributeTemplate::setValue(const T & value) + { + CType::set(value) ; +// SuperClass::setValue(value); + } + + template + void CAttributeTemplate::set(const CAttribute& attr) + { + this->set(dynamic_cast& >(attr)) ; + } + + template + void CAttributeTemplate::set(const CAttributeTemplate& attr) + { + CType::set(attr) ; + } + + template + void CAttributeTemplate::setInheritedValue(const CAttribute& attr) + { + this->setInheritedValue(dynamic_cast& >(attr)) ; + } + + template + void CAttributeTemplate::setInheritedValue(const CAttributeTemplate& attr) + { + if (this->isEmpty() && attr.hasInheritedValue()) inheritedValue.set(attr.getInheritedValue()) ; + } + + template + T CAttributeTemplate::getInheritedValue(void) const + { + if (this->isEmpty()) return inheritedValue.get() ; + else return getValue() ; + } + + template + bool CAttributeTemplate::hasInheritedValue(void) const + { + return !this->isEmpty() || !inheritedValue.isEmpty() ; + } + + //--------------------------------------------------------------- + + template + CAttributeTemplate& CAttributeTemplate::operator=(const T & value) + { + this->setValue(value); +// return (this->getValue()); + return *this; + } + + //--------------------------------------------------------------- + + template + StdString CAttributeTemplate::_toString(void) const + { + StdOStringStream oss; + if (!CType::isEmpty() && this->hasId()) + oss << this->getName() << "=\"" << CType::toString() << "\""; + return (oss.str()); + } + + template + void CAttributeTemplate::_fromString(const StdString & str) + { + CType::fromString(str) ; + } + + //--------------------------------------------------------------- +/* + template + void CAttributeTemplate::toBinary (StdOStream & os) const + { + this->getValue()->toBinary(os); + } + + template + void CAttributeTemplate::fromBinary(StdIStream & is) + { + T value; + FromBinary(is, value); + this->setValue(value); + } +*/ + template + bool CAttributeTemplate::_toBuffer (CBufferOut& buffer) const + { + return CType::toBuffer(buffer) ; +/* + if (isEmpty()) return buffer.put(true) ; + else + { + bool ret=true ; + CType val(*boost::any_cast(&value)) ; + ret&=buffer.put(false) ; + ret&=val.toBuffer(buffer) ; + return ret ; + } +*/ + } + + template + bool CAttributeTemplate::_fromBuffer(CBufferIn& buffer) + { + return CType::fromBuffer(buffer) ; +/* + bool empty ; + bool ret=true ; + ret&=buffer.get(empty) ; + if (empty) + { + clear() ; + return ret ; + } + else + { + if (isEmpty()) + { + T val ; + setValue(val) ; + } + T* V=const_cast(boost::any_cast(&value)) ; + CType val(*V) ; + return val.fromBuffer(buffer) ; + } +*/ + } +/* + template + size_t CAttributeTemplate::size(void) const + { + return CType::size() ;*/ +/* + if (isEmpty()) return sizeof(bool) ; + else + { + CType val(*const_cast(boost::any_cast(&value))) ; + return val.size()+sizeof(bool) ; + } +*/ + /* }*/ + + template + void CAttributeTemplate::generateCInterface(ostream& oss,const string& className) + { + CInterface::AttributeCInterface(oss, className, this->getName()) ; +// CInterface::AttributeIsDefinedCInterface(oss, className, this->getName()) ; + } + + template + void CAttributeTemplate::generateFortran2003Interface(ostream& oss,const string& className) + { + CInterface::AttributeFortran2003Interface(oss, className, this->getName()) ; +// CInterface::AttributeIsDefinedFortran2003Interface(oss, className, this->getName()) ; + } + + template + void CAttributeTemplate::generateFortranInterfaceDeclaration_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceDeclaration(oss, className, this->getName()+"_") ; + } + + template + void CAttributeTemplate::generateFortranInterfaceBody_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceBody(oss, className, this->getName()) ; + } + + template + void CAttributeTemplate::generateFortranInterfaceDeclaration(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceDeclaration(oss, className, this->getName()) ; + } + + template + void CAttributeTemplate::generateFortranInterfaceGetDeclaration_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetDeclaration(oss, className, this->getName()+"_") ; + } + + + template + void CAttributeTemplate::generateFortranInterfaceGetBody_(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetBody(oss, className, this->getName()) ; + } + + template + void CAttributeTemplate::generateFortranInterfaceGetDeclaration(ostream& oss,const string& className) + { + CInterface::AttributeFortranInterfaceGetDeclaration(oss, className, this->getName()) ; + } + + +/* + //--------------------------------------------------------------- + + // Spécialisations des templates pour la fonction [toString] + + template <> + StdString CAttributeTemplate::toString(void) const; + + //--------------------------------------------------------------- + + // Spécialisations des templates pour la fonction [fromString] + + template <> // Chaîne de caractères. + void CAttributeTemplate::fromString(const StdString & str); + + template <> // Entier + void CAttributeTemplate::fromString(const StdString & str); + + template <> // Booléen + void CAttributeTemplate::fromString(const StdString & str); + + template <> // Double + void CAttributeTemplate::fromString(const StdString & str); + + template<> // Tableau + void CAttributeTemplate::fromString(const StdString & str); + + //--------------------------------------------------------------- + + // Spécialisations des templates pour la fonction [toBinary] // + + template <> // Chaîne de caractères. + void CAttributeTemplate::toBinary (StdOStream & os) const; + + template <> // Entier + void CAttributeTemplate::toBinary(StdOStream & os) const; + + template <> // Booléen + void CAttributeTemplate::toBinary(StdOStream & os) const; + + template <> // Double + void CAttributeTemplate::toBinary(StdOStream & os) const; + + //--------------------------------------------------------------- + + // Spécialisations des templates pour la fonction [fromBinary] // + + template <> // Chaîne de caractères. + void CAttributeTemplate::fromBinary(StdIStream & is); + + template <> // Entier + void CAttributeTemplate::fromBinary(StdIStream & is); + + template <> // Booléen + void CAttributeTemplate::fromBinary(StdIStream & is); + + template <> // Double + void CAttributeTemplate::fromBinary(StdIStream & is); + + ///-------------------------------------------------------------- +*/ +} // namespace xios + +#endif // __XMLIO_CAttributeTemplate_impl__ diff --git a/src/attribute_template_specialisation.hpp b/src/attribute_template_specialisation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9d564e37126a72f1dcb6b36134617654083dedf9 --- /dev/null +++ b/src/attribute_template_specialisation.hpp @@ -0,0 +1,217 @@ +#include "attribute_template.hpp" +#include "attribute_template_impl.hpp" + +#include + +namespace xios +{ +/* + /// ////////////////////// Définitions ////////////////////// /// + + /// Spécialisations des templates pour la fonction [toString] /// + + template <> + StdString CAttributeTemplate::toString(void) const + { + StdOStringStream oss; + if (!this->isEmpty() && this->hasId()) + { + if (this->getValue()) + oss << this->getName() << "=\".TRUE.\""; + else + oss << this->getName() << "=\".FALSE.\""; + } + return (oss.str()); + } + + //--------------------------------------------------------------- + + /// Spécialisations des templates pour la fonction [fromString] /// + + template <> // Chaîne de caractères. + void CAttributeTemplate::fromString(const StdString & str) + { + this->setValue(str); + } + + template <> // Entier + void CAttributeTemplate::fromString(const StdString & str) + { + try + { + this->setValue(boost::lexical_cast(str)); + } + catch(boost::bad_lexical_cast &) + { + ERROR("void CAttributeTemplate::fromString(const StdString & str)", + << "[ str = " << str << " ] Bad cast !"); + } + } + + template <> // Double + void CAttributeTemplate::fromString(const StdString & str) + { + if (str.find("max") != StdString::npos) + { + this->setValue(DBL_MAX); + return; + } + if (str.find("min") != StdString::npos) + { + this->setValue(DBL_MIN); + return; + } + + try + { + this->setValue(boost::lexical_cast(str)); + } + catch(boost::bad_lexical_cast &) + { + ERROR("void CAttributeTemplate::fromString(const StdString & str)", + << "[ str = " << str << " ] Bad cast !"); + } + } + + template <> // Booléen + void CAttributeTemplate::fromString(const StdString & str) + { + if (str.find(".TRUE.") != StdString::npos) + this->setValue(true); + else + this->setValue(false); + } + + //--------------------------------------------------------------- + + template<> // Tableau + void CAttributeTemplate::fromString(const StdString & str) + { + ARRAY_CREATE(array_sptr, double, 1, [1]); + CArray & array = *array_sptr; + this->setValue(array_sptr); + + StdIStringStream iss(str) ; + char c = '\0'; int size = 0; + double d = 0.,valsup = 0., valinf = 0.; + std::vector vect; + + iss >> d; vect.push_back(d); + size = vect.size(); + if (!iss.eof ()) + { + iss >> c; + switch (c) + { + case ',' : // Le tableau est généré valeur par valeur. + iss.unget(); + while(!iss.eof ()) + { // On récupère chacune des valeurs une par une jusqu'à ce que le buffer soit vide. + iss >> c >> d; + if (c != ',') + ERROR("CAttributeTemplate::fromString(const StdString & str)", + << "[ str = " << str << " ] bad definition of array !"); + vect.push_back(d); + } + size = vect.size(); + break; + case '(' : // Le tableau est généré automatiquement. + if (!iss.eof ()) + { // on récupère la borne supérieure + valinf = d; + iss >> size >> c >> d; + if ((c != ')') || (size <= 0)) + ERROR("CAttributeTemplate::fromString(const StdString & str)", + << "[ str = " << str << " ] bad definition of array !"); + valsup = d; + } + d = (valsup - valinf) / (double)(size - 1); + for (int j = 1; j <= size; j++) + vect.push_back(valinf + j * d); + break; + default : + ERROR("CAttributeTemplate::fromString(const StdString & str)", + << "[ str = " << str << " ] bad definition of array !"); + } + } + + array.resize(boost::extents[size]); + for (int i = 0; i < size; i++) + array[i] = vect[i]; + + } + + //--------------------------------------------------------------- + + /// Spécialisations des templates pour la fonction [toBinary] /// + + template <> // Chaîne de caractères. + void CAttributeTemplate::toBinary (StdOStream & os) const + { + StdString str = this->getValue(); + StdSize size = str.size(); + os.write (reinterpret_cast(&size) , sizeof(StdSize)); + os.write (str.data(), size * sizeof(char)); + } + + template <> // Entier + void CAttributeTemplate::toBinary(StdOStream & os) const + { + int value = this->getValue(); + os.write (reinterpret_cast(&value) , sizeof(int)); + } + + template <> // Booléen + void CAttributeTemplate::toBinary(StdOStream & os) const + { + bool value = this->getValue(); + os.write (reinterpret_cast(&value) , sizeof(bool)); + } + + template <> // Double + void CAttributeTemplate::toBinary(StdOStream & os) const + { + double value = this->getValue(); + os.write (reinterpret_cast(&value) , sizeof(double)); + } + + //--------------------------------------------------------------- + + /// Spécialisations des templates pour la fonction [fromBinary] /// + + template <> // Chaîne de caractères. + void CAttributeTemplate::fromBinary(StdIStream & is) + { + StdSize size = 0; + is.read (reinterpret_cast(&size), sizeof(StdSize)); + StdString value(size, ' '); + is.read (const_cast(value.data()), size * sizeof(char)); + this->setValue(value); + } + + template <> // Entier + void CAttributeTemplate::fromBinary(StdIStream & is) + { + int value = 0; + is.read (reinterpret_cast(&value), sizeof(int)); + this->setValue(value); + } + + template <> // Booléen + void CAttributeTemplate::fromBinary(StdIStream & is) + { + bool value = false; + is.read (reinterpret_cast(&value), sizeof(bool)); + this->setValue(value); + } + + template <> // Double + void CAttributeTemplate::fromBinary(StdIStream & is) + { + double value = 0.; + is.read (reinterpret_cast(&value), sizeof(double)); + this->setValue(value); + } + ///-------------------------------------------------------------- +*/ +} // namespace xios diff --git a/src/buffer.cpp b/src/buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9515b8ed33b30e5dce677afbb07f8e18c36fa1a7 --- /dev/null +++ b/src/buffer.cpp @@ -0,0 +1,49 @@ +#include "xmlioserver_spl.hpp" +#include "buffer.hpp" + + +namespace xios +{ + CBuffer::CBuffer(void* buffer_,size_t size_) + { + own=false ; + realloc(buffer_,size_) ; + } + + CBuffer::CBuffer(size_t size_) + { + own=false ; + realloc(size_) ; + } + + void CBuffer::realloc(size_t size_) + { + realloc(new char[size_],size_) ; + own=true ; + } + + void CBuffer::realloc(void* buffer_,size_t size_) + { + if (own) delete [] buffer ; + buffer=(char*)buffer_ ; + size=size_ ; + count=0 ; + read=buffer ; + write=buffer ; + own=false ; + } + + size_t CBuffer::remain(void) + { + return size-count ; + } + + CBuffer::~CBuffer() + { + if (own) delete [] buffer ; + } + +} + + + diff --git a/src/buffer.hpp b/src/buffer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7236995637d43c0f95d8005b32fc941635d07fbf --- /dev/null +++ b/src/buffer.hpp @@ -0,0 +1,78 @@ +#ifndef __BUFFER_HPP__ +#define __BUFFER_HPP__ + + +#include "xmlioserver_spl.hpp" + +namespace xios +{ + + class CBuffer + { + + public: + + CBuffer(size_t size) ; + CBuffer(void* buffer,size_t size) ; + + void realloc(size_t size) ; + void realloc(void* buffer,size_t size) ; + + template + bool put(const T& data) ; + + template + bool put(const T* data, size_t n) ; + + template + bool put_ptr(const T*& data_ptr, size_t n) ; + + template + bool get(T& data) ; + + template + bool get(T* data, size_t n) ; + + template + bool get_ptr(T*& data, size_t n) ; + + + + template + bool put_template(const T& data) ; + + template + bool put_template(const T* data, size_t n) ; + + template + bool put_ptr_template(const T*& data, size_t n) ; + + template + bool get_template(T& data) ; + + template + bool get_template(T* data, size_t n) ; + + template + bool get_ptr_template(T*& data, size_t n) ; + + size_t remain(void) ; + + ~CBuffer() ; + char* buffer ; + char* read ; + char* write ; + size_t count ; + bool own ; + size_t size ; + } ; + + + + +} + +//#include "buffer_impl.hpp" + + +#endif diff --git a/src/buffer_client.cpp b/src/buffer_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d67a57b293d47ede69f0081ecd33a4eafc93025d --- /dev/null +++ b/src/buffer_client.cpp @@ -0,0 +1,110 @@ +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "log.hpp" +#include "buffer_out.hpp" +#include "buffer_client.hpp" +#include "cxios.hpp" +#include "mpi.hpp" +#include "tracer.hpp" + +namespace xios +{ + + size_t maxRequestSize=0 ; + + CClientBuffer::CClientBuffer(MPI_Comm interComm_,int serverRank_) + { + bufferSizeByServer=CXios::bufferSize ; + info(10)<<"bufferSizeByServer "<maxRequestSize) maxRequestSize=size ; + + if (size>bufferSize) ERROR("CClientBuffer::hasSpace(int size)", + <<"request size is too big for buffer, increase buffer client size"< "<realloc(buffer[current]+count,size) ; + count+=size ; + return retBuffer ; + } + else + { + ERROR("CBufferOut* CClientBuffer::getSpace(int size) ;", + <<"No ennough space in buffer, that may not happen..."); + return NULL ; + } + + } + + bool CClientBuffer::checkBuffer(void) + { + MPI_Status status ; + int flag ; + + if (pending) + { + traceOff() ; + MPI_Test(&request,&flag,&status) ; + traceOn() ; + if (flag==true) pending=false ; + } + + if (!pending) + { + if (count>0) + { + MPI_Issend(buffer[current],count,MPI_CHAR,serverRank,20,interComm,&request) ; + pending=true ; + if (current==1) current=0 ; + else current=1 ; + count=0 ; + } + } + return pending ; + } + + bool CClientBuffer::hasPendingRequest(void) + { + if (pending) return true ; + else if (count>0) return true ; + else return false ; + } + + + +} + diff --git a/src/buffer_client.hpp b/src/buffer_client.hpp new file mode 100644 index 0000000000000000000000000000000000000000..332e190026e170705c0128e992dbca171af7586a --- /dev/null +++ b/src/buffer_client.hpp @@ -0,0 +1,44 @@ +#ifndef __BUFFER_CLIENT_HPP__ +#define __BUFFER_CLIENT_HPP__ + +#include "xmlioserver_spl.hpp" +#include "buffer_out.hpp" +#include "mpi.hpp" + +namespace xios +{ + extern size_t maxRequestSize ; + + class CClientBuffer + { + + public: + + CClientBuffer(MPI_Comm intercomm,int serverRank) ; + ~CClientBuffer() ; + bool isBufferFree(int size) ; + CBufferOut* getBuffer(int size) ; + bool checkBuffer(void) ; + bool hasPendingRequest(void) ; + + char* buffer[2] ; + int remain(void) ; + + int current ; + int count ; + int bufferSize ; + int serverRank ; + bool pending ; + + size_t bufferSizeByServer ; + + MPI_Request request ; + + CBufferOut* retBuffer; + MPI_Comm interComm ; + } ; + +} + +#endif + diff --git a/src/buffer_decl.cpp b/src/buffer_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf811b24a7efe0222c71d36f5b39f0c9bdba9b76 --- /dev/null +++ b/src/buffer_decl.cpp @@ -0,0 +1,25 @@ +#include "buffer.hpp" +#include "buffer_impl.hpp" + +namespace xios +{ +# define macro(T) \ + template bool CBuffer::put_template(const T& data) ; \ + template bool CBuffer::put_template(const T* data, size_t n) ; \ + template bool CBuffer::put_ptr_template(const T*& data, size_t n) ; \ + template bool CBuffer::get_template(T& data) ; \ + template bool CBuffer::get_template(T* data, size_t n) ; \ + template bool CBuffer::get_ptr_template(T*& data, size_t n) ; + + + macro(char) + macro(int) + macro(short) + macro(long) + macro(uint) + macro(ushort) + macro(ulong) + macro(float) + macro(double) + macro(long double) +} diff --git a/src/buffer_impl.hpp b/src/buffer_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bcaa03ca08324ed516c1a351599d608e845deea6 --- /dev/null +++ b/src/buffer_impl.hpp @@ -0,0 +1,175 @@ +#ifndef __BUFFER_IMPL_HPP__ +#define __BUFFER_IMPL_HPP__ + +namespace xios +{ + +// template spectialisation : CBuffer::put + template <> bool CBuffer::put(const char& data) { return put_template(data) ; } + template <> bool CBuffer::put(const int& data) { return put_template(data) ; } + template <> bool CBuffer::put(const short& data) { return put_template(data) ; } + template <> bool CBuffer::put(const long& data) { return put_template(data) ; } + template <> bool CBuffer::put(const uint& data) { return put_template(data) ; } + template <> bool CBuffer::put(const ushort& data) { return put_template(data) ; } + template <> bool CBuffer::put(const ulong& data) { return put_template(data) ; } + template <> bool CBuffer::put(const float& data) { return put_template(data) ; } + template <> bool CBuffer::put(const double& data) { return put_template(data) ; } + template <> bool CBuffer::put(const long double& data) { return put_template(data) ;} + + template <> bool CBuffer::put(const char* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const int* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const short* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const long* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const uint* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const ushort* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const ulong* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const float* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const double* data, size_t n) { return put_template(data,n) ; } + template <> bool CBuffer::put(const long double* data, size_t n) { return put_template(data,n) ;} + + + template <> bool CBuffer::put_ptr(const char*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const int*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const short*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const long*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const uint*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const ushort*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const ulong*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const float*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const double*& data, size_t n) { return put_ptr_template(data,n) ; } + template <> bool CBuffer::put_ptr(const long double*& data, size_t n) { return put_ptr_template(data,n) ;} + + +// template spectialisation : CBuffer::get + template <> bool CBuffer::get(char& data) { return get_template(data) ; } + template <> bool CBuffer::get(int& data) { return get_template(data) ; } + template <> bool CBuffer::get(short& data) { return get_template(data) ; } + template <> bool CBuffer::get(long& data) { return get_template(data) ; } + template <> bool CBuffer::get(uint& data) { return get_template(data) ; } + template <> bool CBuffer::get(ushort& data) { return get_template(data) ; } + template <> bool CBuffer::get(ulong& data) { return get_template(data) ; } + template <> bool CBuffer::get(float& data) { return get_template(data) ; } + template <> bool CBuffer::get(double& data) { return get_template(data) ; } + template <> bool CBuffer::get(long double& data) { return get_template(data) ;} + + template <> bool CBuffer::get(char* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(int* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(short* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(long* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(uint* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(ushort* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(ulong* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(float* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(double* data, size_t n) { return get_template(data,n) ; } + template <> bool CBuffer::get(long double* data, size_t n) { return get_template(data,n) ;} + + template <> bool CBuffer::get_ptr(char*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(int*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(short*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(long*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(uint*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(ushort*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(ulong*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(float*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(double*& data, size_t n) { return get_ptr_template(data,n) ; } + template <> bool CBuffer::get_ptr(long double*& data, size_t n) { return get_ptr_template(data,n) ;} + + + template + bool CBuffer::put_template(const T& data) + { + return put_template(&data,1); + } + + template + bool CBuffer::put_template(const T* data, size_t n) + { + bool ret; + char* dataBuff ; + + size_t dataSize=sizeof(T)*n ; + + if (count+dataSize<=size) + { + dataBuff=(char*) data ; + for(size_t i=0;i + bool CBuffer::put_ptr_template(const T*& data, size_t n) + { + bool ret; + char* dataBuff ; + + size_t dataSize=sizeof(T)*n ; + + if (count+dataSize<=size) + { + data=(T*) write ; + write+=dataSize ; + count+=dataSize; + ret=true ; + } + else ret=false ; + + return ret ; + } + + + template + bool CBuffer::get_template(T& data) + { + return get_template(&data,1) ; + + } + + template + bool CBuffer::get_template(T* data, size_t n) + { + bool ret; + char* dataBuff ; + + size_t dataSize=sizeof(T)*n ; + + if (read+dataSize<=buffer+size) + { + dataBuff=(char*) data ; + for(size_t i=0;i + bool CBuffer::get_ptr_template(T*& data, size_t n) + { + bool ret; + char* dataBuff ; + + size_t dataSize=sizeof(T)*n ; + + if (read+dataSize<=buffer+size) + { + data=(T*) read ; + read+=dataSize ; + ret=true ; + } + else ret=false ; + + return ret ; + } + +} + + +#endif diff --git a/src/buffer_in.cpp b/src/buffer_in.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4da5ae96d8cbffdff9d57dc02c3eaa5b5c380459 --- /dev/null +++ b/src/buffer_in.cpp @@ -0,0 +1,69 @@ +#include "xmlioserver_spl.hpp" +#include "buffer_in.hpp" + + +namespace xios +{ + CBufferIn::CBufferIn(void* buffer,size_t size) + { + own=false ; + realloc(buffer,size) ; + } + + CBufferIn::CBufferIn(size_t size) + { + own=false ; + realloc(size) ; + } + + CBufferIn::CBufferIn(void) + { + own=false ; + realloc(0,0) ; + } + + void CBufferIn::realloc(size_t size) + { + realloc(new char[size_],size) ; + own=true ; + } + + void CBufferIn::realloc(void* buffer,size_t size) + { + if (own) delete [] begin ; + begin=(char*)buffer ; + size_=size ; + current=begin ; + end=begin+size_ ; + count_=0 ; + own=false ; + } + + bool CBufferIn::advance(size_t n) { return advance(n); } + + size_t CBufferIn::remain(void) + { + return size_-count_ ; + } + + size_t CBufferIn::count(void) + { + return count_ ; + } + + size_t CBufferIn::size(void) + { + return size_ ; + } + + CBufferIn::~CBufferIn() + { + if (own) delete [] begin ; + } + + void* CBufferIn::ptr(void) { return current; } + +} + + + diff --git a/src/buffer_in.hpp b/src/buffer_in.hpp new file mode 100644 index 0000000000000000000000000000000000000000..64b5bbd350128a69020b3bf52070b36d06442337 --- /dev/null +++ b/src/buffer_in.hpp @@ -0,0 +1,64 @@ +#ifndef __BUFFER_IN_HPP__ +#define __BUFFER_IN_HPP__ + + +#include "xmlioserver_spl.hpp" + +namespace xios +{ + + class CBufferIn + { + + public: + + CBufferIn(size_t size) ; + CBufferIn(void) ; + CBufferIn(void* buffer,size_t size) ; + + void realloc(size_t size) ; + void realloc(void* buffer,size_t size) ; + + + template + bool advance(size_t n) ; + + bool advance(size_t n) ; + + template + bool get(T& data) ; + + template + bool get(T* data, size_t n) ; + + template + bool advance_template(size_t n) ; + + template + bool get_template(T& data) ; + + template + bool get_template(T* data, size_t n) ; + + void* ptr(void) ; + + + size_t remain(void) ; + size_t count(void) ; + size_t size(void) ; + ~CBufferIn() ; + + char* begin ; + char* end ; + char* current ; + size_t count_ ; + size_t size_ ; + bool own ; + } ; + +} + +//#include "buffer_in_impl.hpp" + + +#endif diff --git a/src/buffer_in_decl.cpp b/src/buffer_in_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d23748800bf310053d95357946df382c304ef579 --- /dev/null +++ b/src/buffer_in_decl.cpp @@ -0,0 +1,23 @@ +#include "buffer_in.hpp" +#include "buffer_in_impl.hpp" + +namespace xios +{ +# define macro(T) \ + template bool CBufferIn::get_template(T& data); \ + template bool CBufferIn::get_template(T* data, size_t n); \ + template bool CBufferIn::advance_template(size_t n); + + + macro(char) + macro(int) + macro(short) + macro(long) + macro(uint) + macro(ushort) + macro(ulong) + macro(float) + macro(double) + macro(long double) +} + diff --git a/src/buffer_in_impl.hpp b/src/buffer_in_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ff8ec8ce7b2c9c2bea5b3e8ff690d9352fd59842 --- /dev/null +++ b/src/buffer_in_impl.hpp @@ -0,0 +1,94 @@ +#ifndef __BUFFER_IN_IMPL_HPP__ +#define __BUFFER_IN_IMPL_HPP__ + +namespace xios +{ + +// template spectialisation : CBufferIn::get + + template <> bool CBufferIn::get(char& data) { return get_template(data) ; } + template <> bool CBufferIn::get(bool& data) { return get_template(data) ; } + template <> bool CBufferIn::get(int& data) { return get_template(data) ; } + template <> bool CBufferIn::get(short& data) { return get_template(data) ; } + template <> bool CBufferIn::get(long& data) { return get_template(data) ; } + template <> bool CBufferIn::get(uint& data) { return get_template(data) ; } + template <> bool CBufferIn::get(ushort& data) { return get_template(data) ; } + template <> bool CBufferIn::get(ulong& data) { return get_template(data) ; } + template <> bool CBufferIn::get(float& data) { return get_template(data) ; } + template <> bool CBufferIn::get(double& data) { return get_template(data) ; } + template <> bool CBufferIn::get(long double& data) { return get_template(data) ;} + + template <> bool CBufferIn::get(char* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(bool* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(int* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(short* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(long* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(uint* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(ushort* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(ulong* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(float* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(double* data, size_t n) { return get_template(data,n) ; } + template <> bool CBufferIn::get(long double* data, size_t n) { return get_template(data,n) ;} + + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferIn::advance(size_t n) { return advance_template(n) ;} + + template + bool CBufferIn::get_template(T& data) + { + return get_template(&data,1) ; + } + + template + bool CBufferIn::get_template(T* data, size_t n) + { + bool ret; + char* dataBuff ; + + size_t dataSize=sizeof(T)*n ; + + if (count_+dataSize<=size_) + { + dataBuff=(char*) data ; + for(size_t i=0;i + bool CBufferIn::advance_template(size_t n) + { + bool ret; + char* dataBuff ; + + size_t dataSize=sizeof(T)*n ; + + if (count_+dataSize<=size_) + { + current+=dataSize ; + count_+=dataSize ; + ret=true ; + } + else ret=false ; + + return ret ; + } + +} + + +#endif diff --git a/src/buffer_out.cpp b/src/buffer_out.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66471eadd539f86377f6b7773ca789c89d36d5ae --- /dev/null +++ b/src/buffer_out.cpp @@ -0,0 +1,72 @@ +#include "xmlioserver_spl.hpp" +#include "buffer_out.hpp" + + +namespace xios +{ + CBufferOut::CBufferOut(void* buffer,size_t size) + { + own=false ; + realloc(buffer,size) ; + } + + CBufferOut::CBufferOut(void) + { + own=false ; + realloc(0,0) ; + } + + CBufferOut::CBufferOut(size_t size) + { + own=false ; + realloc(size) ; + } + + void CBufferOut::realloc(size_t size) + { + realloc(new char[size],size) ; + own=true ; + } + + void CBufferOut::realloc(void* buffer,size_t size) + { + if (own) delete [] begin ; + begin=(char*)buffer ; + size_=size ; + end=begin+size_ ; + count_=0 ; + current=begin ; + own=false ; + } + + bool CBufferOut::advance(size_t n) { return advance(n); } + + void* CBufferOut::ptr(void) + { + return current ; + } + + size_t CBufferOut::remain(void) + { + return size_-count_ ; + } + + size_t CBufferOut::count(void) + { + return count_ ; + } + + size_t CBufferOut::size(void) + { + return size_ ; + } + + CBufferOut::~CBufferOut() + { + if (own) delete [] begin ; + } + +} + + + diff --git a/src/buffer_out.hpp b/src/buffer_out.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ebdd3bcbbbf6f09ea1cbea73386f7bd61818a0a6 --- /dev/null +++ b/src/buffer_out.hpp @@ -0,0 +1,66 @@ +#ifndef __BUFFER_OUT_HPP__ +#define __BUFFER_OUT_HPP__ + + +#include "xmlioserver_spl.hpp" + +namespace xios +{ + + class CBufferOut + { + + public: + + CBufferOut(size_t size) ; + CBufferOut(void) ; + CBufferOut(void* buffer,size_t size) ; + + void realloc(size_t size) ; + void realloc(void* buffer,size_t size) ; + + template + bool put(const T& data) ; + + template + bool put(const T* data, size_t n) ; + + + template + bool advance(size_t n) ; + + bool advance(size_t n) ; + + + + template + bool put_template(const T& data) ; + + template + bool put_template(const T* data, size_t n) ; + + template + bool advance_template(size_t n) ; + + void* ptr(void) ; + + size_t remain(void) ; + size_t count(void) ; + size_t size(void) ; + + ~CBufferOut() ; + char* begin ; + char* current ; + char* end; + size_t count_ ; + size_t size_ ; + bool own ; + } ; + + +} + +//#include "buffer_out_impl.hpp" + + +#endif diff --git a/src/buffer_out_decl.cpp b/src/buffer_out_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6621dd4b19bedaca42aaaa801dc11b8a5061a7db --- /dev/null +++ b/src/buffer_out_decl.cpp @@ -0,0 +1,23 @@ +#include "buffer_out.hpp" +#include "buffer_out_impl.hpp" + + +namespace xios +{ +# define macro(T) \ + template bool CBufferOut::put_template(const T& data) ; \ + template bool CBufferOut::put_template(const T* data, size_t n) ; \ + template bool CBufferOut::advance_template(size_t n) ; \ + + + macro(char) + macro(int) + macro(short) + macro(long) + macro(uint) + macro(ushort) + macro(ulong) + macro(float) + macro(double) + macro(long double) +} diff --git a/src/buffer_out_impl.hpp b/src/buffer_out_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a1d3a6566cf64572fdccb0c6c85a68a7adfd62be --- /dev/null +++ b/src/buffer_out_impl.hpp @@ -0,0 +1,94 @@ +#ifndef __BUFFER_OUT_IMPL_HPP__ +#define __BUFFER_OUT_IMPL_HPP__ + +namespace xios +{ + +// template spectialisation : CBufferIn::put + template <> bool CBufferOut::put(const char& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const bool& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const int& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const short& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const long& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const uint& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const ushort& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const ulong& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const float& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const double& data) { return put_template(data) ; } + template <> bool CBufferOut::put(const long double& data) { return put_template(data) ;} + + template <> bool CBufferOut::put(const char* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const bool* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const int* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const short* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const long* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const uint* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const ushort* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const ulong* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const float* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const double* data, size_t n) { return put_template(data,n) ; } + template <> bool CBufferOut::put(const long double* data, size_t n) { return put_template(data,n) ;} + + + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ; } + template <> bool CBufferOut::advance(size_t n) { return advance_template(n) ;} + + template + bool CBufferOut::put_template(const T& data) + { + return put_template(&data,1); + } + + template + bool CBufferOut::put_template(const T* data, size_t n) + { + bool ret; + char* dataBuff ; + + size_t dataSize=sizeof(T)*n ; + + if (count_+dataSize<=size_) + { + dataBuff=(char*) data ; + for(size_t i=0;i + bool CBufferOut::advance_template(size_t n) + { + bool ret; + char* dataBuff ; + + size_t dataSize=sizeof(T)*n ; + + if (count_+dataSize<=size_) + { + current+=dataSize ; + count_+=dataSize; + ret=true ; + } + else ret=false ; + + return ret ; + } + +} + + +#endif diff --git a/src/buffer_server.cpp b/src/buffer_server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e3e908bac546c6704febd91559c54f5ccd18733e --- /dev/null +++ b/src/buffer_server.cpp @@ -0,0 +1,172 @@ +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "buffer_server.hpp" +#include "cxios.hpp" + +namespace xios +{ + + CServerBuffer::CServerBuffer(void) + { + bufferSizeByClient=CXios::bufferSize*CXios::bufferServerFactorSize ; + size=bufferSizeByClient ; + first=0 ; + current=1 ; + end=size ; + buffer=new char[size] ; // change later for MPI_ALLOC_MEM later + } + + CServerBuffer::~CServerBuffer() + { + delete [] buffer ; + } + + + bool CServerBuffer::isBufferFree(size_t count) + { + bool ret ; + + if (count==0) return true ; + + if (current>first) + { + if (current+count0) + { + ret=true ; + } + else + { + ret=false ; + } + } + else + { + if (countfirst) + { + if (current+count0) + { + ret=buffer+current ; + current=0 ; + } + else + { + ERROR("void* CServerBuffer::getBuffer(size_t count)", + <<"cannot allocate required size in buffer") ; + } + } + else + { + end=current ; + if (countgetId() + << ", start: " << this->initDate + << ", current: " << this->currentDate << "]"; + return (oss.str()); + } + + void CCalendar::fromString(const StdString & str) + { ERROR("CCalendar::fromString(str)", + << "[ str = " << str << "] Not implemented yet !"); } + + //----------------------------------------------------------------- + + void CCalendar::setTimeStep(const CDuration & duration) + { this->timestep = duration; } + + CDate & CCalendar::update(int step) + { + info(20) << "update step : " << step <<" timestep "<timestep << std::endl; + return (this->getCurrentDate() = this->getInitDate() + step * this->timestep); + } + + //----------------------------------------------------------------- + + const CDuration & CCalendar::getTimeStep(void) const { return (this->timestep); } + const CDate & CCalendar::getInitDate(void) const { return (this->initDate); } + const CDate & CCalendar::getTimeOrigin(void) const { return (this->timeOrigin); } + CDate & CCalendar::getCurrentDate(void) { return (this->currentDate); } + + //----------------------------------------------------------------- + + int CCalendar::getMonthLength(const CDate & date) const + { // Retourne la durée du mois en jour. + static const int NoLeapMonthLength[] = + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + return (NoLeapMonthLength[date.getMonth()-1]); + } + + StdString CCalendar::getType(void) const { return (StdString(this->getId())); } + + int CCalendar::getYearTotalLength(const CDate & date) const { return (365 * 86400); } + + int CCalendar::getYearLength (void) const { return (12); } + int CCalendar::getDayLength (void) const { return (24); } + int CCalendar::getHourLength (void) const { return (60); } + int CCalendar::getMinuteLength(void) const { return (60); } + + int CCalendar::getNbSecond(const CDate & date) const + { // Retourne le nombre de secondes écoulées depuis le début de l'année. + CDate _d0(date); int nbday = 0; + + for(_d0.setMonth(1); _d0.getMonth() < date.getMonth(); _d0.setMonth(_d0.getMonth()+1)) + nbday += getMonthLength(_d0); + return ((((nbday + date.getDay()) * getDayLength() + date.getHour()) * getHourLength() + + date.getMinute()) * getMinuteLength() + date.getSecond()); + } + + StdString CCalendar::getMonthName(int month_id) const + { + static const StdString Monthname_str[] = + { "january", "february", "march" , "april" , "may" , "june" , + "july" , "august" , "september", "october", "november", "december" }; + return(Monthname_str[month_id-1]); + } + + const StdString CCalendar::getMonthShortName(int month_id) const + { StdString value = this->getMonthName(month_id); value.resize(3); return (value); } + + ///---------------------------------------------------------------- + +} // namespace xios diff --git a/src/calendar.hpp b/src/calendar.hpp new file mode 100644 index 0000000000000000000000000000000000000000..157eed64cc9c3918c2ec881691289c832e3f6696 --- /dev/null +++ b/src/calendar.hpp @@ -0,0 +1,101 @@ +#ifndef __XMLIO_CCalendar__ +#define __XMLIO_CCalendar__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "date.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + + typedef enum _monthEnum + { JAN = 1, FEB = 2, MAR = 3, APR = 4 , MAY = 5 , JUN = 6 , + JUL = 7, AUG = 8, SEP = 9, OCT = 10, NOV = 11, DEC = 12 } MonthEnum; + + ///--------------------------------------------------------------- + + class CDate; + + class CCalendar : public CObject + { + /// Typedef /// + typedef CObject SuperClass; + + public : + + /// Destructeur /// + virtual ~CCalendar(void); + + protected : + + /// Constructeurs /// + CCalendar(void); + CCalendar(const StdString & id) ; + CCalendar(const StdString & id, + int yr, int mth, int d, + int hr = 0, int min = 0, int sec = 0); + CCalendar(const StdString & id, const StdString & dateStr); + CCalendar(const StdString & id, const StdString & dateStr, const StdString & timeOrigin); + + CCalendar(const CCalendar & calendar); // Not implemented yet. + CCalendar(const CCalendar * const calendar); // Not implemented yet. + + public : + + //------------------------------------------------------------ + + /// Autres /// + virtual StdString toString(void) const; + virtual void fromString(const StdString & str); + + /// Mutateur /// + void setTimeStep(const CDuration & duration); + + /// Traitemants /// + CDate & update(int step); + + /// Accesseurs /// + const CDuration & getTimeStep(void) const; + const CDate & getInitDate(void) const; + const CDate & getTimeOrigin(void) const; + CDate & getCurrentDate(void); + + public : + + //------------------------------------------------------------ + virtual int getMonthLength(const CDate & date) const ; + + virtual StdString getType(void) const; + + virtual int getYearTotalLength(const CDate & date) const ; // Retourne la durée d'une année en seconde. + + virtual int getYearLength (void) const; // Retourne la durée d'une année en mois. + virtual int getDayLength (void) const; // Retourne la durée d'un jour en heures. + virtual int getHourLength (void) const; // Retourne la durée d'une heure en minute. + virtual int getMinuteLength(void) const; // Retourne la durée d'une minute en secondes. + + virtual int getNbSecond(const CDate & date) const; + virtual StdString getMonthName(int month_id) const; + + virtual const StdString getMonthShortName(int month_id) const; + void initializeDate(int yr, int mth, int d, int hr = 0, int min = 0, int sec = 0) ; + void initializeDate(const StdString & dateStr); + void initializeDate(const StdString & dateStr, const StdString & timeOrigin); + + //------------------------------------------------------------ + + private : + + /// Propriétés privées /// + CDate initDate; + CDate timeOrigin; + CDate currentDate; + CDuration timestep; + + }; // class CCalendar + +} // namespace xios + +#endif // __XMLIO_CCalendar__ diff --git a/src/calendar_util.cpp b/src/calendar_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b86a69669569ae66dd836225b1fe30b125670f2f --- /dev/null +++ b/src/calendar_util.cpp @@ -0,0 +1,195 @@ +#include "calendar_util.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + CDuration operator*(const double & scal, const CDuration & ddr) + { return (ddr * scal); } + + CDuration operator-(const CDuration & ddr , const CDuration & dr) + { + CDuration dur(ddr); + dur.year -= dr.year; dur.month -= dr.month ; dur.day -= dr.day; + dur.hour -= dr.hour; dur.minute -= dr.minute; dur.second -= dr.second; dur.timestep -= dr.timestep; + return (dur); + } + + CDuration operator+(const CDuration & ddr , const CDuration & dr) + { + CDuration dur(ddr); + dur.year += dr.year; dur.month += dr.month ; dur.day += dr.day; + dur.hour += dr.hour; dur.minute += dr.minute; dur.second += dr.second; dur.timestep += dr.timestep; + return (dur); + } + + CDuration operator*(const CDuration & ddr , const double & scal) + { + CDuration dur(ddr); + dur.year *= scal; dur.month *= scal; dur.day *= scal; + dur.hour *= scal; dur.minute *= scal; dur.second *= scal; dur.timestep *= scal; + return (dur); + } + + CDuration operator-(const CDuration & ddr) + { + CDuration dur(ddr); + dur.year = -dur.year; + dur.month = -dur.month; + dur.day = -dur.day; + dur.hour = -dur.hour; + dur.minute = -dur.minute; + dur.second = -dur.second; + dur.timestep = -dur.timestep; + return (dur); + } + + //----------------------------------------------------------------- + + CDate operator+(const CDate & dt, const CDuration & dr) + { + CDuration drr (dr); + int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0; + const CCalendar & c = dt.getRelCalendar(); + + drr.timestep=0 ; + drr=drr+dr.timestep*dt.getRelCalendar().getTimeStep() ; + + drr.resolve(dt.getRelCalendar()); + + // Ajustement des minutes par rapport aux secondes. + second += dt.getSecond() + drr.second; + if (second < 0) { minute --; second += c.getMinuteLength(); } + if (second >= c.getMinuteLength()) { minute ++; second -= c.getMinuteLength(); } + + // Ajustement des heures en fonction des minutes. + minute += dt.getMinute() + drr.minute; + if (minute < 0) { hour --; minute += c.getHourLength(); } + if (minute >= c.getHourLength()) { hour ++; minute -= c.getHourLength(); } + + // Ajustement des jours en fonction des heures. + hour += dt.getHour() + drr.hour; + if (hour < 0) { drr.day --; hour += c.getDayLength(); } + if (hour >= c.getDayLength()) { drr.day ++; hour -= c.getDayLength(); } + + // Ajustement des mois en fonction des jours. + CDate dtt(dt); + drr.day+=dtt.getDay()-1 ; + dtt.setDay(1) ; + + if ( drr.day >= 0 ) + { + for(; c.getMonthLength(dtt) <= drr.day; dtt.addMonth (1)) + { drr.day -= c.getMonthLength(dtt); drr.month += 1 ; } + + day = drr.day+1 ; + } + else + { + dtt.addMonth(-1) ; + drr.month-=1 ; + for(; c.getMonthLength(dtt) < -drr.day; dtt.addMonth (-1)) + { drr.day+=c.getMonthLength(dtt) ; drr.month-=1 ; } + day=c.getMonthLength(dtt)+drr.day+1 ; + } + +/* + if (day < 0) { drr.month --; day += c.getMonthLength(dtt); } + if (day > c.getMonthLength(dtt)) { drr.month ++; day -= c.getMonthLength(dtt); } // << Problème ici + if (day == 0){ day = c.getMonthLength(dtt); drr.month --; } +*/ + drr.resolve(dt.getRelCalendar()); + + // Ajustement des années en fonction des mois. + month += dt.getMonth() + drr.month; + if (month < 0) { drr.year --; month += c.getYearLength(); } + if (month > c.getYearLength()) { drr.year ++; month -= c.getYearLength(); } + if (month == 0){ month = c.getYearLength(); drr.year--; } + + year += dt.getYear() + drr.year; + + return (CDate(dt.getRelCalendar(), year, month, day, hour, minute, second)); + } + + CDate operator-(const CDate & dt, const CDuration & dr) { return (dt + (-dr)); } + + //----------------------------------------------------------------- + + CDuration operator-(const CDate & dt0, const CDate & dt1) + { + // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier. + CDuration dur = + { dt0.getYear() - dt1.getYear(), dt0.getMonth() - dt1.getMonth() , dt0.getDay() - dt1.getDay(), + dt0.getHour() - dt1.getHour(), dt0.getMinute() - dt1.getMinute(), dt0.getSecond() - dt1.getSecond() }; + return (dur.resolve(dt0.getRelCalendar())); + } + + //----------------------------------------------------------------- + + /// Les opérateurs de comparaison. (Non testés pour le moment) + bool operator==(const CDate& dt0, const CDate& dt1) + { + // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier. + return ((dt0.getYear() == dt1.getYear()) && (dt0.getMonth() == dt1.getMonth()) && (dt1.getDay() == dt0.getDay()) && + (dt0.getHour() == dt1.getHour()) && (dt0.getMinute() == dt1.getMinute()) && (dt1.getSecond() == dt0.getSecond())); + } + + bool operator< (const CDate& dt0, const CDate& dt1) + { + // TODO :: Vérifier que les deux dates (dt0 et dt1) ont une référence vers le même calendrier. + if (dt0.getYear() < dt1.getYear()) + { + return true; + } + else if (dt0.getYear() == dt1.getYear()) + { + if (dt0.getMonth() < dt1.getMonth()) + { + return true; + } + else if (dt0.getMonth() == dt1.getMonth()) + { + if (dt0.getDay() < dt1.getDay()) + { + return true; + } + else if (dt0.getDay() == dt1.getDay()) + { + if (dt0.getHour() < dt1.getHour()) + { + return true; + } + else if (dt0.getHour() == dt1.getHour()) + { + if (dt0.getMinute() < dt1.getMinute()) + { + return true; + } + else if (dt0.getMinute() == dt1.getMinute()) + { + if (dt0.getSecond() < dt1.getSecond()) + return true; + } + } + } + } + } + return false; + } + + //----------------------------------------------------------------- + + bool operator!=(const CDate & dt0, const CDate & dt1){ return !(dt1 == dt0); } + bool operator> (const CDate & dt0, const CDate & dt1){ return (dt1 < dt0); } + bool operator>=(const CDate & dt0, const CDate & dt1){ return ((dt0 > dt1) || (dt1 == dt0)); } + bool operator<=(const CDate & dt0, const CDate & dt1){ return ((dt0 < dt1) || (dt1 == dt0)); } + + ///---------------------------------------------------------------- + +} // namespace xios + + + + + + diff --git a/src/calendar_util.hpp b/src/calendar_util.hpp new file mode 100644 index 0000000000000000000000000000000000000000..476ad566dcbc35733c3bf9bc2b8a9aca6a0bb755 --- /dev/null +++ b/src/calendar_util.hpp @@ -0,0 +1,37 @@ +#ifndef __XMLIO_CCalendar_util__ +#define __XMLIO_CCalendar_util__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "calendar.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + + CDuration operator*(const double & scal, const CDuration & ddr); + CDuration operator-(const CDuration & ddr , const CDuration & dr); + CDuration operator+(const CDuration & ddr , const CDuration & dr); + CDuration operator*(const CDuration & ddr , const double & scal); + CDuration operator-(const CDuration & ddr); + + CDate operator+(const CDate & dt, const CDuration & dr); // Non testée. + CDate operator-(const CDate & dt, const CDuration & dr); + + CDuration operator-(const CDate & dt0, const CDate & dt1); + + /// Les opérateurs de comparaison. (Non testés pour le moment) + bool operator==(const CDate& dt0, const CDate& dt1); + bool operator< (const CDate& dt0, const CDate& dt1); + + bool operator!=(const CDate & dt0, const CDate & dt1); + bool operator> (const CDate & dt0, const CDate & dt1); + bool operator>=(const CDate & dt0, const CDate & dt1); + bool operator<=(const CDate & dt0, const CDate & dt1); + + ///--------------------------------------------------------------- + +} // namespace xios + +#endif //__XMLIO_CCalendar_util__ diff --git a/src/client.cpp b/src/client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a58e83f49537c9eb0f06727a806288278a6d8720 --- /dev/null +++ b/src/client.cpp @@ -0,0 +1,316 @@ +#include "globalScopeData.hpp" +#include "xmlioserver_spl.hpp" +#include "cxios.hpp" +#include "client.hpp" +#include +#include "type.hpp" +#include "context.hpp" +#include "context_client.hpp" +#include "oasis_cinterface.hpp" +#include "mpi.hpp" +#include "timer.hpp" +#include "buffer_client.hpp" + +namespace xios +{ + + MPI_Comm CClient::intraComm ; + MPI_Comm CClient::interComm ; + int CClient::serverLeader ; + bool CClient::is_MPI_Initialized ; + int CClient::rank = INVALID_RANK; + StdOFStream CClient::m_infoStream; + StdOFStream CClient::m_errorStream; + + void CClient::initialize(const string& codeId,MPI_Comm& localComm,MPI_Comm& returnComm) + { + int initialized ; + MPI_Initialized(&initialized) ; + if (initialized) is_MPI_Initialized=true ; + else is_MPI_Initialized=false ; + +// don't use OASIS + if (!CXios::usingOasis) + { +// localComm doesn't given + if (localComm == MPI_COMM_NULL) + { + if (!is_MPI_Initialized) + { + int argc=0; + char** argv=NULL; + MPI_Init(&argc,&argv) ; + } + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS init").resume() ; + boost::hash hashString ; + + unsigned long hashClient=hashString(codeId) ; + unsigned long hashServer=hashString(CXios::xiosCodeId) ; + unsigned long* hashAll ; + int size ; + int myColor ; + int i,c ; + MPI_Comm newComm ; + + MPI_Comm_size(CXios::globalComm,&size) ; + MPI_Comm_rank(CXios::globalComm,&rank); + + hashAll=new unsigned long[size] ; + + MPI_Allgather(&hashClient,1,MPI_LONG,hashAll,1,MPI_LONG,CXios::globalComm) ; + + map colors ; + map leaders ; + + for(i=0,c=0;iinitClient(contextComm,contextInterComm) ; + } + else + { + MPI_Comm contextInterComm ; + MPI_Comm_dup(contextComm,&contextInterComm) ; + context->initClient(contextComm,contextInterComm) ; + context->initServer(contextComm,contextInterComm) ; + } + } + + void CClient::finalize(void) + { + int rank ; + int msg=0 ; + if (!CXios::isServer) + { + MPI_Comm_rank(intraComm,&rank) ; + if (rank==0) + { + MPI_Send(&msg,1,MPI_INT,0,0,interComm) ; + } + } + + CTimer::get("XIOS finalize").suspend() ; + CTimer::get("XIOS").suspend() ; + + if (!is_MPI_Initialized) + { + if (CXios::usingOasis) oasis_finalize(); + else MPI_Finalize() ; + } + info(20) << "Client side context is finalized"<open(fileNameClient.str().c_str(), std::ios::out); + if (!fb->is_open()) + ERROR("void CClient::openStream(const StdString& fileName, const StdString& ext, std::filebuf* fb)", + << std::endl << "Can not open <" << fileNameClient << "> file to write the client log(s)."); + } + + /*! + * \brief Open a file stream to write the info logs + * Open a file stream with a specific file name suffix+rank + * to write the info logs. + * \param fileName [in] protype file name + */ + void CClient::openInfoStream(const StdString& fileName) + { + std::filebuf* fb = m_infoStream.rdbuf(); + openStream(fileName, ".out", fb); + + info.write2File(fb); + report.write2File(fb); + } + + //! Write the info logs to standard output + void CClient::openInfoStream() + { + info.write2StdOut(); + report.write2StdOut(); + } + + //! Close the info logs file if it opens + void CClient::closeInfoStream() + { + if (m_infoStream.is_open()) m_infoStream.close(); + } + + /*! + * \brief Open a file stream to write the error log + * Open a file stream with a specific file name suffix+rank + * to write the error log. + * \param fileName [in] protype file name + */ + void CClient::openErrorStream(const StdString& fileName) + { + std::filebuf* fb = m_errorStream.rdbuf(); + openStream(fileName, ".err", fb); + + error.write2File(fb); + } + + //! Write the error log to standard error output + void CClient::openErrorStream() + { + error.write2StdErr(); + } + + //! Close the error log file if it opens + void CClient::closeErrorStream() + { + if (m_errorStream.is_open()) m_errorStream.close(); + } +} diff --git a/src/client.hpp b/src/client.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3b26831ddd1aadce98edfd3315c7fab109961121 --- /dev/null +++ b/src/client.hpp @@ -0,0 +1,47 @@ +#ifndef __CLIENT_HPP__ +#define __CLIENT_HPP__ + +#include "xmlioserver_spl.hpp" +#include "mpi.hpp" + +namespace xios +{ + class CClient + { + public: + static void initialize(const string& codeId, MPI_Comm& localComm, MPI_Comm& returnComm); + static void finalize(void); + static void registerContext(const string& id, MPI_Comm contextComm); + + static MPI_Comm intraComm; + static MPI_Comm interComm; + static int serverLeader; + static bool is_MPI_Initialized ; + + //! Get rank of the current process + static int getRank(); + + //! Open a file stream to write the info logs + static void openInfoStream(const StdString& fileName); + //! Write the info logs to standard output + static void openInfoStream(); + //! Close the info logs file if it opens + static void closeInfoStream(); + + //! Open a file stream to write the error log + static void openErrorStream(const StdString& fileName); + //! Write the error log to standard error output + static void openErrorStream(); + //! Close the error log file if it opens + static void closeErrorStream(); + + protected: + static int rank; + static StdOFStream m_infoStream; + static StdOFStream m_errorStream; + + static void openStream(const StdString& fileName, const StdString& ext, std::filebuf* fb); + }; +} + +#endif diff --git a/src/config/axis_attribute.conf b/src/config/axis_attribute.conf new file mode 100644 index 0000000000000000000000000000000000000000..84f76e58f1bb56c21a6735e56da64166d4d5f784 --- /dev/null +++ b/src/config/axis_attribute.conf @@ -0,0 +1,14 @@ +DECLARE_ATTRIBUTE(StdString, name) +DECLARE_ATTRIBUTE(StdString, standard_name) +DECLARE_ATTRIBUTE(StdString, long_name) + +DECLARE_ATTRIBUTE(StdString, unit) + +DECLARE_ATTRIBUTE(int, size) +DECLARE_ATTRIBUTE(int, zoom_begin) +DECLARE_ATTRIBUTE(int, zoom_end) +DECLARE_ATTRIBUTE(int, zoom_size) +DECLARE_ENUM2(positive, up, down) +DECLARE_ARRAY(double, 1, value) + + diff --git a/src/config/calendar_type.conf b/src/config/calendar_type.conf new file mode 100644 index 0000000000000000000000000000000000000000..67f8ab4c0fe752f45e587f081adc640f6dd48c80 --- /dev/null +++ b/src/config/calendar_type.conf @@ -0,0 +1,21 @@ +#ifdef __XMLIO_CAllLeapCalendar__ + DECLARE_CALENDAR(AllLeap , AllLeap) +#endif //__XMLIO_CAllLeapCalendar__ + +#ifdef __XMLIO_CD360Calendar__ + DECLARE_CALENDAR(D360 , D360) +#endif //__XMLIO_CD360Calendar__ + +#ifdef __XMLIO_CGregorianCalendar__ + DECLARE_CALENDAR(Gregorian , Gregorian) +#endif //__XMLIO_CGregorianCalendar__ + +#ifdef __XMLIO_CJulianCalendar__ + DECLARE_CALENDAR(Julian , Julian) +#endif //__XMLIO_CJulianCalendar__ + +#ifdef __XMLIO_CNoLeapCalendar__ + DECLARE_CALENDAR(NoLeap , NoLeap) +#endif //__XMLIO_CNoLeapCalendar__ + +#undef DECLARE_CALENDAR diff --git a/src/config/context_attribute.conf b/src/config/context_attribute.conf new file mode 100644 index 0000000000000000000000000000000000000000..49345c57a6a256d555d10d3a38979959bf24d9aa --- /dev/null +++ b/src/config/context_attribute.conf @@ -0,0 +1,6 @@ +DECLARE_ATTRIBUTE(StdString, calendar_type) +DECLARE_ATTRIBUTE(StdString, start_date) +DECLARE_ATTRIBUTE(StdString, time_origin) +DECLARE_ATTRIBUTE(StdString, timestep) +DECLARE_ATTRIBUTE(StdString, output_dir) + diff --git a/src/config/domain_attribute.conf b/src/config/domain_attribute.conf new file mode 100644 index 0000000000000000000000000000000000000000..c3087a0e0beffa84f673093f2d15391cb768bbc7 --- /dev/null +++ b/src/config/domain_attribute.conf @@ -0,0 +1,64 @@ +/* GLOBAL */ +DECLARE_ATTRIBUTE(StdString , name) +DECLARE_ATTRIBUTE(StdString , standard_name) +DECLARE_ATTRIBUTE(StdString , long_name) + +/* Spécifique */ +DECLARE_ATTRIBUTE(StdString , domain_group_ref) + +/* GLOBAL */ +DECLARE_ATTRIBUTE(int , ni_glo) +DECLARE_ATTRIBUTE(int , nj_glo) + +/* LOCAL */ +DECLARE_ATTRIBUTE(int , ibegin) +DECLARE_ATTRIBUTE(int , iend) +DECLARE_ATTRIBUTE(int , ni) + +/* LOCAL */ +DECLARE_ATTRIBUTE(int , jbegin) +DECLARE_ATTRIBUTE(int , jend) +DECLARE_ATTRIBUTE(int , nj) + + +DECLARE_ARRAY(int,2 , i_index) +DECLARE_ARRAY(int,2 , j_index) + +/* LOCAL */ +DECLARE_ARRAY(bool, 2 , mask) + +/* GLOBAL */ +DECLARE_ATTRIBUTE(int , data_dim) + +/* LOCAL */ +DECLARE_ATTRIBUTE(int , data_ni) +DECLARE_ATTRIBUTE(int , data_nj) +DECLARE_ATTRIBUTE(int , data_ibegin) +DECLARE_ATTRIBUTE(int , data_jbegin) + +/* GLOBAL */ +DECLARE_ATTRIBUTE(int , zoom_ni) +DECLARE_ATTRIBUTE(int , zoom_nj) +DECLARE_ATTRIBUTE(int , zoom_ibegin) +DECLARE_ATTRIBUTE(int , zoom_jbegin) + +/* LOCAL */ +DECLARE_ATTRIBUTE(int , zoom_ni_loc) +DECLARE_ATTRIBUTE(int , zoom_nj_loc) +DECLARE_ATTRIBUTE(int , zoom_ibegin_loc) +DECLARE_ATTRIBUTE(int , zoom_jbegin_loc) + +/* LOCAL */ +DECLARE_ATTRIBUTE(int , data_n_index) +DECLARE_ARRAY(int, 1 , data_i_index) +DECLARE_ARRAY(int, 1, data_j_index) + +/* LOCAL */ +DECLARE_ARRAY(double, 1, lonvalue) +DECLARE_ARRAY(double, 1, latvalue) +DECLARE_ATTRIBUTE(int, nvertex) +DECLARE_ARRAY(double, 2, bounds_lon) +DECLARE_ARRAY(double, 2, bounds_lat) + +DECLARE_ENUM3(type,regular,curvilinear,unstructured) + diff --git a/src/config/field_attribute.conf b/src/config/field_attribute.conf new file mode 100644 index 0000000000000000000000000000000000000000..fcc133ae1480850511990d46cfbf30d22767a4fd --- /dev/null +++ b/src/config/field_attribute.conf @@ -0,0 +1,25 @@ +DECLARE_ATTRIBUTE(StdString, name) +DECLARE_ATTRIBUTE(StdString, standard_name) +DECLARE_ATTRIBUTE(StdString, long_name) + +DECLARE_ATTRIBUTE(StdString, unit) +DECLARE_ATTRIBUTE(StdString, operation) +DECLARE_ATTRIBUTE(bool, detect_missing_value) + +DECLARE_ATTRIBUTE(StdString, freq_op) +DECLARE_ATTRIBUTE(StdString, freq_offset) +DECLARE_ATTRIBUTE(int, level) +DECLARE_ATTRIBUTE(int, prec) + +DECLARE_ATTRIBUTE(bool, enabled) + +DECLARE_ATTRIBUTE(StdString, domain_ref) +DECLARE_ATTRIBUTE(StdString, axis_ref) +DECLARE_ATTRIBUTE(StdString, grid_ref) +DECLARE_ATTRIBUTE(StdString, field_ref) + +DECLARE_ATTRIBUTE(double, default_value) +DECLARE_ATTRIBUTE(double, valid_min) +DECLARE_ATTRIBUTE(double, valid_max) +DECLARE_ATTRIBUTE(double, add_offset) +DECLARE_ATTRIBUTE(double, scale_factor) diff --git a/src/config/file_attribute.conf b/src/config/file_attribute.conf new file mode 100644 index 0000000000000000000000000000000000000000..4afe7613d3bb824f4dc1e39557324aea8d1bdece --- /dev/null +++ b/src/config/file_attribute.conf @@ -0,0 +1,16 @@ +DECLARE_ATTRIBUTE(StdString, name) +DECLARE_ATTRIBUTE(StdString, description) + +DECLARE_ATTRIBUTE(StdString, name_suffix) +DECLARE_ATTRIBUTE(int, min_digits ) + +DECLARE_ATTRIBUTE(StdString, output_freq) +DECLARE_ATTRIBUTE(int, output_level) +DECLARE_ATTRIBUTE(StdString, sync_freq) +DECLARE_ATTRIBUTE(StdString, split_freq) +DECLARE_ATTRIBUTE(StdString, split_freq_format) +DECLARE_ATTRIBUTE(bool, enabled) +DECLARE_ENUM2(type,one_file,multiple_file) +DECLARE_ATTRIBUTE(StdString, par_access) + +// DECLARE_ATTRIBUTE_DEF(bool, enabled, true) diff --git a/src/config/functor_type.conf b/src/config/functor_type.conf new file mode 100644 index 0000000000000000000000000000000000000000..2bb2e24331befff5d22c36e53c1e828102cdbb4e --- /dev/null +++ b/src/config/functor_type.conf @@ -0,0 +1,26 @@ +#ifdef __XMLIO_CAverage__ + DECLARE_FUNCTOR(Average , average) +#endif //__XMLIO_CAverage__ + +#ifdef __XMLIO_CAccumulate__ + DECLARE_FUNCTOR(Accumulate , accumulate) +#endif //__XMLIO_CAccumulate__ + +#ifdef __XMLIO_CInstant__ + DECLARE_FUNCTOR(Instant, instant) +#endif //__XMLIO_CInstant__ + +#ifdef __XMLIO_COnce__ + DECLARE_FUNCTOR(Once, once) +#endif //__XMLIO_COnce__ + +#ifdef __XMLIO_CMaximum__ + DECLARE_FUNCTOR(Maximum , maximum) +#endif //__XMLIO_CMaximum__ + +#ifdef __XMLIO_CMinimum__ + DECLARE_FUNCTOR(Minimum , minimum) +#endif //__XMLIO_CMinimum__ + + +#undef DECLARE_FUNCTOR diff --git a/src/config/grid_attribute.conf b/src/config/grid_attribute.conf new file mode 100644 index 0000000000000000000000000000000000000000..db48d2c804acb9fdbeb97275eabf70ab852f3470 --- /dev/null +++ b/src/config/grid_attribute.conf @@ -0,0 +1,5 @@ +DECLARE_ATTRIBUTE(StdString, name) +DECLARE_ATTRIBUTE(StdString, description) +DECLARE_ATTRIBUTE(StdString, domain_ref) +DECLARE_ATTRIBUTE(StdString, axis_ref) +DECLARE_ARRAY(bool, 3 , mask) diff --git a/src/config/node_type.conf b/src/config/node_type.conf new file mode 100644 index 0000000000000000000000000000000000000000..0c0c66923d8ba3eab395a6c603874462c37364c1 --- /dev/null +++ b/src/config/node_type.conf @@ -0,0 +1,34 @@ +#ifdef __XMLIO_CAxis__ + DECLARE_NODE(Axis , axis ) +#endif //__XMLIO_CAxis__ + +#ifdef __XMLIO_CDomain__ + DECLARE_NODE(Domain, domain) +#endif //__XMLIO_CDomain__ + +#ifdef __XMLIO_CField__ + DECLARE_NODE(Field , field ) +#endif //__XMLIO_CField__ + +#ifdef __XMLIO_CFile__ + DECLARE_NODE(File , file ) +#endif //__XMLIO_CFile__ + +#ifdef __XMLIO_CGrid__ + DECLARE_NODE(Grid , grid ) +#endif //__XMLIO_CGrid__ + +//#ifdef __XMLIO_CMethod__ +// DECLARE_NODE(Method, method) +//#endif //__XMLIO_CMethod__ + +#ifdef __XMLIO_CVariable__ + DECLARE_NODE(Variable, variable) +#endif //__XMLIO_CVariable__ + +#ifdef __XMLIO_CContext__ + DECLARE_NODE_PAR(Context, context) +#endif //__XMLIO_CContext__ + +#undef DECLARE_NODE +#undef DECLARE_NODE_PAR diff --git a/src/config/properties.conf b/src/config/properties.conf new file mode 100644 index 0000000000000000000000000000000000000000..19c0247d76fe2188820f420e95ca36797ef42e19 --- /dev/null +++ b/src/config/properties.conf @@ -0,0 +1,24 @@ +/// Author /// +DECLARE_PROPERTY (StdString, AUTHOR, "OZDOBA Herve, MEURDESOIF Yann") + +/// Version number /// +DECLARE_PROPERTY (StdString, VERSION, "0.1") + +/// Time name /// +DECLARE_PROPERTY (StdString, TIME_NAME, "time") + +/// Output config /// +//DECLARE_PROPERTY (StdString, NETCDF_OUTPUT, "MULTI_FILE") // (ONE_FILE, TWO_FILE, MULTI_FILE) +DECLARE_PROPERTY (StdString, NETCDF_OUTPUT, "ONE_FILE") // (ONE_FILE, TWO_FILE, MULTI_FILE) +DECLARE_PROPERTY (StdString, FILE_SUFFIX, "_node" ) +DECLARE_PROPERTY (StdString, FILE_EXTENSION, ".nc" ) +DECLARE_PROPERTY (StdString, OUTPUT_PATH, "./data/" ) + +/// Default Value /// +DECLARE_PROPERTY (double, FIELD_DEFAULT_VALUE, 1E-10) + +/// Buffer Size /// +DECLARE_PROPERTY (StdSize, BUFFER_CLIENT_SIZE, 100E6) // 100 Mo +DECLARE_PROPERTY (StdSize, BUFFER_SERVER_SIZE, 1000E6) // 1000 Mo + + diff --git a/src/config/var_attribute.conf b/src/config/var_attribute.conf new file mode 100644 index 0000000000000000000000000000000000000000..f1f081bb4186bc09c4573e4bec333e54ee18c518 --- /dev/null +++ b/src/config/var_attribute.conf @@ -0,0 +1,2 @@ +DECLARE_ATTRIBUTE(StdString, type) +DECLARE_ATTRIBUTE(StdString, name) diff --git a/src/configure.cpp b/src/configure.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3ef2c61e468b2cca782bfcfc0edde6ddebf24472 --- /dev/null +++ b/src/configure.cpp @@ -0,0 +1,14 @@ +#define __XMLIO_Configure__ // < Ne pas supprimer + +/// xios headers /// +#include "xmlioserver_spl.hpp" + +/// /////////// Macros /////////// /// +#undef DECLARE_PROPERTY +#define DECLARE_PROPERTY(type, name, value) \ + type name = value; + +namespace xios +{ +#include "properties.conf" +} // namespace xios diff --git a/src/configure.hpp b/src/configure.hpp new file mode 100644 index 0000000000000000000000000000000000000000..358b1d7cde3c739694313f20c61ccd581f37a2b6 --- /dev/null +++ b/src/configure.hpp @@ -0,0 +1,14 @@ +#ifndef __XMLIO_Configure__ +#define __XMLIO_Configure__ + + +/// /////////// Macros /////////// /// +#define DECLARE_PROPERTY(type, name, value) \ + extern type name; // = value + +namespace xios +{ +#include "properties.conf" +} // namespace xios + +#endif // __XMLIO_Configure__ diff --git a/src/context_client.cpp b/src/context_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cfff715cd548f43e3cc6dc001b9ee39a2f47fa0a --- /dev/null +++ b/src/context_client.cpp @@ -0,0 +1,214 @@ +#include "xmlioserver_spl.hpp" +#include "context_client.hpp" +#include "context_server.hpp" +#include "event_client.hpp" +#include "buffer_out.hpp" +#include "buffer_client.hpp" +#include "type.hpp" +#include "message.hpp" +#include "event_client.hpp" +#include "context.hpp" +#include "mpi.hpp" +#include "timer.hpp" +#include "cxios.hpp" + +namespace xios +{ + + + CContextClient::CContextClient(CContext* parent,MPI_Comm intraComm_, MPI_Comm interComm_) + { + context=parent ; + intraComm=intraComm_ ; + interComm=interComm_ ; + MPI_Comm_rank(intraComm,&clientRank) ; + MPI_Comm_size(intraComm,&clientSize) ; + + int flag ; + MPI_Comm_test_inter(interComm,&flag) ; + if (flag) MPI_Comm_remote_size(interComm,&serverSize); + else MPI_Comm_size(interComm,&serverSize) ; + + timeLine=0 ; + + } + + + void CContextClient::sendEvent(CEventClient& event) + { + list::iterator itServer ; + list ranks ; + list sizes ; + list::iterator itSize ; + + ranks=event.getRanks() ; + if (! event.isEmpty()) + { + sizes=event.getSizes() ; + CMessage msg ; + + msg<<*(sizes.begin())<::iterator it=sizes.begin();it!=sizes.end();it++) *it+=msg.size() ; + list buffList=getBuffers(ranks,sizes) ; + + list::iterator it ; + for(it=buffList.begin(),itSize=sizes.begin();it!=buffList.end();++it,++itSize) + { + **it<<*itSize<hasServer) waitEvent(ranks) ; + timeLine++ ; + } + + void CContextClient::waitEvent(list& ranks) + { + context->server->setPendingEvent() ; + while(checkBuffers(ranks)) + { + context->server->listen() ; + context->server->checkPendingRequest() ; + } + + while(context->server->hasPendingEvent()) + { + context->server->eventLoop() ; + } + + } + + list CContextClient::getBuffers(list& serverList, list& sizeList) + { + list::iterator itServer,itSize ; + list bufferList ; + map::iterator it ; + list::iterator itBuffer ; + list retBuffer ; + bool free ; + + for(itServer=serverList.begin();itServer!=serverList.end();itServer++) + { + it=buffers.find(*itServer) ; + if (it==buffers.end()) + { + newBuffer(*itServer) ; + it=buffers.find(*itServer) ; + } + bufferList.push_back(it->second) ; + } + free=false ; + + CTimer::get("Blocking time").resume(); + while(!free) + { + free=true ; + for(itBuffer=bufferList.begin(),itSize=sizeList.begin(); itBuffer!=bufferList.end();itBuffer++,itSize++) + { + (*itBuffer)->checkBuffer() ; + free&=(*itBuffer)->isBufferFree(*itSize) ; + } + } + CTimer::get("Blocking time").suspend(); + + for(itBuffer=bufferList.begin(),itSize=sizeList.begin(); itBuffer!=bufferList.end();itBuffer++,itSize++) + { + retBuffer.push_back((*itBuffer)->getBuffer(*itSize)) ; + } + return retBuffer ; + + } + + void CContextClient::newBuffer(int rank) + { + buffers[rank]=new CClientBuffer(interComm,rank) ; + } + + bool CContextClient::checkBuffers(void) + { + map::iterator itBuff ; + bool pending=false ; + for(itBuff=buffers.begin();itBuff!=buffers.end();itBuff++) pending|=itBuff->second->checkBuffer() ; + return pending ; + } + + void CContextClient::releaseBuffers(void) + { + map::iterator itBuff ; + for(itBuff=buffers.begin();itBuff!=buffers.end();itBuff++) delete itBuff->second ; + } + + bool CContextClient::checkBuffers(list& ranks) + { + list::iterator it ; + bool pending=false ; + for(it=ranks.begin();it!=ranks.end();it++) pending|=buffers[*it]->checkBuffer() ; + return pending ; + } + + int CContextClient::getServerLeader(void) + { + int clientByServer=clientSize/serverSize ; + int remain=clientSize%serverSize ; + + if (clientRank<(clientByServer+1)*remain) + { + return clientRank/(clientByServer+1) ; + } + else + { + int rank=clientRank-(clientByServer+1)*remain ; + int nbServer=serverSize-remain ; + return remain+rank/clientByServer ; + } + } + + bool CContextClient::isServerLeader(void) + { + int clientByServer=clientSize/serverSize ; + int remain=clientSize%serverSize ; + + if (clientRank<(clientByServer+1)*remain) + { + if (clientRank%(clientByServer+1)==0) return true ; + else return false ; + } + else + { + int rank=clientRank-(clientByServer+1)*remain ; + int nbServer=serverSize-remain ; + if (rank%clientByServer==0) return true ; + else return false ; + } + } + + void CContextClient::finalize(void) + { + + map::iterator itBuff ; + bool stop=true ; + + CEventClient event(CContext::GetType(),CContext::EVENT_ID_CONTEXT_FINALIZE) ; + if (isServerLeader()) + { + CMessage msg ; + event.push(getServerLeader(),1,msg) ; + sendEvent(event) ; + } + else sendEvent(event) ; + + CTimer::get("Blocking time").resume(); + while(stop) + { + checkBuffers() ; + stop=false ; + for(itBuff=buffers.begin();itBuff!=buffers.end();itBuff++) stop|=itBuff->second->hasPendingRequest() ; + } + CTimer::get("Blocking time").suspend(); + report(0)<< " Memory report : Context <"<getId()<<"> : client side : total memory used for buffer "< newEvent(CEventClient& event,list& sizes) ; + void sendEvent(CEventClient& event) ; + + list getBuffers(list& serverlist, list& sizeList) ; + void newBuffer(int rank) ; + size_t timeLine ; + int clientRank ; + int clientSize ; + int serverSize ; +// set connectedServer ; + MPI_Comm interComm ; + MPI_Comm intraComm ; + map buffers ; + bool checkBuffers(list& ranks) ; + bool checkBuffers(void); + void releaseBuffers(void); + void closeContext(void) ; + bool isServerLeader(void) ; + int getServerLeader(void) ; + void finalize(void) ; + void waitEvent(list& ranks) ; + + CContext* context ; +// bool locked ; + + } ; + + + + +} + + + +#endif diff --git a/src/context_server.cpp b/src/context_server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..abb748455cbfa635860ea7ad151e40f27c83e534 --- /dev/null +++ b/src/context_server.cpp @@ -0,0 +1,224 @@ +#include "context_server.hpp" +#include "buffer_in.hpp" +#include "type.hpp" +#include "context.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "attribute_template.hpp" +#include "domain.hpp" +#include "field.hpp" +#include "file.hpp" +#include "grid.hpp" +#include "mpi.hpp" +#include "tracer.hpp" +#include "timer.hpp" +#include "cxios.hpp" +#include "event_scheduler.hpp" +#include "server.hpp" +#include + + + +namespace xios +{ + + CContextServer::CContextServer(CContext* parent,MPI_Comm intraComm_,MPI_Comm interComm_) + { + context=parent ; + intraComm=intraComm_ ; + MPI_Comm_size(intraComm,&intraCommSize) ; + MPI_Comm_rank(intraComm,&intraCommRank) ; + interComm=interComm_ ; + int flag ; + MPI_Comm_test_inter(interComm,&flag) ; + if (flag) MPI_Comm_remote_size(interComm,&commSize); + else MPI_Comm_size(interComm,&commSize) ; + currentTimeLine=0 ; + scheduled=false ; + finished=false ; + + boost::hash hashString ; + hashId=hashString(context->getId()) ; + + } + void CContextServer::setPendingEvent(void) + { + pendingEvent=true ; + } + + bool CContextServer::hasPendingEvent(void) + { + return pendingEvent ; + } + + bool CContextServer::eventLoop(void) + { + listen() ; + checkPendingRequest() ; + processEvents() ; + return finished ; + } + + void CContextServer::listen(void) + { + int rank; + int flag ; + int count ; + char * addr ; + MPI_Status status; + map::iterator it; + + for(rank=0;rank(rank,new CServerBuffer))).first ; + MPI_Get_count(&status,MPI_CHAR,&count) ; + if (it->second->isBufferFree(count)) + { + addr=(char*)it->second->getBuffer(count) ; + MPI_Irecv(addr,count,MPI_CHAR,rank,20,interComm,&pendingRequest[rank]) ; + bufferRequest[rank]=addr ; + } + } + } + } + } + + void CContextServer::checkPendingRequest(void) + { + map::iterator it; + list recvRequest ; + list::iterator itRecv; + int rank ; + int flag ; + int count ; + MPI_Status status ; + + for(it=pendingRequest.begin();it!=pendingRequest.end();it++) + { + rank=it->first ; + traceOff() ; + MPI_Test(& it->second, &flag, &status) ; + traceOn() ; + if (flag==true) + { + recvRequest.push_back(rank) ; + MPI_Get_count(&status,MPI_CHAR,&count) ; + processRequest(rank,bufferRequest[rank],count) ; + } + } + + for(itRecv=recvRequest.begin();itRecv!=recvRequest.end();itRecv++) + { + pendingRequest.erase(*itRecv) ; + bufferRequest.erase(*itRecv) ; + } + } + + void CContextServer::processRequest(int rank, char* buff,int count) + { + + CBufferIn buffer(buff,count) ; + char* startBuffer,endBuffer ; + int size, offset ; + size_t timeLine ; + map::iterator it ; + + while(count>0) + { + char* startBuffer=(char*)buffer.ptr() ; + CBufferIn newBuffer(startBuffer,buffer.remain()) ; + newBuffer>>size>>timeLine ; + + it=events.find(timeLine) ; + if (it==events.end()) it=events.insert(pair(timeLine,new CEventServer)).first ; + it->second->push(rank,buffers[rank],startBuffer,size) ; + + buffer.advance(size) ; + count=buffer.remain() ; + } + + } + + void CContextServer::processEvents(void) + { + map::iterator it ; + CEventServer* event ; + + it=events.find(currentTimeLine) ; + if (it!=events.end()) + { + event=it->second ; + + if (event->isFull()) + { + if (!scheduled && !CXios::isServer) + { + CServer::eventScheduler->registerEvent(currentTimeLine,hashId) ; + scheduled=true ; + } + else if (CXios::isServer || CServer::eventScheduler->queryEvent(currentTimeLine,hashId) ) + { + CTimer::get("Process events").resume() ; + dispatchEvent(*event) ; + CTimer::get("Process events").suspend() ; + pendingEvent=false ; + delete event ; + events.erase(it) ; + currentTimeLine++ ; + scheduled = false ; + } + } + } + } + + CContextServer::~CContextServer() + { + map::iterator it ; + for(it=buffers.begin();it!=buffers.end();++it) delete it->second ; + } + + + void CContextServer::dispatchEvent(CEventServer& event) + { + string contextName ; + string buff ; + int MsgSize ; + int rank ; + list::iterator it ; + CContext::setCurrent(context->getId()) ; + + if (event.classId==CContext::GetType() && event.type==CContext::EVENT_ID_CONTEXT_FINALIZE) + { + info(20)<<"Server Side context <"<getId()<<"> finalized"<finalize() ; + finished=true ; + report(0)<< " Memory report : Context <"<getId()<<"> : server side : total memory used for buffer "< buffers ; + map pendingRequest ; + map bufferRequest ; + + map events ; + size_t currentTimeLine ; + CContext* context ; + + bool finished ; + bool pendingEvent ; + bool scheduled ; /*!< event of current timeline is alreading scheduled ? */ + size_t hashId ; + ~CContextServer() ; + } ; + +} + +#endif diff --git a/src/cxios.cpp b/src/cxios.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b215021ec28c0fa4089b06e30afd2a0a5b6bfeb4 --- /dev/null +++ b/src/cxios.cpp @@ -0,0 +1,125 @@ + +#include "xmlioserver_spl.hpp" +#include "cxios.hpp" +#include "client.hpp" +#include "server.hpp" +#include "xml_parser.hpp" +#include +#include "mpi.hpp" +#include "memory.hpp" +#include +#include "memtrack.hpp" + +namespace xios +{ + string CXios::rootFile="./iodef.xml" ; + string CXios::xiosCodeId="xios.x" ; + string CXios::clientFile="./xios_client"; + string CXios::serverFile="./xios_server"; + + bool CXios::isClient ; + bool CXios::isServer ; + MPI_Comm CXios::globalComm ; + bool CXios::usingOasis ; + bool CXios::usingServer = false; + size_t CXios::bufferSize ; + double CXios::bufferServerFactorSize=2 ; + size_t CXios::defaultBufferSize=1024*1024*100 ; // 100Mo + double CXios::defaultBufferServerFactorSize=2 ; + bool CXios::printLogs2Files; + + + void CXios::initialize() + { + set_new_handler(noMemory); + parseFile(rootFile); + usingOasis=getin("using_oasis",false) ; + usingServer=getin("using_server",false) ; + info.setLevel(getin("info_level",0)) ; + printLogs2Files=getin("print_file",false); + bufferSize=getin("buffer_size",defaultBufferSize) ; + bufferServerFactorSize=getin("buffer_server_factor_size",defaultBufferServerFactorSize) ; + globalComm=MPI_COMM_WORLD ; + } + + + void CXios::initClientSide(const string& codeId, MPI_Comm& localComm, MPI_Comm& returnComm) + { + + initialize() ; + + isClient=true; + + CClient::initialize(codeId,localComm,returnComm) ; + + if (usingServer) isServer=false; + else isServer=true; + + if (printLogs2Files) + { + CClient::openInfoStream(clientFile); + CClient::openErrorStream(clientFile); + } + else + { + CClient::openInfoStream(); + CClient::openErrorStream(); + } + } + + void CXios::clientFinalize(void) + { + CClient::finalize() ; + CClient::closeInfoStream(); + +#ifdef XIOS_MEMTRACK + MemTrack::TrackListMemoryUsage() ; + MemTrack::TrackDumpBlocks(); +#endif + } + + + void CXios::initServerSide(void) + { + initialize(); + + isClient=true; + isServer=false ; + + // Initialize all aspects MPI + CServer::initialize(); + + if (printLogs2Files) + { + CServer::openInfoStream(serverFile); + CServer::openErrorStream(serverFile); + } + else + { + CServer::openInfoStream(); + CServer::openErrorStream(); + } + + // Enter the loop to listen message from Client + CServer::eventLoop(); + + // Finalize + CServer::finalize(); + CServer::closeInfoStream(); + } + + void CXios::parseFile(const string& filename) + { + xml::CXMLParser::ParseFile(filename); + } + + void CXios::setUsingServer() + { + usingServer = true; + } + + void CXios::setNotUsingServer() + { + usingServer = false; + } +} diff --git a/src/cxios.hpp b/src/cxios.hpp new file mode 100644 index 0000000000000000000000000000000000000000..12ba432bbbaaa3414e49a759abeece24dea43896 --- /dev/null +++ b/src/cxios.hpp @@ -0,0 +1,66 @@ +#ifndef __XIOS_HPP__ +#define __XIOS_HPP__ + +#include "xmlioserver_spl.hpp" +#include "mpi.hpp" + +namespace xios +{ + class CXios + { + public: + + static string rootFile ; + static string xiosCodeId ; + static string clientFile; + static string serverFile; + + static void initialize(void) ; + + + static void initClientSide(const string & codeId, MPI_Comm& localComm, MPI_Comm& returnComm) ; + static void initServerSide(void) ; + static void clientFinalize(void) ; + static void parseFile(const string& filename) ; + + template + static T getin(const string& id,const T& defaultValue) ; + + template + static T getin(const string& id) ; + + static bool isClient ; + static bool isServer ; + + static MPI_Comm globalComm ; + + static bool printLogs2Files; //!< Printing out logs into files + static bool usingOasis ; + static bool usingServer ; + static size_t bufferSize ; + static size_t defaultBufferSize ; + static double bufferServerFactorSize ; + static double defaultBufferServerFactorSize ; + + public: + //! Setting xios to use server mode + static void setUsingServer(); + + //! Setting xios NOT to use server mode + static void setNotUsingServer(); + + } ; + +} + +//#include "cxios_impl.hpp" + + + + + + + + + +#endif diff --git a/src/cxios_decl.cpp b/src/cxios_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b9c53acad673cf8061c5d534b799e6f31ae32f8 --- /dev/null +++ b/src/cxios_decl.cpp @@ -0,0 +1,16 @@ +#include "cxios_impl.hpp" +#include "xmlioserver_spl.hpp" +#include + +namespace xios +{ +# define macro(T) \ + template T CXios::getin(const string& id) ; \ + template T CXios::getin(const string& id, const T& defaultValue) ; + + macro(int) + macro(double) + macro(bool) + macro(StdSize) + macro(string) +} diff --git a/src/cxios_impl.hpp b/src/cxios_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ab98145b056d15db60d77c0497fb2f55bd0e7ea3 --- /dev/null +++ b/src/cxios_impl.hpp @@ -0,0 +1,26 @@ +#ifndef __XIOS_IMPL_HPP__ +#define __XIOS_IMPL_HPP__ + +#include "xmlioserver_spl.hpp" +#include "variable.hpp" +#include "object_template.hpp" +#include "cxios.hpp" + +namespace xios +{ + template + T CXios::getin(const string& id) + { + return CVariable::get("xios",id)->getData() ; + } + + template + T CXios::getin(const string& id, const T& defaultValue) + { + if (CVariable::has("xios",id)) return CVariable::get("xios",id)->getData() ; + else return defaultValue ; + } + + +} +#endif diff --git a/src/data_output.cpp b/src/data_output.cpp new file mode 100644 index 0000000000000000000000000000000000000000..db5e52c02425c34923b49bfc9e03c08eaffcf1f5 --- /dev/null +++ b/src/data_output.cpp @@ -0,0 +1,104 @@ +#include "data_output.hpp" + +#include "attribute_template.hpp" +#include "group_template.hpp" +#include "context.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + CDataOutput::~CDataOutput(void) + { /* Ne rien faire de plus */ } + + //---------------------------------------------------------------- + + void CDataOutput::writeGrid(CGrid* grid) + { + if (grid->domain_ref.isEmpty()) + ERROR("CDataOutput::writeGrid(grid)", + << " domain is not defined !"); + + if (grid->axis_ref.isEmpty()) + { + this->writeGrid(CDomain::get(grid->domain_ref.getValue())); + } + else + { + this->writeGrid(CDomain::get(grid->domain_ref.getValue()), + CAxis::get(grid->axis_ref.getValue())); + } + } + + //---------------------------------------------------------------- + + void CDataOutput::writeFile(CFile* file) + { + this->writeFile_(file); + } + + void CDataOutput::writeAttribute(CVariable* var) + { + this->writeAttribute_(var) ; + } + + void CDataOutput::syncFile(void) + { + this->syncFile_(); + } + + void CDataOutput::closeFile(void) + { + this->closeFile_(); + } + + //---------------------------------------------------------------- + + void CDataOutput::writeGrid(CDomain* domain,CAxis* axis) + { + this->writeDomain_(domain); + this->writeAxis_(axis); + } + + //---------------------------------------------------------------- + + void CDataOutput::writeGrid(CDomain* domain) + { + this->writeDomain_(domain); + } + + void CDataOutput::writeTimeDimension(void) + { + this->writeTimeDimension_(); + } + + //---------------------------------------------------------------- + + void CDataOutput::writeField(CField* field) + { + CContext* context = CContext::getCurrent() ; + boost::shared_ptr calendar = context->getCalendar(); + + this->writeField_(field); + this->writeTimeAxis_(field, calendar); + } + + //---------------------------------------------------------------- + + void CDataOutput::writeFieldGrid(CField* field) + { + this->writeGrid(field->getRelGrid()); + } + + //---------------------------------------------------------------- + + void CDataOutput::writeFieldData(CField* field) + { + CGrid* grid = CGrid::get(field->grid_ref.getValue()); + CDomain* domain = CDomain::get(grid->domain_ref.getValue()); + this->writeFieldData_(field); + } + + ///---------------------------------------------------------------- + +} // namespace xios diff --git a/src/data_output.hpp b/src/data_output.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4f21dd6e46f82d2667292aee8df176160a43e212 --- /dev/null +++ b/src/data_output.hpp @@ -0,0 +1,63 @@ +#ifndef __XMLIO_DATA_OUTPUT__ +#define __XMLIO_DATA_OUTPUT__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "grid.hpp" +#include "field.hpp" + + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CDataOutput + { + public : + + /// Définition de type /// + typedef enum { ONE_FILE = 0, MULTI_GROUP, MULTI_FILE } EDataOutputType; + + /// Ecriture /// + void writeFile (CFile* file); + void writeAttribute(CVariable* var); + void syncFile (void); + void closeFile (void); + void writeField (CField* field); + void writeFieldGrid(CField* field); + void writeTimeDimension(void); + void writeFieldData(CField* field); + + virtual void definition_start(void) = 0; + virtual void definition_end(void) = 0; + + virtual ~CDataOutput(void); + + protected: + + /// Ecriture /// + void writeGrid(CGrid* grid); + void writeGrid(CDomain* domain, + CAxis* axis); + void writeGrid(CDomain* domain); + + virtual void writeFile_ (CFile* file) = 0; + virtual void writeAttribute_(CVariable* var) = 0 ; + virtual void closeFile_ (void) = 0; + virtual void syncFile_ (void) = 0; + virtual void writeField_ (CField* field) = 0; + virtual void writeFieldData_ (CField* field) = 0; + virtual void writeDomain_ (CDomain* domain) = 0; + virtual void writeTimeDimension_ (void) = 0; + virtual void writeAxis_ (CAxis* axis) = 0; + virtual void writeTimeAxis_ (CField* field, + const shared_ptr cal) = 0; + + /// Propriétés protégées /// + EDataOutputType type; + + }; // class CDataOutput + +} // namespace xios + +#endif //__XMLIO_DATA_OUTPUT__ diff --git a/src/date.cpp b/src/date.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7794397c5539ad4b169e58a71ef14dbae00f6795 --- /dev/null +++ b/src/date.cpp @@ -0,0 +1,297 @@ +#include "date.hpp" +#include "calendar.hpp" +#include "calendar_type.hpp" +#include +#include + +using namespace boost::posix_time ; +using namespace boost::gregorian ; + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + CDate::CDate(const CCalendar& calendar) + : relCalendar(calendar) + , year(0), month(1) , day(1) + , hour(0), minute(0), second(0) + { } + + CDate::CDate(const CCalendar& calendar, + int yr, int mth, int d, + int hr, int min, int sec) + : relCalendar(calendar) + , year(yr), month(mth) , day(d) + , hour(hr), minute(min), second(sec) + { + if(!this->checkDate()) + { + DEBUG(<< "La date initialisée a été modifiée " + << "car elle était incorrecte par rapport au calendrier souhaité."); + } + } + + CDate::CDate(const CDate & date) + : relCalendar(date.getRelCalendar()), + year(date.year), month(date.month) , day(date.day), + hour(date.hour), minute(date.minute), second(date.second) + { + if(!this->checkDate()) + { + DEBUG(<< "La date initialisée a été modifiée " + << "car elle était incorrecte par rapport au calendrier souhaité."); + } + } + + CDate::~CDate(void) + { /* Ne rien faire de plus */ } + + ///--------------------------------------------------------------- + + CDate & CDate::operator=(const CDate & date) + { + // relCalendar = d.getRelCalendar(); << inutile si fonction bien utilisée + year = date.year; month = date.month ; day = date.day; + hour = date.hour; minute = date.minute; second = date.second; + return (*this); + } + + StdOStream & operator<<(StdOStream & out, const CDate & date) + { + std::streamsize s ; + char c ; + + + int width=4 ; + double maxSize=10000 ; + while(date.year>=maxSize) + { + maxSize*=10 ; + width++ ; + } + s = out.width (width); c = out.fill ('0') ; out << date.year << '-'; + + s = out.width (2); c = out.fill ('0') ; out << date.month << '-'; + s = out.width (2); c = out.fill ('0') ; out << date.day << ' '; + s = out.width (2); c = out.fill ('0') ; out << date.hour << ':'; + s = out.width (2); c = out.fill ('0') ; out << date.minute << ':'; + s = out.width (2); c = out.fill ('0') ; out << date.second ; + + return (out); + } + + StdIStream & operator>>(StdIStream & in, CDate & date) // Non testée. + { + char sep = '-'; // Le caractère c est utilisé pour "recueillir" les séparateurs "/" et ":". + char c ; + + in >> date.year >> c ; + if (c==sep) + { + in >> date.month >> c ; + if (c==sep) + { + in >> date.day ; + c=in.get(); + sep=' ' ; + if (c==sep) + { + in >> date.hour >> c ; + sep=':' ; + if (c==sep) + { + in>>date.minute >> c; + if (c==sep) + { + in>>date.second ; + if(!date.checkDate()) + ERROR("StdIStream & operator >> (StdIStream & in, CDate & date)",<<"Bad date format or not conform to calendar" ); + return (in); + } + } + } + } + } + ERROR("StdIStream & operator >> (StdIStream & in, CDate & date)",<<"Bad date format or not conform to calendar" ); + return (in); + } + + CDate::operator Time(void) const // Non vérifiée, pas optimisée ... + { + // Todo : Tester si la date courante est supérieure à la date initiale. + Time retvalue = - relCalendar.getNbSecond(relCalendar.getTimeOrigin()) + + relCalendar.getNbSecond(*this); + + if ((relCalendar.getId().compare("D360") == 0) || + (relCalendar.getId().compare("AllLeap") == 0) || + (relCalendar.getId().compare("NoLeap") == 0)) + return (retvalue + (getYear() - relCalendar.getTimeOrigin().getYear()) + * relCalendar.getYearTotalLength(*this)); + + for(CDate _d(relCalendar.getTimeOrigin()); + _d.getYear() < getYear(); _d.setYear(_d.getYear()+1)) + retvalue += relCalendar.getYearTotalLength(_d); + return (retvalue); + } + + //---------------------------------------------------------------- + + bool CDate::checkDate(void) + { + bool retValue = true; + + // Vérificatio de la valeur du mois. + if (month < 1) { retValue = false; month = 1; } + if (month > relCalendar.getYearLength()) + { retValue = false; month = relCalendar.getYearLength(); } + + // Vérification de la valeur du jour. + if (day < 1) { retValue = false; month = 1; } + if (day > (&relCalendar)->getMonthLength(*this)) + { retValue = false; day = (&relCalendar)->getMonthLength(*this); } + + // Vérification de la valeur de l'heure. + if (hour < 0) { retValue = false; hour = 0; } + if (hour >= relCalendar.getDayLength()) + { retValue = false; hour = relCalendar.getDayLength()-1; } + + // Vérification de la valeur des minutes. + if (minute < 0) { retValue = false; minute = 0; } + if (minute >= relCalendar.getHourLength()) + { retValue = false; minute = relCalendar.getHourLength()-1; } + + // Vérification de la valeur des secondes. + if (second < 0) { retValue = false; month = 0; } + if (second >= relCalendar.getMinuteLength()) + { retValue = false; second = relCalendar.getMinuteLength()-1; } + + return retValue; + } + + //---------------------------------------------------------------- + + int CDate::getYear (void) const { return (this->year ); } + int CDate::getMonth (void) const { return (this->month ); } + int CDate::getDay (void) const { return (this->day ); } + int CDate::getHour (void) const { return (this->hour ); } + int CDate::getMinute(void) const { return (this->minute); } + int CDate::getSecond(void) const { return (this->second); } + + //---------------------------------------------------------------- + + const CCalendar & CDate::getRelCalendar(void) const + { return (this->relCalendar); } + + //---------------------------------------------------------------- + + void CDate::setYear (int newyear) { this->year = newyear; } + void CDate::setMonth (int newmonth) { this->month = newmonth; } + void CDate::setDay (int newday) { this->day = newday; } + + //---------------------------------------------------------------- + + void CDate::addMonth (int value) + {// Value doit être égale à 1 ou -1. + this->month += value; + if (this->month == 13) { year++; this->month = 1 ; } + if (this->month == 0 ) { year--; this->month = 12; } + } + + //---------------------------------------------------------------- + + CDate CDate::FromString(const StdString & str, const CCalendar & calendar) + { + CDate dt(calendar); + StdIStringStream iss(str); + iss >> dt; + return dt; + } + + //---------------------------------------------------------------- + + StdString CDate::getStryyyymmdd(void) const + { + std::streamsize s ; + char c ; + + ostringstream oss ; + + s = oss.width (4); c = oss.fill ('0') ; oss << year ; + s = oss.width (2); c = oss.fill ('0') ; oss << month; + s = oss.width (2); c = oss.fill ('0') ; oss << day ; + + return oss.str(); + } + + + string CDate::getStr(const string& str) const + { + ostringstream oss ; + int level; + + level=0 ; + for(string::const_iterator it=str.begin();it!=str.end();++it) + { + if (level==0) + { + if (*it=='%') level++ ; + else oss<<*it ; + } + else if (level==1) + { + switch (*it) + { + case 'y' : + oss.width (4); oss.fill ('0') ; oss << year ; + level=0 ; + break ; + case 'm' : // month or minute + level++ ; + break ; + case 'd' : + oss.width (2); oss.fill ('0') ; oss << day ; + level=0; + break ; + case 'h' : + oss.width (2); oss.fill ('0') ; oss << hour ; + level=0; + break ; + case 's' : + oss.width (2); oss.fill ('0') ; oss << second ; + level=0 ; + break; + default : + oss<<'%'<<*it ; + level=0 ; + } + } + else if (level==2) + { + switch (*it) + { + case 'o' : // month + oss.width (2); oss.fill ('0') ; oss << month ; + level=0 ; + break ; + case 'i' : //minute + oss.width (2); oss.fill ('0') ; oss << minute ; + level=0 ; + break ; + default : + oss<<"%m"<<*it ; + level=0 ; + } + } + } + return oss.str(); + } + + StdString CDate::toString(void) const + { + StdOStringStream oss; + oss << (*this); + return (oss.str()); + } + + ///--------------------------------------------------------------- + +} // namespace xios diff --git a/src/date.hpp b/src/date.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7fb66f7df09f9c4ba935cfd95033e447aa34aaf9 --- /dev/null +++ b/src/date.hpp @@ -0,0 +1,78 @@ +#ifndef __XMLIO_CDate__ +#define __XMLIO_CDate__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "duration.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CCalendar; + + class CDate + { + public : + + /// Constructeurs /// + CDate(void); // Not implemented yet + CDate(const CCalendar & cal); + CDate(const CCalendar & cal,int yr, int mth, int d, + int hr = 0, int min = 0, int sec = 0); + CDate(const CDate & odate); + CDate(const CDate * const odate); // Not implemented yet + + /// Destructeur /// + ~CDate(void); + + /// Opérateurs /// + CDate & operator=(const CDate & date); + friend StdOStream & operator<<(StdOStream & out, const CDate & date); + friend StdIStream & operator>>(StdIStream & in, CDate & date); // Non testée. + + //!< Return the number of seconds since the time origin fixed when creating the calendar + operator Time(void) const; + + /// Traitements /// + bool checkDate(void); // Vérifie la validité de la date. + + /// Divers accesseurs /// + int getYear (void) const; + int getMonth (void) const; + int getDay (void) const; + int getHour (void) const; + int getMinute(void) const; + int getSecond(void) const; + + const CCalendar & getRelCalendar(void) const; + + /// Mutateurs /// + void setYear (int newyear); + void setMonth (int newmonth); + void setDay (int newday); + + void addMonth (int value); + + /// Autres /// + StdString toString(void) const; + StdString getStryyyymmdd(void) const; + string getStr(const string& str) const; + + + public : /* static */ + + static CDate FromString(const StdString & str, const CCalendar & calendar); + + private : + + /// Propriétés privées /// + const CCalendar & relCalendar; // Calendrier lié à la Date. + int year, month, day, hour, minute, second; // Année, mois, ... + + + }; // class CDate; + +} // namespace xios + +#endif // __XMLIO_CDate__ diff --git a/src/date/allleap.cpp b/src/date/allleap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5919ef1e78ecf0647288bf873fc2717d5834d563 --- /dev/null +++ b/src/date/allleap.cpp @@ -0,0 +1,39 @@ +#include "allleap.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + CAllLeapCalendar::CAllLeapCalendar(const StdString & dateStr) + : CCalendar("AllLeap") + { initializeDate(dateStr); } + + CAllLeapCalendar::CAllLeapCalendar(const StdString & dateStr,const StdString & timeOriginStr) + : CCalendar("AllLeap") + { initializeDate(dateStr, timeOriginStr); } + + CAllLeapCalendar::CAllLeapCalendar(int yr, int mth, int d, + int hr, int min, int sec) + : CCalendar("AllLeap") + { initializeDate(yr, mth, d, hr, min, sec) ; } + + CAllLeapCalendar::~CAllLeapCalendar(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + int CAllLeapCalendar::getYearTotalLength(const CDate & date) const + { return (366 * 86400); } + + int CAllLeapCalendar::getMonthLength(const CDate & date) const + { + if (date.getMonth() == 2) return (29); + return (CCalendar::getMonthLength(date)); + } + + StdString CAllLeapCalendar::getType(void) const + { return (StdString("all_leap")); } + + ///-------------------------------------------------------------- +} // namespace xmlioserver + diff --git a/src/date/allleap.hpp b/src/date/allleap.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5493e15ab9a062a84a16f0a7df8a4f77138c75cd --- /dev/null +++ b/src/date/allleap.hpp @@ -0,0 +1,39 @@ +#ifndef __XMLIO_CAllLeapCalendar__ +#define __XMLIO_CAllLeapCalendar__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "calendar.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CAllLeapCalendar : public CCalendar + { + /// Typedef /// + typedef CCalendar SuperClass; + + public : + + /// Constructeur /// +// CAllLeapCalendar(void); // Not implemented yet. + CAllLeapCalendar(const StdString & dateStr); + CAllLeapCalendar(const StdString & dateStr,const StdString & timeOriginStr); + CAllLeapCalendar(int yr = 0, int mth = 1, int d = 1, + int hr = 0, int min = 0, int sec = 0); + CAllLeapCalendar(const CAllLeapCalendar & calendar); // Not implemented yet. + CAllLeapCalendar(const CAllLeapCalendar * calendar); // Not implemented yet. + + /// Accesseurs /// + virtual int getYearTotalLength(const CDate & date) const; + virtual int getMonthLength(const CDate & date) const; + virtual StdString getType(void) const; + + /// Destructeur /// + virtual ~CAllLeapCalendar(void); + + }; // class CAllLeapCalendar + +} // namespace xmlioserver + +#endif // __XMLIO_CAllLeapCalendar__ diff --git a/src/date/calendar_type.hpp b/src/date/calendar_type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..34d8ad86fd53ec473797cae21096f5b48bd13048 --- /dev/null +++ b/src/date/calendar_type.hpp @@ -0,0 +1,10 @@ +#ifndef __XMLIO_calendar_type__ +#define __XMLIO_calendar_type__ + +#include "allleap.hpp" +#include "d360.hpp" +#include "gregorian.hpp" +#include "julian.hpp" +#include "noleap.hpp" + +#endif //__XMLIO_calendar_type__ diff --git a/src/date/d360.cpp b/src/date/d360.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5536635c9f64f9b8242096cad1354e02bba728e8 --- /dev/null +++ b/src/date/d360.cpp @@ -0,0 +1,36 @@ +#include "d360.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + CD360Calendar::CD360Calendar(const StdString & dateStr) + : CCalendar("D360") + { initializeDate(dateStr); } + + CD360Calendar::CD360Calendar(const StdString & dateStr,const StdString & timeOriginStr) + : CCalendar("D360", dateStr) + { initializeDate(dateStr, timeOriginStr); } + + CD360Calendar::CD360Calendar(int yr, int mth, int d, + int hr, int min, int sec) + : CCalendar("D360") + { initializeDate(yr, mth, d, hr, min, sec) ; } + + CD360Calendar::~CD360Calendar(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + int CD360Calendar::getYearTotalLength(const CDate & date) const + { return (360 * 86400); } + + int CD360Calendar::getMonthLength(const CDate & date) const + { return (30); } + + StdString CD360Calendar::getType(void) const + { return (StdString("360_day")); } + + ///-------------------------------------------------------------- +} // namespace xmlioserver + diff --git a/src/date/d360.hpp b/src/date/d360.hpp new file mode 100644 index 0000000000000000000000000000000000000000..982b068ccb0e536457295dcb8a1e2ec6217cef80 --- /dev/null +++ b/src/date/d360.hpp @@ -0,0 +1,40 @@ +#ifndef __XMLIO_CD360Calendar__ +#define __XMLIO_CD360Calendar__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "calendar.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CD360Calendar : public CCalendar + { + /// Typedef /// + typedef CCalendar SuperClass; + + public : + + /// Constructeur /// + CD360Calendar(void); // Not implemented yet. + CD360Calendar(const StdString & dateStr); + CD360Calendar(const StdString & dateStr,const StdString & timeOriginStr); + CD360Calendar(int yr = 0, int mth = 1, int d = 1, + int hr = 0, int min = 0, int sec = 0); + CD360Calendar(const CD360Calendar & calendar); // Not implemented yet. + CD360Calendar(const CD360Calendar * calendar); // Not implemented yet. + + /// Accesseurs /// + virtual int getYearTotalLength(const CDate & date) const; + virtual int getMonthLength(const CDate & date) const; + virtual StdString getType(void) const; + + /// Destructeur /// + virtual ~CD360Calendar(void); + + }; // class CD360Calendar + +} // namespace xmlioserver + +#endif // __XMLIO_CD360Calendar__ + diff --git a/src/date/gregorian.cpp b/src/date/gregorian.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f522499b3be280b3ef68541a1bae4658269bcfca --- /dev/null +++ b/src/date/gregorian.cpp @@ -0,0 +1,52 @@ +#include "gregorian.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + CGregorianCalendar::CGregorianCalendar(const StdString & dateStr) + : CCalendar("Gregorian") + { initializeDate(dateStr); } + + CGregorianCalendar::CGregorianCalendar(const StdString & dateStr,const StdString & timeOriginStr) + : CCalendar("Gregorian") + { initializeDate(dateStr, timeOriginStr); } + + CGregorianCalendar::CGregorianCalendar(int yr, int mth, int d, + int hr, int min, int sec) + : CCalendar("Gregorian") + { initializeDate(yr, mth, d, hr, min, sec) ; } + + CGregorianCalendar::~CGregorianCalendar(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + int CGregorianCalendar::getYearTotalLength(const CDate & date) const + { // Retourne la durée d'une année en seconde. + if ((date.getYear() % 4 == 0) && + ((date.getYear() % 100 != 0) || + (date.getYear() % 400 == 0) )) + return (366 * 86400); + return (365 * 86400); + } + + int CGregorianCalendar::getMonthLength(const CDate & date) const + { // Retourne la durée du mois en jour. + if (date.getMonth() == 2) + { // Traitement du cas particulier en Février. + if ((date.getYear() % 4 == 0) && + ((date.getYear() % 100 != 0) || + (date.getYear() % 400 == 0) )) + return (29); + return (28); + } + return (CCalendar::getMonthLength(date)); + } + + StdString CGregorianCalendar::getType(void) const + { return (StdString("gregorian")); } + + ///-------------------------------------------------------------- +} // namespace xmlioserver + diff --git a/src/date/gregorian.hpp b/src/date/gregorian.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b6a9ff4f5d4e45bd9e4b7d83c6590277039068bb --- /dev/null +++ b/src/date/gregorian.hpp @@ -0,0 +1,39 @@ +#ifndef __XMLIO_CGregorianCalendar__ +#define __XMLIO_CGregorianCalendar__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "calendar.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CGregorianCalendar : public CCalendar + { + /// Typedef /// + typedef CCalendar SuperClass; + + public : + + /// Constructeur /// +// CGregorianCalendar(void); // Not implemented yet. + CGregorianCalendar(const StdString & dateStr); + CGregorianCalendar(const StdString & dateStr,const StdString & timeOriginStr); + CGregorianCalendar(int yr = 0, int mth = 1, int d = 1, + int hr = 0, int min = 0, int sec = 0); + CGregorianCalendar(const CGregorianCalendar & calendar); // Not implemented yet. + CGregorianCalendar(const CGregorianCalendar * calendar); // Not implemented yet. + + /// Accesseurs /// + virtual int getYearTotalLength(const CDate & date) const; + virtual int getMonthLength(const CDate & date) const; + virtual StdString getType(void) const; + + /// Destructeur /// + virtual ~CGregorianCalendar(void); + + }; // class CGregorianCalendar + +} // namespace xmlioserver + +#endif // __XMLIO_CGregorianCalendar__ diff --git a/src/date/julian.cpp b/src/date/julian.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d5bb6fa5187af147c59b2744651de05f5ab51d9 --- /dev/null +++ b/src/date/julian.cpp @@ -0,0 +1,45 @@ +#include "julian.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + CJulianCalendar::CJulianCalendar(const StdString & dateStr) + : CCalendar("Julian") + { initializeDate(dateStr); } + + CJulianCalendar::CJulianCalendar(const StdString & dateStr,const StdString & timeOriginStr) + : CCalendar("Julian") + { initializeDate(dateStr, timeOriginStr); } + + CJulianCalendar::CJulianCalendar(int yr, int mth, int d, + int hr, int min, int sec) + : CCalendar("Julian") + { initializeDate(yr, mth, d, hr, min, sec) ; } + + CJulianCalendar::~CJulianCalendar(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + int CJulianCalendar::getYearTotalLength(const CDate & date) const + { // Retourne la durée d'une année en seconde. + if (date.getYear() % 4 == 0) return (366 * 86400); + return (365 * 86400); + } + + int CJulianCalendar::getMonthLength(const CDate & date) const + { // Retourne la durée du mois en jour. + if (date.getMonth() == 2) + { + if (date.getYear()%4 == 0) return 29; + return 28; + } + return (CCalendar::getMonthLength(date)); + } + + StdString CJulianCalendar::getType(void) const + { return (StdString("julian")); } + + ///-------------------------------------------------------------- +} // namespace xmlioserver diff --git a/src/date/julian.hpp b/src/date/julian.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ee0390449a7c1f72581bc6fca260c6b632381c95 --- /dev/null +++ b/src/date/julian.hpp @@ -0,0 +1,39 @@ +#ifndef __XMLIO_CJulianCalendar__ +#define __XMLIO_CJulianCalendar__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "calendar.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CJulianCalendar : public CCalendar + { + /// Typedef /// + typedef CCalendar SuperClass; + + public : + + /// Constructeur /// +// CJulianCalendar(void); // Not implemented yet. + CJulianCalendar(const StdString & dateStr); + CJulianCalendar(const StdString & dateStr,const StdString & timeOriginStr); + CJulianCalendar(int yr = 0, int mth = 1, int d = 1, + int hr = 0, int min = 0, int sec = 0); + CJulianCalendar(const CJulianCalendar & calendar); // Not implemented yet. + CJulianCalendar(const CJulianCalendar * calendar); // Not implemented yet. + + /// Accesseurs /// + virtual int getYearTotalLength(const CDate & date) const; + virtual int getMonthLength(const CDate & date) const; + virtual StdString getType(void) const; + + /// Destructeur /// + virtual ~CJulianCalendar(void); + + }; // class CJulianCalendar + +} // namespace xmlioserver + +#endif // __XMLIO_CJulianCalendar__ diff --git a/src/date/noleap.cpp b/src/date/noleap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8cf5f48abc7820d6d50a1c94e898937116d483e --- /dev/null +++ b/src/date/noleap.cpp @@ -0,0 +1,32 @@ +#include "noleap.hpp" +#include "calendar.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + CNoLeapCalendar::CNoLeapCalendar(const StdString & dateStr) + : CCalendar("NoLeap", dateStr) + { initializeDate(dateStr); } + + CNoLeapCalendar::CNoLeapCalendar(const StdString & dateStr,const StdString & timeOriginStr) + : CCalendar("NoLeap", dateStr, timeOriginStr) + { initializeDate(dateStr, timeOriginStr); } + + CNoLeapCalendar::CNoLeapCalendar(int yr, int mth, int d, + int hr, int min, int sec) + : CCalendar("NoLeap") + { initializeDate(yr, mth, d, hr, min, sec) ; } + + + CNoLeapCalendar::~CNoLeapCalendar(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + StdString CNoLeapCalendar::getType(void) const + { return (StdString("noleap")); } + + ///-------------------------------------------------------------- +} // namespace xmlioserver + diff --git a/src/date/noleap.hpp b/src/date/noleap.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9c2144ef205ad239437f19a16d2965985669269b --- /dev/null +++ b/src/date/noleap.hpp @@ -0,0 +1,38 @@ +#ifndef __XMLIO_CNoLeapCalendar__ +#define __XMLIO_CNoLeapCalendar__ + +/// xmlioserver headers /// +#include "xmlioserver_spl.hpp" +#include "calendar.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CNoLeapCalendar : public CCalendar + { + /// Typedef /// + typedef CCalendar SuperClass; + + public : + + /// Constructeur /// +// CNoLeapCalendar(void); // Not implemented yet. + CNoLeapCalendar(const StdString & dateStr); + CNoLeapCalendar(const StdString & dateStr,const StdString & timeOriginStr); + CNoLeapCalendar(int yr = 0, int mth = 1, int d = 1, + int hr = 0, int min = 0, int sec = 0); + CNoLeapCalendar(const CNoLeapCalendar & calendar); // Not implemented yet. + CNoLeapCalendar(const CNoLeapCalendar * calendar); // Not implemented yet. + + /// Accesseurs /// + virtual StdString getType(void) const; + + /// Destructeur /// + virtual ~CNoLeapCalendar(void); + + }; // class CNoLeapCalendar + +} // namespace xmlioserver + +#endif // __XMLIO_CNoLeapCalendar__ + diff --git a/src/declare_attribute.hpp b/src/declare_attribute.hpp new file mode 100644 index 0000000000000000000000000000000000000000..be7a7354328b9430c5fa974be4c77895bf459a92 --- /dev/null +++ b/src/declare_attribute.hpp @@ -0,0 +1,130 @@ +#ifndef __XMLIO_DECLARE_ATTRIBUTE__ +#define __XMLIO_DECLARE_ATTRIBUTE__ + +/// ///////////////////////////// Macros ///////////////////////////// /// + +#define DECLARE_ATTRIBUTE(type, name) \ + class name##_attr : public CAttributeTemplate \ + { \ + public : \ + name##_attr(void) \ + : CAttributeTemplate \ + (#name, *CAttributeMap::Current) \ + { /* Ne rien faire de plus */ } \ + type operator=(const type & value) \ + { return (CAttributeTemplate::operator=(value)); } \ + virtual ~name##_attr(void) \ + { /* Ne rien faire de plus */ } \ + } name; + +#define DECLARE_ARRAY(T_num, T_rank, name) \ + class name##_attr : public CAttributeArray \ + { \ + public : \ + using CAttributeArray::operator = ; \ + name##_attr(void) : CAttributeArray (#name, *CAttributeMap::Current) {} \ + virtual ~name##_attr(void) {} \ + } name; + +#define DECLARE_CLASS_ENUM(name) \ + class name##_attr : public CAttributeEnum \ + { \ + public : \ + name##_attr(void) : CAttributeEnum(#name, *CAttributeMap::Current) { } \ + virtual ~name##_attr(void) {} \ + } name; + +#define DECLARE_ENUM2(name,arg1,arg2) \ + class Enum_##name \ + { \ + public: \ + enum t_enum { arg1=0, arg2} ; \ + const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2 } ; return enumStr ; } \ + int getSize(void) const { return 2 ; } \ + } ; \ + DECLARE_CLASS_ENUM(name) + +#define DECLARE_ENUM3(name,arg1,arg2,arg3) \ + class Enum_##name \ + { \ + public: \ + enum t_enum { arg1=0, arg2, arg3} ; \ + const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3 } ; return enumStr ; } \ + int getSize(void) const { return 3 ; } \ + } ; \ + DECLARE_CLASS_ENUM(name) + +#define DECLARE_ENUM4(name,arg1,arg2,arg3,arg4) \ + class Enum_##name \ + { \ + public: \ + enum t_enum { arg1=0, arg2, arg3,arg4} ; \ + const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4 } ; return enumStr ; } \ + int getSize(void) const { return 4 ; } \ + } ; \ + DECLARE_CLASS_ENUM(name) + +#define DECLARE_ENUM5(name,arg1,arg2,arg3,arg4,arg5) \ + class Enum_##name \ + { \ + public: \ + enum t_enum { arg1=0, arg2, arg3,arg4,arg5} ; \ + const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5 } ; return enumStr ; } \ + int getSize(void) const { return 5 ; } \ + } ; \ + DECLARE_CLASS_ENUM(name) + +#define DECLARE_ENUM6(name,arg1,arg2,arg3,arg4,arg5,arg6) \ + class Enum_##name \ + { \ + public: \ + enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6} ; \ + const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5,#arg6 } ; return enumStr ; } \ + int getSize(void) const { return 6 ; } \ + } ; \ + DECLARE_CLASS_ENUM(name) + +#define DECLARE_ENUM7(name,arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ + class Enum_##name \ + { \ + public: \ + enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6,arg7} ; \ + const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5,#arg6,#arg7 } ; return enumStr ; } \ + int getSize(void) const { return 7 ; } \ + } ; \ + DECLARE_CLASS_ENUM(name) + +#define DECLARE_ENUM8(name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \ + class Enum_##name \ + { \ + public: \ + enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6,arg7,arg8} ; \ + const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5,#arg6,#arg7,#arg8 } ; return enumStr ; } \ + int getSize(void) const { return 8 ; } \ + } ; \ + DECLARE_CLASS_ENUM(name) + + #define DECLARE_ENUM9(name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) \ + class Enum_##name \ + { \ + public: \ + enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6,arg7,arg8,arg9} ; \ + const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5,#arg6,#arg7,#arg8,#arg9 } ; return enumStr ; } \ + int getSize(void) const { return 9 ; } \ + } ; \ + DECLARE_CLASS_ENUM(name) + + +#define BEGIN_DECLARE_ATTRIBUTE_MAP(type) \ + class type##Attributes : public virtual CAttributeMap \ + { \ + public : + +#define END_DECLARE_ATTRIBUTE_MAP(type) \ + type##Attributes (void) : CAttributeMap() \ + { /* Ne rien faire de plus */ } \ + virtual ~type##Attributes (void) \ + { /* Ne rien faire de plus */ } \ + }; + +#endif // __XMLIO_DECLARE_ATTRIBUTE__ diff --git a/src/declare_group.hpp b/src/declare_group.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b164ea285b27ab15f53d45eb61431fb34e96babd --- /dev/null +++ b/src/declare_group.hpp @@ -0,0 +1,58 @@ +#ifndef __XMLIO_DECLARE_GROUP__ +#define __XMLIO_DECLARE_GROUP__ + +/// ///////////////////////////// Macros ///////////////////////////// /// + +#define DECLARE_GROUP(type) \ + class type##Group \ + : public CGroupTemplate \ + { \ + public: \ + typedef type RelChild; \ + typedef type##Group RelGroup; \ + typedef type##Attributes RelAttributes; \ + \ + type##Group(void) \ + : CGroupTemplate () \ + { /* Ne rien faire de plus */ } \ + type##Group(const StdString& _id) \ + : CGroupTemplate (_id) \ + { /* Ne rien faire de plus */ } \ + \ + static ENodeType GetType(void) \ + { return static_cast(RelChild::GetType()+1); } \ + \ + virtual ~type##Group(void) \ + { /* Ne rien faire de plus */ } \ + }; \ + typedef type##Group type##Definition + +#define DECLARE_GROUP_PARSE_REDEF(type) \ + class type##Group \ + : public CGroupTemplate \ + { \ + public: \ + typedef type RelChild; \ + typedef type##Group RelGroup; \ + typedef type##Attributes RelAttributes; \ + typedef CGroupTemplate \ + SuperClass; \ + \ + type##Group(void) \ + : CGroupTemplate () \ + { /* Ne rien faire de plus */ } \ + type##Group(const StdString& _id) \ + : CGroupTemplate (_id) \ + { /* Ne rien faire de plus */ } \ + \ + static ENodeType GetType(void) \ + { return static_cast(RelChild::GetType()+1); } \ + \ + virtual void parse(xml::CXMLNode & node, bool withAttr = true); \ + \ + virtual ~type##Group(void) \ + { /* Ne rien faire de plus */ } \ + }; \ + typedef type##Group type##Definition + +#endif // __XMLIO_DECLARE_GROUP__ diff --git a/src/duration.cpp b/src/duration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..968ed9275e3b2c8e83dd85fb567ecbb63b148075 --- /dev/null +++ b/src/duration.cpp @@ -0,0 +1,161 @@ +#include "duration.hpp" +#include "date.hpp" +#include "calendar.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + const CDuration Year = {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + Month = {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + Week = {0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0}, + Day = {0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + Hour = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + Minute = {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, + Second = {0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, + NoneDu = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + TimeStep = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}; + + ///--------------------------------------------------------------- + + CDuration & CDuration::operator=(const CDuration & duration) + { + year = duration.year; month = duration.month; day = duration.day; + hour = duration.hour; minute = duration.minute; second = duration.second; timestep=duration.timestep; + return *this; + } + + StdOStream & operator<<(StdOStream & out, const CDuration & duration) + { + StdOStringStream sout; + bool testValue = true; + if(duration.year != 0.0) { testValue = false; sout << duration.year << "y "; } + if(duration.month != 0.0) { testValue = false; sout << duration.month << "mo "; } + if(duration.day != 0.0) { testValue = false; sout << duration.day << "d "; } + if(duration.hour != 0.0) { testValue = false; sout << duration.hour << "h "; } + if(duration.minute != 0.0) { testValue = false; sout << duration.minute << "mi "; } + if(duration.second != 0.0) { testValue = false; sout << duration.second << "s "; } + if(duration.timestep != 0.0 || testValue) { sout << duration.timestep << "ts "; } + + // << suppression de l'espace en fin de chaîne. + out << (sout.str().substr(0, sout.str().size()-1)); + return out; + } + + StdIStream & operator>>(StdIStream & in , CDuration & duration) + { + duration.year = duration.month = duration.day = + duration.hour = duration.minute = duration.second = duration.timestep=0.0; + double v = 1.0; + char c = '/'; + while (!in.eof()) + { + if (!(in >> v >> c)) + { + //DEBUG("----> Pb StdIStream & operator>>(StdIStream & in , CDuration & duration)"); + //if (in.eof()) DEBUG("----> Fin de fichier StdIStream & operator>>(StdIStream & in , CDuration & duration)"); + } + if (in.eof()) + { + //DEBUG("----> Fin de fichier StdIStream & operator>>(StdIStream & in , CDuration & duration)"); + break; + } + switch (c) + { + case 'y': duration.year = v; break; + case 'd': duration.day = v; break; + case 'h': duration.hour = v; break; + case 's': duration.second = v; break; + case 'm': + { + in >> c; + if (c == 'i') duration.minute = v; + else if(c == 'o') duration.month = v; + else + { + StdString valc("m"); valc.append(1, c); + //DEBUG("La chaine \"" << valc << "\" ne permet pas de définir une unité de durée."); + break; + } + break; + } + case 't' : + { + in >> c; + if (c=='s') duration.timestep = v; + break; + } + + default: + StdString valc; valc.append(1, c); + //DEBUG("La chaine \"" << valc << "\" ne permet pas de définir une unité de durée."); + break; + } + } + return in; + } + + //----------------------------------------------------------------- + + bool CDuration::isNone(void) const + { + if ((year == 0) && (month == 0) && (day == 0) && + (hour == 0) && (minute == 0) && (second == 0) && (timestep == 0)) + return true; + return false; + } + + //----------------------------------------------------------------- + CDuration & CDuration::solveTimeStep(const CCalendar & c) + { + CDuration timeStep=c.getTimeStep(); + second +=timestep*timeStep.second; + minute +=timestep*timeStep.minute; + hour +=timestep*timeStep.hour; + day +=timestep*timeStep.day; + month +=timestep*timeStep.month; + year +=timestep*timeStep.year; + timestep = 0; + return *this; + } + + CDuration & CDuration::resolve(const CCalendar & c) + { + // Simplification de l'écriture des minutes. + second += modf(minute, &minute) * (float)c.getMinuteLength(); + minute += int(second)/c.getMinuteLength(); second = int(second)%c.getMinuteLength(); + + // Simplification de l'écriture des heures. + minute += modf(hour , &hour) * (float)c.getHourLength(); + hour += int(minute)/c.getHourLength(); minute = int(minute)%c.getHourLength(); + + // Simplification de l'écriture des jours. + hour += modf(day, &day) * (float)c.getDayLength(); + day += int(hour) /c.getDayLength(); hour = int(hour)%c.getDayLength(); + + // > Aucune équivalence jour - mois fixée par avance. // + + // Simplification de l'écriture des années. + month += modf(year, &year) * (float)c.getYearLength(); + year += int(month) /c.getYearLength(); month = int(month)%c.getYearLength(); + return *this; + } + + //----------------------------------------------------------------- + + StdString CDuration::toString(void) const + { + const CDuration & own = *this; + StdOStringStream oss; oss << own; + return oss.str(); + } + + CDuration CDuration::FromString(const StdString & str) + { + CDuration dr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + StdIStringStream iss(str); iss >> dr; + return dr; + } + + ///--------------------------------------------------------------- +} // namespace xios + diff --git a/src/duration.hpp b/src/duration.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4612bb974d8c926143e91b450908e4ff6a2a7ff2 --- /dev/null +++ b/src/duration.hpp @@ -0,0 +1,51 @@ +#ifndef __XMLIO_CDuration__ +#define __XMLIO_CDuration__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + typedef long long int Time; + class CCalendar; + + ///--------------------------------------------------------------- + typedef struct _duration + { + public : + + /// Opérateurs /// + struct _duration & operator=(const struct _duration& duration); + + friend StdOStream & operator<<(StdOStream & out, const struct _duration& duration); + friend StdIStream & operator>>(StdIStream & in , struct _duration& duration); + + /// Test /// + bool isNone(void) const; + + /// Traitement /// + struct _duration & resolve(const CCalendar & calendar); + struct _duration & solveTimeStep(const CCalendar & c) ; + /// Autres /// + StdString toString(void) const; + + public: /* static */ + + static struct _duration FromString(const StdString & str); + + /// Propriétés publiques /// + double year, month, day, hour, minute, second, timestep; + + } CDuration; + + ///--------------------------------------------------------------- + + const extern CDuration Year, Month , Week , Day , + Hour, Minute, Second, NoneDu, TimeStep ; + ///--------------------------------------------------------------- + +} // namespace xios + +#endif // __XMLIO_CDuration__ diff --git a/src/event_client.cpp b/src/event_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9bb77b5c5d76c0d41a9979a91683985e18469522 --- /dev/null +++ b/src/event_client.cpp @@ -0,0 +1,90 @@ +#include "xmlioserver_spl.hpp" +#include "event_client.hpp" +#include "buffer_out.hpp" +#include "message.hpp" +#include "type.hpp" +#include "mpi.hpp" + +namespace xios +{ + CEventClient::CEventClient(int classId_,int typeId_) + { + classId=classId_ ; + typeId=typeId_ ; + } + + void CEventClient::push(int rank,int nbSender,CMessage & msg) + { + nbSenders.push_back(nbSender) ; + ranks.push_back(rank) ; + messages.push_back(&msg) ; + } + + bool CEventClient::isEmpty(void) + { + return ranks.empty() ; + } + + list CEventClient::getRanks(void) + { + return ranks ; + } + + list CEventClient::getSizes(void) + { + list::iterator it ; + list sizes ; + size_t headerSize=sizeof(int)+sizeof(classId)+sizeof(typeId) ; + + for(it=messages.begin();it!=messages.end();++it) sizes.push_back((*it)->size()+headerSize) ; + return sizes ; + } + + void CEventClient::send(list& buffers) + { + list::iterator itBuff ; + list::iterator itMsg ; + list::iterator itSenders ; + + for(itBuff=buffers.begin(),itMsg=messages.begin(),itSenders=nbSenders.begin();itBuff!=buffers.end();++itBuff,++itMsg,++itSenders) + { + **itBuff<<*itSenders<& serverList_) + { + client=&client_ ; + nbSender=nbSender_ ; + serverList=serverList_ ; + + client->registerEvent(*this) ; + } + + list CEventClient::newEvent(int classId, int type, list sizes) + { + list::iterator it ; + list::iterator itBuff; + + + CMessage msg; + + msg< buffers=client->newEvent(*this,sizes) ; + + for(itBuff=buffers.begin();itBuff!=buffers.end();itBuff++) *(*itBuff)<sendEvent(*this) ; + } + +*/ + +} diff --git a/src/event_client.hpp b/src/event_client.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1953440fb5abe0b60d9fb2d7573f9af95bb6bdbc --- /dev/null +++ b/src/event_client.hpp @@ -0,0 +1,34 @@ +#ifndef __EVENT_CLIENT_HPP__ +#define __EVENT_CLIENT_HPP__ + +#include "xmlioserver_spl.hpp" +#include "buffer_out.hpp" +#include "message.hpp" + +namespace xios +{ + + class CEventClient + { + public: + +// CEventClient(CContextClient& client,int nbSender,list& serverList); + CEventClient(int classId, int typeId); + void push(int rank,int nbSender, CMessage& msg) ; + +// list newEvent(int classId, int type, list sizes) ; + list getRanks(void) ; + list getSizes(void) ; + void send(list&) ; + bool isEmpty(void) ; + list ranks ; + list nbSenders ; + list messages ; +// CContextClient* client ; + int classId ; + int typeId ; + } ; + +} + +#endif diff --git a/src/event_scheduler.cpp b/src/event_scheduler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..05fc52ec5fce36653dd4c45b076f78cabc1ff24f --- /dev/null +++ b/src/event_scheduler.cpp @@ -0,0 +1,256 @@ +#include "event_scheduler.hpp" +#include "xmlioserver_spl.hpp" +#include "mpi.hpp" + +namespace xios +{ + + + CEventScheduler::CEventScheduler(const MPI_Comm& comm) + { + MPI_Comm_dup(comm, &communicator) ; + MPI_Comm_size(communicator,&mpiSize) ; + MPI_Comm_rank(communicator,&mpiRank); + + + int maxChild=1 ; + + int m ; + do + { + m=1 ; + maxChild=maxChild+1 ; + for(int i=0;i(maxLevel+1) ; + child=vector >(maxLevel+1,vector(maxChild)) ; + nbChild=vector (maxLevel+1) ; + + level=0 ; + begin=0 ; + end=mpiSize-1 ; + nb=end-begin+1 ; + + do + { + n=0 ; + pos=begin ; + nbChild[level]=0 ; + parent[level+1]=begin ; + for(int i=0;i=pos && mpiRank1) ; + + + } + + CEventScheduler::~CEventScheduler() + { + + } + + void CEventScheduler::registerEvent(const size_t timeLine, const size_t contextHashId) + { + registerEvent(timeLine, contextHashId, level) ; + } + + void CEventScheduler::registerEvent(const size_t timeLine, const size_t contextHashId, const size_t lev) + { + + SPendingRequest* sentRequest=new SPendingRequest ; + sentRequest->buffer[0]=timeLine ; + sentRequest->buffer[1]=contextHashId ; + sentRequest->buffer[2]=lev-1 ; + + pendingSentParentRequest.push(sentRequest) ; + MPI_Isend(sentRequest->buffer,3, MPI_UNSIGNED_LONG, parent[lev], 0, communicator, &sentRequest->request) ; + } + + bool CEventScheduler::queryEvent(const size_t timeLine, const size_t contextHashId) + { + + if (! eventStack.empty() && eventStack.front().first==timeLine && eventStack.front().second==contextHashId) + { + eventStack.pop() ; + return true ; + } + else return false ; + } + + void CEventScheduler::checkEvent(void) + { + checkChildRequest() ; + checkParentRequest() ; + + } + + + + void CEventScheduler::checkParentRequest(void) + { + int completed ; + MPI_Status status ; + int received ; + SPendingRequest* recvRequest ; + completed=true ; + + // check sent request to parent + while (! pendingSentParentRequest.empty() && completed) + { + MPI_Test( & pendingSentParentRequest.front()->request, &completed, &status) ; + if (completed) + { + delete pendingSentParentRequest.front() ; + pendingSentParentRequest.pop() ; + } + } + + // probe if a message is coming from parent + received=true ; + while(received) + { + MPI_Iprobe(MPI_ANY_SOURCE,1,communicator,&received, &status) ; + if (received) + { + recvRequest=new SPendingRequest ; + MPI_Irecv(recvRequest->buffer, 3, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, 1, communicator, &(recvRequest->request)) ; + pendingRecvParentRequest.push(recvRequest) ; + } + } + + // check sent request from parent + completed=true ; + while (! pendingRecvParentRequest.empty() && completed) + { + recvRequest=pendingRecvParentRequest.front() ; + MPI_Test( &(recvRequest->request), &completed, &status) ; + if (completed) + { + size_t timeLine=recvRequest->buffer[0] ; + size_t hashId=recvRequest->buffer[1] ; + size_t lev=recvRequest->buffer[2] ; + delete recvRequest ; + pendingRecvParentRequest.pop() ; + + if (lev==level) eventStack.push(pair(timeLine,hashId)) ; + else bcastEvent(timeLine, hashId, lev) ; + } + } + + } + + void CEventScheduler::checkChildRequest(void) + { +// function call only by parent mpi process + + MPI_Status status ; + int received ; + received=true ; + SPendingRequest* recvRequest ; + + // check for posted requests and make the corresponding receive + while(received) + { + MPI_Iprobe(MPI_ANY_SOURCE,0,communicator,&received, &status) ; + if (received) + { + recvRequest=new SPendingRequest ; + MPI_Irecv(recvRequest->buffer, 3, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, 0, communicator, &recvRequest->request) ; + pendingRecvChildRequest.push_back(recvRequest) ; + } + } + + // check if receive request is achieved + + for(list::iterator it=pendingRecvChildRequest.begin(); it!=pendingRecvChildRequest.end() ; ) + { + MPI_Test(&((*it)->request),&received,&status) ; + if (received) + { + size_t timeLine=(*it)->buffer[0] ; + size_t hashId=(*it)->buffer[1] ; + size_t lev=(*it)->buffer[2] ; + + SEvent event={timeLine,hashId,lev} ; + delete *it ; // free mem + it=pendingRecvChildRequest.erase(it) ; // get out of the list + + map< SEvent,int>::iterator itEvent=recvEvent.find(event) ; + if (itEvent==recvEvent.end()) + { + itEvent=(recvEvent.insert(pair< SEvent ,int > (event,1))).first ; + + } + else (itEvent->second)++ ; + if (itEvent->second==nbChild[lev]) + { + if (lev==0) + { + bcastEvent(timeLine,hashId,lev) ; + recvEvent.erase(itEvent) ; + } + else + { + registerEvent( timeLine,hashId,lev) ; + } + } + } + else ++it ; + } + + // check if bcast request is achieved + + for(list::iterator it=pendingSentChildRequest.begin(); it!=pendingSentChildRequest.end() ; ) + { + MPI_Test(&(*it)->request,&received,&status) ; + if (received) + { + delete *it ; // free memory + it = pendingSentChildRequest.erase(it) ; // get out of the list + + } + else ++it ; + + } + } + + void CEventScheduler::bcastEvent(const size_t timeLine, const size_t contextHashId, const size_t lev) + { + SPendingRequest* sentRequest ; + + + for(int i=0; ibuffer[0]=timeLine ; + sentRequest->buffer[1]=contextHashId ; + sentRequest->buffer[2]=lev+1 ; + MPI_Isend(sentRequest->buffer,3, MPI_UNSIGNED_LONG, child[lev][i], 1, communicator, & sentRequest->request) ; + pendingSentChildRequest.push_back(sentRequest) ; + } + } + + +} diff --git a/src/event_scheduler.hpp b/src/event_scheduler.hpp new file mode 100644 index 0000000000000000000000000000000000000000..702a7e02160f54d50edcf7398b46becf5fe36987 --- /dev/null +++ b/src/event_scheduler.hpp @@ -0,0 +1,176 @@ +#ifndef __EVENT_SCHEDULER_HPP__ +#define __EVENT_SCHEDULER_HPP__ + +#include "xmlioserver_spl.hpp" +#include "mpi.hpp" + +namespace xios +{ + + //! Event scheduling class. An instance of this class is used to order the event providing from different context to avoid dead lock. + /*! + * Event are ordered in a same context using the timeLine id, so each server will process the same event. But between different + * context, events are not scheduled and servers may choose to process different events and deadlock or MPI crash may occurs if + * collective MPI communication are involved by the events. + * This class solve the problem by scheduling the event and choose which event must be process by each server to insure correct + * synchronisation. Information is send by asynchronous MPI communication to the root process that order the different events + * (First In First Out) and brodcast the information to the other servers. To avoid to much incoming communication for the root + * process, and hierachical tree is used for communicating from a limited number of child processes to the parent. + */ + + class CEventScheduler + { + public: + //! Constructor + /*! A new communicator is created by duplicate comm. The communicating tree hierarchy is created. + * @param[in] comm : MPI communicator du duplicate for internal use + */ + CEventScheduler(const MPI_Comm& comm) ; + + + //! Destructor + ~CEventScheduler() ; + + + + //! public interface for registring an event from the server + /*! + * @param[in] timeLine : Time line id of the event + * @param[in] contextHashId : Hashed id of the context + */ + void registerEvent(const size_t timeLine, const size_t contextHashId) ; + + + + //! public interface for query if the event defined by timeLine and hashId is sheduled next + /*! + * @param[in] timeLine : Time line id of the event + * @param[in] contextHasId : Hashed id of the context + * @return : boolean value, true is the event is scheduled next + * + * If the event is scheduled next, it is remove from the `eventStack` queue list + */ + bool queryEvent(const size_t timeLine, const size_t contextHashId) ; + + + //! Public interface to give the hand to the instance to check pending or incoming message. + /*! + * Must be called periodicaly. Call `checkParentRequest` and `checkChildRequest` private method. + */ + void checkEvent(void) ; + + private: + + + //! Send an event to the parent of level `lev+1` + /*! + * @param[in] timeLine : Time line id of the event + * @param[in] contextHasId : Hashed id of the context + * @param[in] lev : actual level of the child in the hierarchy + * The event is sent by an asynchrounous MPI_ISend + */ + void registerEvent(const size_t timeLine, const size_t contextHashId, const size_t lev) ; + + + + //! Children side. Check potential incoming message and if pending request are completed + /*! + * - Check by `MPI_Test` if pending request sent to parents are complete. + * - Probe incoming message from parent by using `MPI_Probe`. If yes, post an asynchronous reception by `MPI_IRecv` + * - Check by `MPI_Test` if pending received requests are complete. if yes : + * + Broadcast the event to the childrens if is also a parent + * + Otherwise : push the incomming event in the `eventStack` queue. + */ + void checkParentRequest(void) ; + + + + //! Parent side. Check potential incoming message and if pending request are completed + /*! + * - Probe incoming message from chidren by using `MPI_Probe`. If yes, post an asynchronous reception by `MPI_IRecv`. + * - Check pending received event request from children using `MPI_Probe`. If and event is received, it is incerted in the + * map `recvEvent` which is increased by 1. If the number of request received from children for this event is equal to the number + * of children then : + * + if the event level is 0, bcast the event to the children. + * + else send the event to the parent. + * - Check pending sent event request to children using `MPI_TEST` and if complete release the corresponding buffer + */ + void checkChildRequest(void) ; + + + + //! Parent side. Broadcast a received event from the parent to the children. + /*! + * @param[in] timeLine : Time line id of the event + * @param[in] contextHasId : Hashed id of the context + * @param[in] lev : actual level of the child in the hierarchy + * Asynchronus MPI_ISend is used. + */ + void bcastEvent(const size_t timeLine, const size_t contextHashId, const size_t lev) ; + + + + + //! Structure defining an event, composed of the timeLine, the context hashId and the hierachical level of the communication. + struct SEvent + { + size_t timeLine ; /*!< Time line id of the event in the context */ + size_t hashId ; /*!< hassh id of the context */ + size_t level ; /*! > eventStack ; + queue pendingSentParentRequest ; /*!< Pending request sent to parent */ + queue pendingRecvParentRequest ; /*!< Pending request recv from parent */ + list pendingRecvChildRequest ; /*!< Pending request recv from child */ + list pendingSentChildRequest ; /*!< Pending request sent to child */ + map< SEvent, int > recvEvent ; /*!< list of event received from children. Contains the currnet number children that have already post the same event */ + + + int level ; /*!< Number of hierachical level for communication */ + vector parent ; /*!< Parent rank for each level */ + vector > child ; /*!< List of child rank for each level */ + vector nbChild ; /*!< Number of child for each level */ + + } ; +} + +#endif diff --git a/src/event_server.cpp b/src/event_server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4aa33711f83c6e18317902d5c8aa2d2be6f68dc2 --- /dev/null +++ b/src/event_server.cpp @@ -0,0 +1,64 @@ +#include "xmlioserver_spl.hpp" +#include "buffer_in.hpp" +#include "type.hpp" +#include "event_server.hpp" +#include "buffer_server.hpp" + +namespace xios +{ + + void CEventServer::push(int rank,CServerBuffer* serverBuffer,char* startBuffer,int size) + { + CBufferIn buffer(startBuffer,size) ; + size_t timeLine ; + int myClassId ; + int myType ; + int myNbSender ; + + buffer>>size>>timeLine>>myNbSender>>myClassId>>myType ; + + if (subEvents.empty()) + { + nbSender=myNbSender ; + classId=myClassId; + type=myType ; + } + else + { + if (nbSender!=myNbSender || classId!=myClassId || type!=myType) + ERROR("void CEventServer::push(int rank,char* startBuffer,int size)", + "Callers of an event are not coherent") ; + } + + SSubEvent ev ; + ev.rank=rank ; + ev.serverBuffer=serverBuffer ; + ev.buffer=new CBufferIn(buffer.ptr(),buffer.remain()) ; + ev.size=size ; + subEvents.push_back(ev) ; + + if (subEvents.size()>nbSender) + { + ERROR("void CEventServer::push(int rank,CServerBuffer* serverBuffer,char* startBuffer,int size)", + "Callers of an event are not coherent") ; + } + + } + + bool CEventServer::isFull(void) + { + return (nbSender==subEvents.size()) ; + } + + CEventServer::~CEventServer() + { + list::iterator it; + + for(it=subEvents.begin();it!=subEvents.end();it++) + { + it->serverBuffer->freeBuffer(it->size) ; + delete it->buffer ; + } + } + +} diff --git a/src/event_server.hpp b/src/event_server.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a686f76d07f3a40a1955e923b8f04fd22d153cfe --- /dev/null +++ b/src/event_server.hpp @@ -0,0 +1,38 @@ +#ifndef __EVENT_SERVER_HPP__ +#define __EVENT_SERVER_HPP__ + +#include "xmlioserver_spl.hpp" +#include "buffer_in.hpp" +#include "buffer_server.hpp" + +namespace xios +{ + + class CEventServer + { + public: + + int classId ; + int type ; + int nbSender ; + + + void push(int rank,CServerBuffer* serverBuffer ,char* startBuffer,int size) ; + + struct SSubEvent + { + int rank ; + CServerBuffer* serverBuffer ; + CBufferIn* buffer ; + int size ; + } ; + + list subEvents ; + + bool isFull(void) ; + ~CEventServer() ; + } ; + +} + +#endif diff --git a/src/exception.cpp b/src/exception.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc765d8217bc85d9128b9e6c73afda371061919c --- /dev/null +++ b/src/exception.cpp @@ -0,0 +1,63 @@ +#include "exception.hpp" + +/// boost headers /// +#include +#include "client.hpp" +#include "server.hpp" +#include "cxios.hpp" +#include "log.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + CException::CException(void) + : CObject(), desc_rethrow(true) + { /* Ne rien faire de plus */ } + + CException::CException(const StdString & id) + : CObject(id), desc_rethrow(true) + { /* Ne rien faire de plus */ } + + CException::CException(const CException & exception) + : std::basic_ios() + , CObject(exception.getId()) + , StdOStringStream() + , desc_rethrow(false) + { (*this) << exception.str(); } + + CException::~CException(void) + { + if (desc_rethrow) +#ifdef __XIOS_NOABORT + { + throw (*this); + } +#else + { + error << this->getMessage() << std::endl; + abort(); + } +#endif + } + + //--------------------------------------------------------------- + + StdString CException::getMessage(void) const + { + StdOStringStream oss; + oss << "> Error [" << this->getId() << "] : " << this->str(); + return (oss.str()); + } + + StdOStringStream & CException::getStream(void) + { return (*boost::polymorphic_cast(this)); } + + StdString CException::toString(void) const + { return (StdString(this->getMessage())); } + + void CException::fromString(const StdString & str) + { this->str(str); } + + //--------------------------------------------------------------- + +} // namespace xios diff --git a/src/exception.hpp b/src/exception.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e047841fda71f99b03c3c5508d31a6693fee7010 --- /dev/null +++ b/src/exception.hpp @@ -0,0 +1,56 @@ +#ifndef __XMLIO_CException__ +#define __XMLIO_CException__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "object.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CException + : private CObject, public StdOStringStream + { + typedef CObject SuperClass; + + public : + + /// Constructeurs /// + CException(void); + explicit CException(const StdString & id); + CException(const CException & exception); + CException(const CException * const exception); // Not implemented. + + /// Accesseurs /// + StdString getMessage(void) const; + StdOStringStream & getStream(void); + + /// Destructeur /// + virtual ~CException(void); + + /// Autre /// + virtual StdString toString(void) const; + virtual void fromString(const StdString & str); + + private : + + /// Propriétés /// + bool desc_rethrow; // throw destructor + + }; // CException +} // namespace xios + +/// //////////////////////////// Macros //////////////////////////// /// + +#define INFO(x) \ + "In file \'" __FILE__ "\', line " << __LINE__ << " -> " x << std::endl; + +#ifdef __XIOS_DEBUG +# define DEBUG(x) std::clog << "> Debug " << INFO(x) +#else +# define DEBUG(x) +#endif + +#define ERROR(id, x) CException(id).getStream() << INFO(x) + +#endif // __XMLIO_CException__ diff --git a/src/functor.cpp b/src/functor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ec415e0c5b727537d29626c14d2c19529aaa631 --- /dev/null +++ b/src/functor.cpp @@ -0,0 +1,66 @@ +#include "functor.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Définitions ////////////////////// /// + + CFunctor::CFunctor(const StdString & id, CArray& doutput) + : SuperClass(id), doutput(doutput), nbcall(0),hasMissingValue(false) + { /* Ne rien faire de plus */ } + + CFunctor::CFunctor(const StdString & id, CArray& doutput, double missingValue) + : SuperClass(id), doutput(doutput), nbcall(0),hasMissingValue(true),missingValue(missingValue) + { + /* Ne rien faire de plus */ + } + + CFunctor::~CFunctor(void) + { /* Ne rien faire de plus */ } + + //--------------------------------------------------------------- + + CArray CFunctor::getDataOutput(void) const + { + return (this->doutput); + } + + //--------------------------------------------------------------- + + StdString CFunctor::toString(void) const + { + ERROR("CFunctor::toString()", << "Not implemented yet !"); + return (SuperClass::getId()); + } + + void CFunctor::fromString(const StdString & str) + { + ERROR("CFunctor::fromString(str)", + << "[ str = " << str << "] Not implemented yet !"); + } + + //--------------------------------------------------------------- + + CArray CFunctor::operator ()(const CArray& dinput) + { + this->nbcall++; + if (dinput.numElements() != this->doutput.numElements()) + ERROR("CFunctor::operator ()(dinput)", + << "[ input size = " << dinput.numElements() + << ", output size = " << this->doutput.numElements() << " ]" + << " size of input array != size of output array !"); + this->apply(dinput, this->doutput); + return (this->doutput); + } + + void CFunctor::final(void) + { + this->nbcall = 0; + } + + //--------------------------------------------------------------- + + } // namespace func +} // namespace xios diff --git a/src/functor.hpp b/src/functor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..512aa8e616215acf09d8d78be4d95d056e4406c3 --- /dev/null +++ b/src/functor.hpp @@ -0,0 +1,62 @@ +#ifndef __XMLIO_CFunctor__ +#define __XMLIO_CFunctor__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Déclarations ////////////////////// /// + class CFunctor : public CObject + { + /// Définition de type /// + typedef CObject SuperClass; + public : + enum ETimeType { once, instant, centered } ; + + /// Accesseurs /// + CArray getDataOutput(void) const; + /// Opérateur /// + CArray operator ()(const CArray& dinput); + virtual ETimeType timeType(void) = 0 ; + + /// Destructeur /// + virtual ~CFunctor(void); + + //Traitement /// + virtual void final(void); + + protected : + + /// Traitement /// + virtual void apply(const CArray& dinput, CArray& doutput) = 0; + + /// Autres /// + virtual StdString toString(void) const; + virtual void fromString(const StdString & str); + + /// Constructeurs /// + CFunctor(void); // Not implemented. + CFunctor(const StdString & id, CArray& doutput); + CFunctor(const StdString & id, CArray& doutput, double missingValue); + CFunctor(const CFunctor & functor); // Not implemented. + CFunctor(const CFunctor * const functor); // Not implemented. + protected : + /// Propriétés privées /// + CArray& doutput; + /// Propriétés protégées /// + int nbcall; + bool hasMissingValue ; + double missingValue ; + CArray nbcalls ; + }; // class CFunctor + } // namespace func +} // namespace xios + +//#include "functor_type.hpp" + +#endif // __XMLIO_CFunctor__ diff --git a/src/functor/accumulate.cpp b/src/functor/accumulate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..84ce0eda4ba49be0f71309b42075d1a2fec78d9d --- /dev/null +++ b/src/functor/accumulate.cpp @@ -0,0 +1,51 @@ +#include "accumulate.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Définitions ////////////////////// /// + + CAccumulate::CAccumulate(CArray& doutput) + : SuperClass(StdString("accumulate"), doutput) + { /* Ne rien faire de plus */ } + + CAccumulate::CAccumulate(CArray& doutput, double missingValue) + : SuperClass(StdString("accumulate"), doutput, missingValue) + { /* Ne rien faire de plus */ } + + CAccumulate::~CAccumulate(void) + { /* Ne rien faire de plus */ } + + //--------------------------------------------------------------- + + void CAccumulate::apply(const CArray& _dinput, + CArray& _doutput) + { + if (this->nbcall == 1) _doutput=_dinput ; + else + { + if (hasMissingValue) + { + int i, n =_dinput.numElements() ; + const double * in=_dinput.dataFirst() ; + double* out=_doutput.dataFirst(); + for (i=0; inbcall = 0; + } + } // namespace func +} // namespace xmlioserver diff --git a/src/functor/accumulate.hpp b/src/functor/accumulate.hpp new file mode 100644 index 0000000000000000000000000000000000000000..912687b54b29439f6df0768e53055563c5750843 --- /dev/null +++ b/src/functor/accumulate.hpp @@ -0,0 +1,41 @@ +#ifndef __XMLIO_CAccumulate__ +#define __XMLIO_CAccumulate__ + +/// xmlioserver headers /// +#include "functor.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Déclarations ////////////////////// /// + class CAccumulate : public CFunctor + { + /// Définition de type /// + typedef CFunctor SuperClass; + + public : + + /// Constructeurs /// + //CAccumulate(void); // Not implemented. + //CAccumulate(const CFunData & data); + CAccumulate(CArray& doutput); + CAccumulate(CArray& doutput, double missingValue); + //CAccumulate(const CAccumulate & accumulate); // Not implemented. + //CAccumulate(const CAccumulate * const accumulate); // Not implemented. + + /// Traitement /// + virtual void apply(const CArray& dinput, CArray& doutput); + virtual void final(void) ; + virtual ETimeType timeType(void) { return centered ; } + + /// Destructeur /// + virtual ~CAccumulate(void); + + }; // class CAccumulate + + } // namespace func +} // namespace xmlioserver + +#endif //__XMLIO_CAccumulate__ diff --git a/src/functor/average.cpp b/src/functor/average.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4756c34f9bff49f3f8de31045724983351b274ca --- /dev/null +++ b/src/functor/average.cpp @@ -0,0 +1,88 @@ +#include "average.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Définitions ////////////////////// /// + + CAverage::CAverage(CArray& doutput) + : SuperClass(StdString("average"), doutput) + { /* Ne rien faire de plus */ } + + CAverage::CAverage(CArray& doutput, double missingValue) + : SuperClass(StdString("average"), doutput, missingValue) + { /* Ne rien faire de plus */ } + + CAverage::~CAverage(void) + { /* Ne rien faire de plus */ } + + //--------------------------------------------------------------- + + void CAverage::apply(const CArray& _dinput, + CArray& _doutput) + { + if (hasMissingValue) + { + if (nbcalls.numElements()==0) + { + nbcalls.resize(_dinput.numElements()) ; + nbcalls=0 ; + } + } + + if (this->nbcall == 1) + { + _doutput=_dinput ; + if (hasMissingValue) + { + int i, n =_dinput.numElements() ; + const double * in=_dinput.dataFirst() ; + int* nc=nbcalls.dataFirst() ; + for (i=0; inbcall; + this->nbcall = 0; + + } + } // namespace func +} // namespace xmlioserver diff --git a/src/functor/average.hpp b/src/functor/average.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d0f6dad434476327617359abf653b9b1028e5762 --- /dev/null +++ b/src/functor/average.hpp @@ -0,0 +1,41 @@ +#ifndef __XMLIO_CAverage__ +#define __XMLIO_CAverage__ + +/// xmlioserver headers /// +#include "functor.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Déclarations ////////////////////// /// + class CAverage : public CFunctor + { + /// Définition de type /// + typedef CFunctor SuperClass; + + public : + + /// Constructeurs /// + //CAverage(void); // Not implemented. + //CAverage(const CFunData & data); + CAverage(CArray& doutput); + CAverage(CArray& doutput, double missingValue); + //CAverage(const CAverage & average); // Not implemented. + //CAverage(const CAverage * const average); // Not implemented. + + /// Traitement /// + virtual void apply(const CArray& dinput, CArray& doutput); + virtual void final(void) ; + virtual ETimeType timeType(void) { return centered ; } + + /// Destructeur /// + virtual ~CAverage(void); + + }; // class CAverage + + } // namespace func +} // namespace xmlioserver + +#endif //__XMLIO_CAverage__ diff --git a/src/functor/functor_type.hpp b/src/functor/functor_type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..059cdebfe82befeb1a0e5591d5f9faafe6d4cc1f --- /dev/null +++ b/src/functor/functor_type.hpp @@ -0,0 +1,12 @@ +#ifndef __XMLIO_functor_type__ +#define __XMLIO_functor_type__ + +#include "average.hpp" +#include "accumulate.hpp" +#include "instant.hpp" +#include "once.hpp" +#include "maximum.hpp" +#include "minimum.hpp" + +#endif //__XMLIO_functor_type__ + diff --git a/src/functor/instant.cpp b/src/functor/instant.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8caefd45fb3acf7a5a62200eb98d0970c0784fe2 --- /dev/null +++ b/src/functor/instant.cpp @@ -0,0 +1,36 @@ +#include "instant.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Définitions ////////////////////// /// + + CInstant::CInstant(CArray& doutput) + : SuperClass(StdString("instant"), doutput) + { /* Ne rien faire de plus */ } + + CInstant::CInstant(CArray& doutput, double missingValue) + : SuperClass(StdString("instant"), doutput, missingValue) + { /* Ne rien faire de plus */ } + + CInstant::~CInstant(void) + { /* Ne rien faire de plus */ } + + //--------------------------------------------------------------- + + void CInstant::apply(const CArray& _dinput, + CArray& _doutput) + { +/* const double * it1 = _dinput->data(), + * end1 = _dinput->data() + _dinput->num_elements(); + double * it = _doutput->data(); + for (; it1 != end1; it1++, it++) *it = *it1;*/ + _doutput=_dinput ; + } + + //--------------------------------------------------------------- + + } // namespace func +} // namespace xmlioserver diff --git a/src/functor/instant.hpp b/src/functor/instant.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c026797ab8a5761c67fdbe808ed8ad292cfc5ebc --- /dev/null +++ b/src/functor/instant.hpp @@ -0,0 +1,40 @@ +#ifndef __XMLIO_CInstant__ +#define __XMLIO_CInstant__ + +/// xios headers /// +#include "functor.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Déclarations ////////////////////// /// + class CInstant : public CFunctor + { + /// Définition de type /// + typedef CFunctor SuperClass; + + public : + + /// Constructeurs /// + //CInstant(void); // Not implemented. + //CInstant(const CFunData & data); + CInstant(CArray& doutput); + CInstant(CArray& doutput, double missingValue); + //CInstant(const CInstant & instant); // Not implemented. + //CInstant(const CInstant * const instant); // Not implemented. + + /// Traitement /// + virtual void apply(const CArray& dinput, CArray& doutput); + virtual ETimeType timeType(void) { return instant ; } + + /// Destructeur /// + virtual ~CInstant(void); + + }; // class CInstant + + } // namespace func +} // namespace xmlioserver + +#endif //__XMLIO_CInstant__ diff --git a/src/functor/maximum.cpp b/src/functor/maximum.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53b40aa6beb7f27050196e34d10ed5504afc74c7 --- /dev/null +++ b/src/functor/maximum.cpp @@ -0,0 +1,52 @@ +#include "maximum.hpp" +#include "array_new.hpp" + + + +namespace xios +{ + namespace func + { + /// ////////////////////// Définitions ////////////////////// /// + + CMaximum::CMaximum(CArray& doutput) + : SuperClass(StdString("maximum"), doutput) + { /* Ne rien faire de plus */ } + + CMaximum::CMaximum(CArray& doutput, double missingValue) + : SuperClass(StdString("maximum"), doutput, missingValue) + { /* Ne rien faire de plus */ } + + CMaximum::~CMaximum(void) + { /* Ne rien faire de plus */ } + + //--------------------------------------------------------------- + + void CMaximum::apply(const CArray& _dinput, + CArray& _doutput) + { + const double * it1 = _dinput.dataFirst(), + * end1 = _dinput.dataFirst() + _dinput.numElements(); + double * it = _doutput.dataFirst(); + if (this->nbcall == 1) for (; it1 != end1; it1++, it++) *it = *it1; + else + { + if (hasMissingValue) + { + for (; it1 != end1; it1++, it++) + if (*it1 != missingValue) + { + if ( *it != missingValue) *it = std::max(*it1, *it); + else *it=*it1 ; + } + } + else for (; it1 != end1; it1++, it++) *it = std::max(*it1, *it); + } + + + } + + //--------------------------------------------------------------- + + } // namespace func +} // namespace xmlioserver diff --git a/src/functor/maximum.hpp b/src/functor/maximum.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ad2493c2179e4502051ff7f0a8cef30d7b87bed2 --- /dev/null +++ b/src/functor/maximum.hpp @@ -0,0 +1,40 @@ +#ifndef __XMLIO_CMaximum__ +#define __XMLIO_CMaximum__ + +/// xios headers /// +#include "functor.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Déclarations ////////////////////// /// + class CMaximum : public CFunctor + { + /// Définition de type /// + typedef CFunctor SuperClass; + + public : + + /// Constructeurs /// + //CMaximum(void); // Not implemented. + //CMaximum(const CFunData & data); + CMaximum(CArray& doutput); + CMaximum(CArray& doutput, double missingValue); + //CMaximum(const CMaximum & Maximum); // Not implemented. + //CMaximum(const CMaximum * const Maximum); // Not implemented. + + /// Traitement /// + virtual void apply(const CArray& dinput, CArray& doutput); + virtual ETimeType timeType(void) { return centered ; } + + /// Destructeur /// + virtual ~CMaximum(void); + + }; // class CMaximum + + } // namespace func +} // namespace xmlioserver + +#endif //__XMLIO_CMaximum__ diff --git a/src/functor/minimum.cpp b/src/functor/minimum.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d4e1a6a84a71634c0b4b78493776211b6837cde --- /dev/null +++ b/src/functor/minimum.cpp @@ -0,0 +1,51 @@ +#include "minimum.hpp" +#include "array_new.hpp" +#include + +namespace xios +{ + namespace func + { + /// ////////////////////// Définitions ////////////////////// /// + + CMinimum::CMinimum(CArray& doutput) + : SuperClass(StdString("minimum"), doutput) + { /* Ne rien faire de plus */ } + + CMinimum::CMinimum(CArray& doutput, double missingValue) + : SuperClass(StdString("minimum"), doutput, missingValue) + { /* Ne rien faire de plus */ } + + CMinimum::~CMinimum(void) + { /* Ne rien faire de plus */ } + + //--------------------------------------------------------------- + + void CMinimum::apply(const CArray& _dinput, + CArray& _doutput) + { + const double * it1 = _dinput.dataFirst(), + * end1 = _dinput.dataFirst() + _dinput.numElements(); + double * it = _doutput.dataFirst(); + + if (this->nbcall == 1) for (; it1 != end1; it1++, it++) *it = *it1; + else + { + if (hasMissingValue) + { + for (; it1 != end1; it1++, it++) + if (*it1!=missingValue) + { + if (*it != missingValue) *it = std::min(*it1, *it); + else *it=*it1 ; + } + } + else for (; it1 != end1; it1++, it++) *it = std::min(*it1, *it); + } + + } + + //--------------------------------------------------------------- + + } // namespace func +} // namespace xmlioserver diff --git a/src/functor/minimum.hpp b/src/functor/minimum.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fb980aef044cb597a75dde9840b7c57a85af5d05 --- /dev/null +++ b/src/functor/minimum.hpp @@ -0,0 +1,40 @@ +#ifndef __XMLIO_CMinimum__ +#define __XMLIO_CMinimum__ + +/// xmlioserver headers /// +#include "functor.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Déclarations ////////////////////// /// + class CMinimum : public CFunctor + { + /// Définition de type /// + typedef CFunctor SuperClass; + + public : + + /// Constructeurs /// + //CMinimum(void); // Not implemented. + //CMinimum(const CFunData & data); + CMinimum(CArray& doutput); + CMinimum(CArray& doutput, double missingValue); + //CMinimum(const CMinimum & Minimum); // Not implemented. + //CMinimum(const CMinimum * const Minimum); // Not implemented. + + /// Traitement /// + virtual void apply(const CArray& dinput, CArray& doutput); + virtual ETimeType timeType(void) { return centered ; } + + /// Destructeur /// + virtual ~CMinimum(void); + + }; // class CMinimum + + } // namespace func +} // namespace xmlioserver + +#endif //__XMLIO_CMinimum__ diff --git a/src/functor/once.cpp b/src/functor/once.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b80b1e990970662e3985cc690240c78df6062742 --- /dev/null +++ b/src/functor/once.cpp @@ -0,0 +1,37 @@ +#include "once.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Définitions ////////////////////// /// + + COnce::COnce(CArray& doutput) + : SuperClass(StdString("once"), doutput) + { /* Ne rien faire de plus */ } + + COnce::COnce(CArray& doutput, double missingValue) + : SuperClass(StdString("once"), doutput, missingValue) + { /* Ne rien faire de plus */ } + + COnce::~COnce(void) + { /* Ne rien faire de plus */ } + + //--------------------------------------------------------------- + + void COnce::apply(const CArray& _dinput, + CArray& _doutput) + { +/* const double * it1 = _dinput->data(), + * end1 = _dinput->data() + _dinput->num_elements(); + double * it = _doutput->data(); + for (; it1 != end1; it1++, it++) *it = *it1;*/ + _doutput=_dinput ; + } + + //--------------------------------------------------------------- + + } // namespace func +} // namespace xmlioserver + diff --git a/src/functor/once.hpp b/src/functor/once.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1eb1ccb714d8b22506d090feb0f2c898cc1ef21b --- /dev/null +++ b/src/functor/once.hpp @@ -0,0 +1,40 @@ +#ifndef __XMLIO_COnce__ +#define __XMLIO_COnce__ + +/// xios headers /// +#include "functor.hpp" +#include "array_new.hpp" + +namespace xios +{ + namespace func + { + /// ////////////////////// Déclarations ////////////////////// /// + class COnce : public CFunctor + { + /// Définition de type /// + typedef CFunctor SuperClass; + + public : + + /// Constructeurs /// + //COnce(void); // Not implemented. + COnce(CArray& doutput); + COnce(CArray& doutput, double missingValue); + //COnce(const COnce & once); // Not implemented. + //COnce(const COnce * const once); // Not implemented. + + /// Traitement /// + virtual void apply(const CArray& dinput, CArray& doutput); + virtual ETimeType timeType(void) { return once ; } + + /// Destructeur /// + virtual ~COnce(void); + + }; // class COnce + + } // namespace func +} // namespace xios + +#endif //__XMLIO_COnce__ + diff --git a/src/generate_fortran_interface.cpp b/src/generate_fortran_interface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ff298d750deeb745febfbc0772e5c64e68fdc97 --- /dev/null +++ b/src/generate_fortran_interface.cpp @@ -0,0 +1,196 @@ +#include "xmlioserver.hpp" +#include "generate_interface.hpp" +#include "indent.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "context.hpp" +#include "file.hpp" + +int main (int argc, char ** argv, char ** UNUSED (env)) +{ +// string path="./src/attr_interface/" ; + string path="./interface/" ; + + CContext* context=CContext::create("interface") ; + CAxis axis ; + CAxisGroup axisgroup ; + CField field; + CFieldGroup fieldgroup ; + CVariable variable; + CVariableGroup variablegroup ; + CDomain domain ; + CDomainGroup domaingroup ; + CGrid grid ; + CGridGroup gridgroup ; + + CFile afile; + CFileGroup filegroup; + + ostringstream oss ; + ofstream file; + + file.open((path+"axis_interface_attr.f90").c_str()); + axis.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icaxis_attr.cpp").c_str()); + axis.generateCInterface(file) ; + file.close(); + + file.open((path+"iaxis_attr.F90").c_str()); + axis.generateFortranInterface(file) ; + file.close(); + + file.open((path+"axisgroup_interface_attr.f90").c_str()); + axisgroup.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icaxisgroup_attr.cpp").c_str()); + axisgroup.generateCInterface(file) ; + file.close(); + + file.open((path+"iaxisgroup_attr.F90").c_str()); + axisgroup.generateFortranInterface(file) ; + file.close(); + + file.open((path+"domain_interface_attr.f90").c_str()); + domain.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icdomain_attr.cpp").c_str()); + domain.generateCInterface(file) ; + file.close(); + + file.open((path+"idomain_attr.F90").c_str()); + domain.generateFortranInterface(file) ; + file.close(); + + file.open((path+"domaingroup_interface_attr.f90").c_str()); + domaingroup.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icdomaingroup_attr.cpp").c_str()); + domaingroup.generateCInterface(file) ; + file.close(); + + file.open((path+"idomaingroup_attr.F90").c_str()); + domaingroup.generateFortranInterface(file) ; + file.close(); + + + file.open((path+"grid_interface_attr.f90").c_str()); + grid.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icgrid_attr.cpp").c_str()); + grid.generateCInterface(file) ; + file.close(); + + file.open((path+"igrid_attr.F90").c_str()); + grid.generateFortranInterface(file) ; + file.close(); + + file.open((path+"gridgroup_interface_attr.f90").c_str()); + gridgroup.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icgridgroup_attr.cpp").c_str()); + gridgroup.generateCInterface(file) ; + file.close(); + + file.open((path+"igridgroup_attr.F90").c_str()); + gridgroup.generateFortranInterface(file) ; + file.close(); + + + file.open((path+"field_interface_attr.f90").c_str()); + field.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icfield_attr.cpp").c_str()); + field.generateCInterface(file) ; + file.close(); + + file.open((path+"ifield_attr.F90").c_str()); + field.generateFortranInterface(file) ; + file.close(); + + file.open((path+"fieldgroup_interface_attr.f90").c_str()); + fieldgroup.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icfieldgroup_attr.cpp").c_str()); + fieldgroup.generateCInterface(file) ; + file.close(); + + file.open((path+"ifieldgroup_attr.F90").c_str()); + fieldgroup.generateFortranInterface(file) ; + file.close(); + + + + file.open((path+"variable_interface_attr.f90").c_str()); + variable.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icvariable_attr.cpp").c_str()); + variable.generateCInterface(file) ; + file.close(); + + file.open((path+"ivariable_attr.F90").c_str()); + variable.generateFortranInterface(file) ; + file.close(); + + file.open((path+"variablegroup_interface_attr.f90").c_str()); + variablegroup.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icvariablegroup_attr.cpp").c_str()); + variablegroup.generateCInterface(file) ; + file.close(); + + file.open((path+"ivariablegroup_attr.F90").c_str()); + variablegroup.generateFortranInterface(file) ; + file.close(); + + + + file.open((path+"file_interface_attr.f90").c_str()); + afile.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icfile_attr.cpp").c_str()); + afile.generateCInterface(file) ; + file.close(); + + file.open((path+"ifile_attr.F90").c_str()); + afile.generateFortranInterface(file) ; + file.close(); + + file.open((path+"filegroup_interface_attr.f90").c_str()); + filegroup.generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"icfilegroup_attr.cpp").c_str()); + filegroup.generateCInterface(file) ; + file.close(); + + file.open((path+"ifilegroup_attr.F90").c_str()); + filegroup.generateFortranInterface(file) ; + file.close(); + + + file.open((path+"context_interface_attr.f90").c_str()); + context->generateFortran2003Interface(file) ; + file.close(); + + file.open((path+"iccontext_attr.cpp").c_str()); + context->generateCInterface(file) ; + file.close(); + + file.open((path+"icontext_attr.F90").c_str()); + context->generateFortranInterface(file) ; + file.close(); + +} diff --git a/src/generate_interface.hpp b/src/generate_interface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..faafb6c02ba810092194760e8a2df9cb7d04958c --- /dev/null +++ b/src/generate_interface.hpp @@ -0,0 +1,72 @@ +#ifndef __XIOS_GENERATE_INTERFACE_HPP__ +#define __XIOS_GENERATE_INTERFACE_HPP__ + +#include "xmlioserver_spl.hpp" + +namespace xios +{ + class CInterface + { + public: + + template + static void AttributeCInterface(ostream& oss,const string& className,const string& name) ; + static void AttributeIsDefinedCInterface(ostream& oss, const string& className,const string& name); + + template + static void AttributeFortran2003Interface(ostream& oss,const string& className,const string& name) ; + static void AttributeIsDefinedFortran2003Interface(ostream& oss,const string& className,const string& name); + + template + static void AttributeFortranInterfaceDeclaration(ostream& oss,const string& className,const string& name) ; + + template + static void AttributeFortranInterfaceGetDeclaration(ostream& oss,const string& className,const string& name) ; + + static void AttributeFortranInterfaceIsDefinedDeclaration(ostream& oss,const string& className,const string& name) ; + + template + static void AttributeFortranInterfaceBody(ostream& oss,const string& className,const string& name) ; + + template + static void AttributeFortranInterfaceGetBody(ostream& oss,const string& className,const string& name) ; + + static void AttributeFortranInterfaceIsDefinedBody(ostream& oss,const string& className,const string& name) ; + + template + static string getStrFortranType(void) ; + + template + static string getStrFortranKind(void) ; + + template + static string getStrFortranKindC(void) ; + + template + static bool matchingTypeCFortran(void) ; + + + }; +/* + template<> string CInterface::getStrFortranType(void) {return string("INTEGER") ;} + template<> string CInterface::getStrFortranType(void) {return string("LOGICAL") ;} + template<> string CInterface::getStrFortranType(void) {return string("REAL") ;} + template<> string CInterface::getStrFortranType(void) {return string("REAL") ;} + + template<> string CInterface::getStrFortranKind(void) {return string("") ;} + template<> string CInterface::getStrFortranKind(void) {return string("") ;} + template<> string CInterface::getStrFortranKind(void) {return string("(KIND=8)") ;} + template<> string CInterface::getStrFortranKind(void) {return string("(KIND=4)") ;} + + template<> string CInterface::getStrFortranKindC(void) {return string("(KIND=C_INT)") ;} + template<> string CInterface::getStrFortranKindC(void) {return string("(KIND=C_BOOL)") ;} + template<> string CInterface::getStrFortranKindC(void) {return string("(KIND=C_DOUBLE)") ;} + template<> string CInterface::getStrFortranKindC(void) {return string("(KIND=C_FLOAT)") ;} + + template<> bool CInterface::matchingTypeCFortran(void) { return true ; } + template<> bool CInterface::matchingTypeCFortran(void) { return false ;} + template<> bool CInterface::matchingTypeCFortran(void) { return true; } + template<> bool CInterface::matchingTypeCFortran(void) { return true; } +*/ +} +#endif diff --git a/src/generate_interface_decl.cpp b/src/generate_interface_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2bc32e4fdac995ab16b31b0d8a73f9f26c20990d --- /dev/null +++ b/src/generate_interface_decl.cpp @@ -0,0 +1,21 @@ +#include "generate_interface_impl.hpp" + +namespace xios +{ + +#define macro(T) \ + template void CInterface::AttributeCInterface(ostream& oss,const string& className,const string& name) ; \ + template void CInterface::AttributeFortran2003Interface(ostream& oss,const string& className,const string& name) ; \ + template void CInterface::AttributeFortranInterfaceDeclaration(ostream& oss,const string& className,const string& name) ; \ + template void CInterface::AttributeFortranInterfaceGetDeclaration(ostream& oss,const string& className,const string& name) ; \ + template void CInterface::AttributeFortranInterfaceBody(ostream& oss,const string& className,const string& name) ; \ + template void CInterface::AttributeFortranInterfaceGetBody(ostream& oss,const string& className,const string& name) ; \ + template string CInterface::getStrFortranType(void) ; \ + template string CInterface::getStrFortranKind(void) ; \ + template string CInterface::getStrFortranKindC(void) ; \ + template bool CInterface::matchingTypeCFortran(void) ; + + macro(bool) + macro(int) + macro(double) +} diff --git a/src/generate_interface_impl.hpp b/src/generate_interface_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..97a45b2ec8273d240a458fbc66a1611dfe4d6c43 --- /dev/null +++ b/src/generate_interface_impl.hpp @@ -0,0 +1,955 @@ +#ifndef __XIOS_GENERATE_INTERFACE_IMPL_HPP__ +#define __XIOS_GENERATE_INTERFACE_IMPL_HPP__ + +#include "xmlioserver_spl.hpp" +#include "generate_interface.hpp" +#include "type_util.hpp" +#include "indent.hpp" +#include "enum.hpp" +#include "array_new.hpp" + +namespace xios +{ + template<> string CInterface::getStrFortranType(void) {return string("INTEGER") ;} + template<> string CInterface::getStrFortranType(void) {return string("LOGICAL") ;} + template<> string CInterface::getStrFortranType(void) {return string("REAL") ;} + template<> string CInterface::getStrFortranType(void) {return string("REAL") ;} + + template<> string CInterface::getStrFortranKind(void) {return string("") ;} + template<> string CInterface::getStrFortranKind(void) {return string("") ;} + template<> string CInterface::getStrFortranKind(void) {return string("(KIND=8)") ;} + template<> string CInterface::getStrFortranKind(void) {return string("(KIND=4)") ;} + + template<> string CInterface::getStrFortranKindC(void) {return string("(KIND=C_INT)") ;} + template<> string CInterface::getStrFortranKindC(void) {return string("(KIND=C_BOOL)") ;} + template<> string CInterface::getStrFortranKindC(void) {return string("(KIND=C_DOUBLE)") ;} + template<> string CInterface::getStrFortranKindC(void) {return string("(KIND=C_FLOAT)") ;} + + template<> bool CInterface::matchingTypeCFortran(void) { return true ; } + template<> bool CInterface::matchingTypeCFortran(void) { return false ;} + template<> bool CInterface::matchingTypeCFortran(void) { return true; } + template<> bool CInterface::matchingTypeCFortran(void) { return true; } + + +// ///////////////////////////////////////////////// +// // C Interface // +// ///////////////////////////////////////////////// + + + void CInterface::AttributeIsDefinedCInterface(ostream& oss, const string& className,const string& name) + { + oss<<"bool cxios_is_defined_"<"< + void CInterface::AttributeCInterface(ostream& oss, const string& className,const string& name) + { + string typeName=getStrType() ; + + oss<<"void cxios_set_"<"<sendAttributToServer("<"<"< + void CInterface::AttributeCInterface(ostream& oss, const string& className,const string& name) + { + oss<<"void cxios_set_"<"<sendAttributToServer("<"<"< + void CInterface::AttributeCInterface(ostream& oss, const string& className,const string& name) + { + oss<<"void cxios_set_"<"<sendAttributToServer("<"<"<mask.getValue(), mask, extent1, extent2)) +// ERROR("cxios_get_domain_mask(XDomainPtr domain_hdl, bool * mask, int extent1, int extent2)",<<"Output array size is not conform to array size attribut") ; + +/* +#define macro(T) \ + template <>\ + void CInterface::AttributeCInterface(ostream& oss, const string& className,const string& name)\ + {\ + string typeName=getStrType() ;\ +\ + oss<<"void cxios_set_"<(boost::extents[extent1]));"<num_elements()]), array_tmp->data());"<"<sendAttributToServer("<"<"< \ + void CInterface::AttributeCInterface(ostream& oss, const string& className,const string& name)\ + {\ + string typeName=getStrType() ;\ +\ + oss<<"void cxios_set_"<(boost::extents[extent1][extent2]));"<num_elements()]), array_tmp->data());"<"<sendAttributToServer("<"<"<\ + void CInterface::AttributeCInterface(ostream& oss, const string& className,const string& name)\ + {\ + string typeName=getStrType() ;\ +\ + oss<<"void cxios_set_"<(boost::extents[extent1][extent2][extent3]));"<num_elements()]), array_tmp->data());"<"<sendAttributToServer("<"<"< + void CInterface::AttributeFortran2003Interface(ostream& oss,const string& className,const string& name) + { + string fortranType=getStrFortranType() ; + string fortranKindC=getStrFortranKindC() ; + + oss<<"SUBROUTINE cxios_set_"< + void CInterface::AttributeFortran2003Interface(ostream& oss,const string& className,const string& name) + { + + oss<<"SUBROUTINE cxios_set_"<\ + void CInterface::AttributeFortran2003Interface(ostream& oss,const string& className,const string& name) \ + { \ + string fortranType=getStrFortranType() ; \ + string fortranKindC=getStrFortranKindC() ; \ + \ + oss<<"SUBROUTINE cxios_set_"< \ + void CInterface::AttributeFortran2003Interface(ostream& oss,const string& className,const string& name) \ + { \ + string fortranType=getStrFortranType() ; \ + string fortranKindC=getStrFortranKindC() ; \ + \ + oss<<"SUBROUTINE cxios_set_"< \ + void CInterface::AttributeFortran2003Interface(ostream& oss,const string& className,const string& name) \ + { \ + string fortranType=getStrFortranType() ; \ + string fortranKindC=getStrFortranKindC() ; \ + \ + oss<<"SUBROUTINE cxios_set_"< + void CInterface::AttributeFortranInterfaceDeclaration(ostream& oss,const string& className,const string& name) + { + oss<()<<" "<< getStrFortranKind() <<" , OPTIONAL, INTENT(IN) :: "<()) oss<()<<" "<()<<" :: "< + void CInterface::AttributeFortranInterfaceGetDeclaration(ostream& oss,const string& className,const string& name) + { + oss<()<<" "<< getStrFortranKind() <<" , OPTIONAL, INTENT(OUT) :: "<()) oss<()<<" "<()<<" :: "< + void CInterface::AttributeFortranInterfaceDeclaration(ostream& oss,const string& className,const string& name) + { + oss<<"CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: "< + void CInterface::AttributeFortranInterfaceGetDeclaration(ostream& oss,const string& className,const string& name) + { + oss<<"CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: "< \ + void CInterface::AttributeFortranInterfaceDeclaration(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(IN) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceGetDeclaration(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(OUT) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceDeclaration(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(IN) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceGetDeclaration(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(OUT) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceDeclaration(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(IN) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceGetDeclaration(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(OUT) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< + void CInterface::AttributeFortranInterfaceBody(ostream& oss,const string& className,const string& name) + { + string name_tmp=name+"__tmp" ; + + oss<<"IF (PRESENT("<()) + { + oss<<" "< + void CInterface::AttributeFortranInterfaceGetBody(ostream& oss,const string& className,const string& name) + { + string name_tmp=name+"__tmp" ; + + oss<<"IF (PRESENT("<()) + { + oss<<" CALL cxios_get_"< + void CInterface::AttributeFortranInterfaceBody(ostream& oss,const string& className,const string& name) + { + oss<<"IF (PRESENT("< + void CInterface::AttributeFortranInterfaceGetBody(ostream& oss,const string& className,const string& name) + { + oss<<"IF (PRESENT("< \ + void CInterface::AttributeFortranInterfaceBody< ARRAY(T,1) >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceBody< ARRAY(T,2) >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceBody< ARRAY(T,3) >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceGetBody< ARRAY(T,1) >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceGetBody< ARRAY(T,2) >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceGetBody< ARRAY(T,3) >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("<\ + void CInterface::AttributeCInterface >(ostream& oss, const string& className,const string& name)\ + {\ + string typeName=getStrType() ;\ +\ + oss<<"void cxios_set_"< tmp("<"<sendAttributToServer("<"< tmp("<"< \ + void CInterface::AttributeCInterface >(ostream& oss, const string& className,const string& name)\ + {\ + string typeName=getStrType() ;\ +\ + oss<<"void cxios_set_"< tmp("<"<sendAttributToServer("<"< tmp("<"<\ + void CInterface::AttributeCInterface >(ostream& oss, const string& className,const string& name)\ + {\ + string typeName=getStrType() ;\ +\ + oss<<"void cxios_set_"< tmp("<"<sendAttributToServer("<"< tmp("<"<\ + void CInterface::AttributeFortran2003Interface >(ostream& oss,const string& className,const string& name) \ + { \ + string fortranType=getStrFortranType() ; \ + string fortranKindC=getStrFortranKindC() ; \ + \ + oss<<"SUBROUTINE cxios_set_"< \ + void CInterface::AttributeFortran2003Interface >(ostream& oss,const string& className,const string& name) \ + { \ + string fortranType=getStrFortranType() ; \ + string fortranKindC=getStrFortranKindC() ; \ + \ + oss<<"SUBROUTINE cxios_set_"< \ + void CInterface::AttributeFortran2003Interface >(ostream& oss,const string& className,const string& name) \ + { \ + string fortranType=getStrFortranType() ; \ + string fortranKindC=getStrFortranKindC() ; \ + \ + oss<<"SUBROUTINE cxios_set_"< \ + void CInterface::AttributeFortranInterfaceDeclaration >(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(IN) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceGetDeclaration >(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(OUT) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceDeclaration >(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(IN) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceGetDeclaration >(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(OUT) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceDeclaration >(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(IN) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceGetDeclaration >(ostream& oss,const string& className,const string& name) \ + { \ + oss<()<<" "<() <<" , OPTIONAL, INTENT(OUT) :: "<()) oss<()<<" "<() <<" , ALLOCATABLE :: "< \ + void CInterface::AttributeFortranInterfaceBody< CArray >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceBody< CArray >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceBody< CArray >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceGetBody< CArray >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceGetBody< CArray >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< \ + void CInterface::AttributeFortranInterfaceGetBody< CArray >(ostream& oss,const string& className,const string& name) \ + { \ + string name_tmp=name+"__tmp" ; \ + \ + oss<<"IF (PRESENT("<()) \ + { \ + oss<<" ALLOCATE("< + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "object_factory.hpp" +#include "group_template.hpp" +#include "xml_parser.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CGroupFactory + { + public : + + /// Mutateurs /// + static void SetCurrentContextId(const StdString & context); + + template + static void AddGroup(boost::shared_ptr pgroup, + boost::shared_ptr cgroup); + + template + static void AddChild(boost::shared_ptr group, + boost::shared_ptr child); + + /// Accesseurs /// + static StdString & GetCurrentContextId(void); + + template + static boost::shared_ptr + GetGroup(boost::shared_ptr group, const StdString & id); + + template + static boost::shared_ptr + GetChild(boost::shared_ptr group, const StdString & id); + + template + static int GetGroupNum(boost::shared_ptr group); + template + static int GetGroupIdNum(boost::shared_ptr group); + template + static int GetChildNum(boost::shared_ptr group); + template + static int GetChildIdNum(boost::shared_ptr group); + + /// Tests /// + template + static bool HasGroup(boost::shared_ptr group, const StdString & id); + + template + static bool HasChild(boost::shared_ptr group, const StdString & id); + + /// Instanciateur /// + template + static boost::shared_ptr + CreateGroup(boost::shared_ptr group, const StdString & id = StdString("")); + + template + static boost::shared_ptr + CreateChild(boost::shared_ptr group, const StdString & id = StdString("")); + + private : + + /// Propriétés statiques /// + static StdString CurrContext; + + }; // class CGroupFactory +} // namespace xios + +//#include "group_factory_impl.hpp" +//#include "group_parser.hpp" + +#endif // __XMLIO_CGroupFactory__ diff --git a/src/group_factory_decl.cpp b/src/group_factory_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1775560490153b93b6aaf20a6f79150eee80390 --- /dev/null +++ b/src/group_factory_decl.cpp @@ -0,0 +1,27 @@ +#include "group_factory_impl.hpp" +#include "node_type.hpp" + +namespace xios +{ +# define macro(U) \ + template void CGroupFactory::AddGroup(shared_ptr pgroup,shared_ptr cgroup); \ + template void CGroupFactory::AddChild(shared_ptr group, shared_ptr child); \ + template shared_ptr CGroupFactory::GetGroup(shared_ptr group, const StdString & id); \ + template shared_ptr CGroupFactory::GetChild(shared_ptr group, const StdString & id); \ + template int CGroupFactory::GetGroupNum(shared_ptr group); \ + template int CGroupFactory::GetGroupIdNum(shared_ptr group); \ + template int CGroupFactory::GetChildNum(shared_ptr group); \ + template int CGroupFactory::GetChildIdNum(boost::shared_ptr group); \ + template bool CGroupFactory::HasGroup(shared_ptr group, const StdString & id); \ + template bool CGroupFactory::HasChild(boost::shared_ptr group, const StdString & id); \ + template shared_ptr CGroupFactory::CreateGroup(shared_ptr group, const StdString & id ); \ + template shared_ptr CGroupFactory::CreateChild(shared_ptr group, const StdString & id); + + macro(CFieldGroup) + macro(CFileGroup) + macro(CGridGroup) + macro(CAxisGroup) + macro(CDomainGroup) + macro(CContextGroup) + macro(CVariableGroup) +} diff --git a/src/group_factory_impl.hpp b/src/group_factory_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0c8efc999e5f92cbee7e1359ba588da65369ef1d --- /dev/null +++ b/src/group_factory_impl.hpp @@ -0,0 +1,140 @@ +#ifndef __XMLIO_CGroupFactory_impl__ +#define __XMLIO_CGroupFactory_impl__ + +#include "group_factory.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + template + void CGroupFactory::AddGroup(boost::shared_ptr pgroup, + boost::shared_ptr cgroup) + { + if (cgroup.get() == NULL || pgroup.get() == NULL ) + ERROR("CGroupFactory::AddGroup(boost::shared_ptr pgroup, boost::shared_ptr cgroup)", + << " pgroup or cgroup NULL !"); + if (!cgroup->hasId()) + pgroup->groupList.insert(pgroup->groupList.end(), cgroup.get()); + else + { + pgroup->groupList.insert(pgroup->groupList.end(), cgroup.get()); + pgroup->groupMap.insert(std::make_pair(cgroup->getId(), cgroup.get())); + } + } + + template + void CGroupFactory::AddChild(boost::shared_ptr group, + boost::shared_ptr child) + { + if (group.get() == NULL || child.get() == NULL ) + ERROR("CGroupFactory::AddGroup(boost::shared_ptr pgroup, boost::shared_ptr cgroup)", + << " pgroup or cgroup NULL !"); + if (!child->hasId()) + group->childList.insert(group->childList.end(), child.get()); + else + { + group->childList.insert(group->childList.end(), child.get()); + group->childMap.insert(std::make_pair(child->getId(), child.get())); + } + } + + template + boost::shared_ptr + CGroupFactory::CreateGroup(boost::shared_ptr group, const StdString & id) + { + CObjectFactory::SetCurrentContextId + (CGroupFactory::GetCurrentContextId()); + if (id.size() == 0) + { + boost::shared_ptr value = CObjectFactory::CreateObject(CObjectFactory::GenUId()); + group->groupList.insert(group->groupList.end(), value.get()); + group->groupMap.insert(std::make_pair(value->getId(), value.get())); + return (value); + } + else if (CGroupFactory::HasGroup(group, id)) + return (CGroupFactory::GetGroup(group, id)); + else + { + boost::shared_ptr value = CObjectFactory::CreateObject(id); + group->groupList.insert(group->groupList.end(), value.get()); + group->groupMap.insert(std::make_pair(id, value.get())); + return (value); + } + } + + template + boost::shared_ptr + CGroupFactory::CreateChild(boost::shared_ptr group, const StdString & id) + { + CObjectFactory::SetCurrentContextId + (CGroupFactory::GetCurrentContextId()); + if (id.size() == 0) + { + boost::shared_ptr value = + CObjectFactory::CreateObject(); + group->childList.insert(group->childList.end(), value.get()); + group->childMap.insert(std::make_pair(value->getId(), value.get())); + return (value); + } + else if (CGroupFactory::HasChild(group, id)) + return (CGroupFactory::GetChild(group, id)); + else + { + boost::shared_ptr value = + CObjectFactory::CreateObject(id); + group->childList.insert(group->childList.end(), value.get()); + group->childMap.insert(std::make_pair(id, value.get())); + return (value); + } + } + + template + bool CGroupFactory::HasGroup(boost::shared_ptr group, const StdString & id) + { return (group->groupMap.find(id) != group->groupMap.end()); } + + template + bool CGroupFactory::HasChild(boost::shared_ptr group, const StdString & id) + { return (group->childMap.find(id) != group->childMap.end()); } + + template + int CGroupFactory::GetGroupNum(boost::shared_ptr group) + { return (group->groupList.size()); } + + template + int CGroupFactory::GetGroupIdNum(boost::shared_ptr group) + { return (group->groupMap.size()); } + + template + int CGroupFactory::GetChildNum(boost::shared_ptr group) + { return (group->childList.size()); } + + template + int CGroupFactory::GetChildIdNum(boost::shared_ptr group) + { return (group->childMap.size()); } + + template + boost::shared_ptr + CGroupFactory::GetGroup(boost::shared_ptr group, const StdString & id) + { + if (!CGroupFactory::HasGroup(group, id)) + ERROR("CGroupFactory::GetGroup(boost::shared_ptr group, const StdString & id)", + << "[ id = " << id << ", U = " << U::GetName() << " ] " + << " group is not referenced !"); + return (group->groupMap[id]->getShared()); + } + + template + boost::shared_ptr + CGroupFactory::GetChild(boost::shared_ptr group, const StdString & id) + { + if (!CGroupFactory::HasChild(group, id)) + ERROR("CGroupFactory::GetChild(boost::shared_ptr group, const StdString & id)", + << "[ id = " << id << ", U = " << U::GetName() << " ] " + << " child is not referenced !"); + return (group->childMap[id]->getShared()); + } + +} // namespace xios + +#endif // __XMLIO_CGroupFactory_impl__ diff --git a/src/group_parser.hpp b/src/group_parser.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7ebb6cef921abc3c9da57b73affbd1c950fbfecf --- /dev/null +++ b/src/group_parser.hpp @@ -0,0 +1,127 @@ +#ifndef __XMLIO_GroupParser__ +#define __XMLIO_GroupParser__ + +/// boost headers /// +#include + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + template + void CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr) + { + + StdString name = node.getElementName(); + xml::THashAttributes attributes = node.getAttributes(); + if (withAttr) + { + CGroupTemplate::SuperClass::parse(node); + if (attributes.end() != attributes.find("src")) + { + StdIFStream ifs ( attributes["src"].c_str() , StdIFStream::in ); + if ( (ifs.rdstate() & std::ifstream::failbit ) != 0 ) + ERROR(" void CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr)", + < file" ); + if (!ifs.good()) + ERROR("CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr)", + << "[ filename = " << attributes["src"] << " ] Bad xml stream !"); + xml::CXMLParser::ParseInclude(ifs, attributes["src"].c_str(), *this); + } + } + + // PARSING POUR GESTION DES ENFANTS + V* group_ptr = (this->hasId()) + ? V::get(this->getId()) + : boost::polymorphic_downcast(this); + + if (!(node.goToChildElement())) + { + if (this->hasId()) + { + DEBUG(<< "L'objet de type \'" << V::GetName() + << "\' nommé \'" << this->getId() + << "\' ne contient pas d\'enfant !"); + } + } + else + { + do { // Parcours pour traitement. + + StdString name = node.getElementName(); + attributes.clear(); + attributes = node.getAttributes(); + + if (name.compare(V::GetName()) == 0) + { + if (attributes.end() == attributes.find("id")) + CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node); + else + CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node); + continue; + } + + if (name.compare(U::GetName()) == 0) + { + if (attributes.end() == attributes.find("id")) + CGroupFactory::CreateChild(group_ptr->getShared())->parse(node); + else + CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node); + continue; + } + + DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId() + << "\', un objet de type \'" << V::GetName() + << "\' ne peut contenir qu'un objet de type \'" << V::GetName() + << "\' ou de type \'" << U::GetName() + << "\' (reçu : " << name << ") !"); + + } while (node.goToNextElement()); + node.goToParentElement(); // Retour au parent + } + } + + /// ////////////////////// Définitions ////////////////////// /// + template + void CGroupTemplate::parseChild(xml::CXMLNode & node) + { + + + // PARSING POUR GESTION DES ENFANTS + V* group_ptr = (this->hasId()) + ? V::get(this->getId()) + : boost::polymorphic_downcast(this); + + StdString name = node.getElementName(); + attributes.clear(); + attributes = node.getAttributes(); + + if (name.compare(V::GetName()) == 0) + { + if (attributes.end() == attributes.find("id")) + CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node); + return ; + else + CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node); + continue; + } + + if (name.compare(U::GetName()) == 0) + { + if (attributes.end() == attributes.find("id")) + CGroupFactory::CreateChild(group_ptr->getShared())->parse(node); + return ; + else + CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node); + continue; + } + + DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId() + << "\', un objet de type \'" << V::GetName() + << "\' ne peut contenir qu'un objet de type \'" << V::GetName() + << "\' ou de type \'" << U::GetName() + << "\' (reçu : " << name << ") !"); + + } +} // namespace xios + +#endif // __XMLIO_GroupParser__ diff --git a/src/group_template.hpp b/src/group_template.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dd24e0875860f97d9f3f1a48667c13e8d609c4ab --- /dev/null +++ b/src/group_template.hpp @@ -0,0 +1,106 @@ +#ifndef __XMLIO_CGroupTemplate__ +#define __XMLIO_CGroupTemplate__ + +#include "xmlioserver_spl.hpp" +#include "declare_attribute.hpp" +#include "event_server.hpp" +#include "object_template.hpp" + +namespace xios +{ + + /// ////////////////////// Déclarations ////////////////////// /// + template + class CGroupTemplate + : public CObjectTemplate, public virtual W + { + /// Friend /// + friend class CGroupFactory; + + /// Typedef /// + typedef U Child; + typedef V Derived, Group; + typedef W SuperClassAttribute; + typedef CObjectTemplate SuperClass; + + public : + + enum EEventId + { + EVENT_ID_CREATE_CHILD=200, EVENT_ID_CREATE_CHILD_GROUP + } ; + + /// Spécifique /// + DECLARE_ATTRIBUTE(StdString, group_ref) + + /// Accesseurs /// + const xios_map& getGroupMap(void) const; + const vector& getChildList(void) const; + + void getAllChildren(vector & allc) const; + vector getAllChildren(void) const; + + /// Autres /// + virtual StdString toString(void) const; + virtual void fromString(const StdString & str); + +// virtual void toBinary (StdOStream & os) const; +// virtual void fromBinary(StdIStream & is); + + virtual void parse(xml::CXMLNode & node); + virtual void parse(xml::CXMLNode & node, bool withAttr); + virtual void parseChild(xml::CXMLNode & node); + + /// Test /// + virtual bool hasChild(void) const; + + /// Accesseurs statiques /// + static StdString GetName(void); + static StdString GetDefName(void); + + /// Traitements /// + virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0); + void solveRefInheritance(void); +// static bool has(const string & id); +// static boost::shared_ptr get(const string& id) ; +// static boost::shared_ptr create(const string& id=string("")) ; + U* createChild(const string& id="") ; + + void addChild(U* child) ; + V* createChildGroup(const string& id="") ; + void addChildGroup(V* childGroup) ; + static bool dispatchEvent(CEventServer& event) ; + void sendCreateChild(const string& id="") ; + void sendCreateChildGroup(const string& id="") ; + static void recvCreateChild(CEventServer& event) ; + void recvCreateChild(CBufferIn& buffer) ; + static void recvCreateChildGroup(CEventServer& event) ; + void recvCreateChildGroup(CBufferIn& buffer) ; + + /// Destructeur /// + virtual ~CGroupTemplate(void); + + protected : + + /// Constructeurs /// + CGroupTemplate(void); + CGroupTemplate(const StdString & id); + CGroupTemplate(const CGroupTemplate & group, + bool withAttrList = true, bool withId = true); // Not implemented yet. + CGroupTemplate(const CGroupTemplate * const group); // Not implemented yet. + + private : + + /// Propriétés /// + xios_map childMap; + vector childList; + + xios_map groupMap; + vector groupList; + + }; // class CGroupTemplate +} // namespace xios + +//#include "group_template_impl.hpp" + +#endif // __XMLIO_CGroupTemplate__ diff --git a/src/group_template_decl.cpp b/src/group_template_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b44df6779cd27b2a02bc161c05994b1563412d9 --- /dev/null +++ b/src/group_template_decl.cpp @@ -0,0 +1,18 @@ +#include "group_template_impl.hpp" +#include "node_type.hpp" + +namespace xios +{ +# define macro(T) \ + template class CGroupTemplate ; + + macro(Context) + macro(Field) + macro(File) + macro(Domain) + macro(Grid) + macro(Axis) + macro(Variable) + + +} diff --git a/src/group_template_impl.hpp b/src/group_template_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..91b8e6fa40a159e53d33c2ee11b4645b39b1da77 --- /dev/null +++ b/src/group_template_impl.hpp @@ -0,0 +1,594 @@ +#ifndef __XMLIO_CGroupTemplate_impl__ +#define __XMLIO_CGroupTemplate_impl__ + +#include "xmlioserver_spl.hpp" +#include "event_server.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "context.hpp" +#include "event_client.hpp" +#include "context_client.hpp" +#include "message.hpp" +#include "type.hpp" +#include "type_util.hpp" + + +namespace xios +{ + + /// ////////////////////// Définitions ////////////////////// /// + + template + CGroupTemplate::CGroupTemplate(void) + : CObjectTemplate() //, V() + , childMap(), childList() + , groupMap(), groupList() + { /* Ne rien faire de plus */ } + + template + CGroupTemplate::CGroupTemplate(const StdString & id) + : CObjectTemplate(id) //, V() + , childMap(), childList() + , groupMap(), groupList() + { /* Ne rien faire de plus */ } + + template + CGroupTemplate::~CGroupTemplate(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- +/* + template + void CGroupTemplate::toBinary(StdOStream & os) const + { + SuperClass::toBinary(os); + + const StdSize grpnb = this->groupList.size(); + const StdSize chdnb = this->childList.size(); + ENodeType cenum = U::GetType(); + ENodeType genum = V::GetType(); + + os.write (reinterpret_cast(&grpnb) , sizeof(StdSize)); + os.write (reinterpret_cast(&chdnb) , sizeof(StdSize)); + + typename std::vector::const_iterator + itg = this->groupList.begin(), endg = this->groupList.end(); + typename std::vector::const_iterator + itc = this->childList.begin(), endc = this->childList.end(); + + for (; itg != endg; itg++) + { + V* group = *itg; + bool hid = group->hasId(); + + os.write (reinterpret_cast(&genum), sizeof(ENodeType)); + os.write (reinterpret_cast(&hid), sizeof(bool)); + + if (hid) + { + const StdString & id = group->getId(); + const StdSize size = id.size(); + + os.write (reinterpret_cast(&size), sizeof(StdSize)); + os.write (id.data(), size * sizeof(char)); + } + group->toBinary(os); + } + + for (; itc != endc; itc++) + { + U* child = *itc; + bool hid = child->hasId(); + + os.write (reinterpret_cast(&cenum), sizeof(ENodeType)); + os.write (reinterpret_cast(&hid), sizeof(bool)); + + if (hid) + { + const StdString & id = child->getId(); + const StdSize size = id.size(); + + os.write (reinterpret_cast(&size), sizeof(StdSize)); + os.write (id.data(), size * sizeof(char)); + } + child->toBinary(os); + } + + } + + template + void CGroupTemplate::fromBinary(StdIStream & is) + { + SuperClass::fromBinary(is); + + V* group_ptr = (this->hasId()) + ? V::get(this->getId()) + : V::get((V*)this); + + StdSize grpnb = 0; + StdSize chdnb = 0; + ENodeType renum = Unknown; + + is.read (reinterpret_cast(&grpnb), sizeof(StdSize)); + is.read (reinterpret_cast(&chdnb), sizeof(StdSize)); + + for (StdSize i = 0; i < grpnb; i++) + { + bool hid = false; + is.read (reinterpret_cast(&renum), sizeof(ENodeType)); + is.read (reinterpret_cast(&hid), sizeof(bool)); + + if (renum != V::GetType()) + ERROR("CGroupTemplate::fromBinary(StdIStream & is)", + << "[ renum = " << renum << "] Bad type !"); + + if (hid) + { + StdSize size = 0; + is.read (reinterpret_cast(&size), sizeof(StdSize)); + StdString id(size, ' '); + is.read (const_cast(id.data()), size * sizeof(char)); + CGroupFactory::CreateGroup(group_ptr->getShared(), id)->fromBinary(is); + } + else + { + CGroupFactory::CreateGroup(group_ptr->getShared())->fromBinary(is); + } + } + + for (StdSize j = 0; j < chdnb; j++) + { + bool hid = false; + is.read (reinterpret_cast(&renum), sizeof(ENodeType)); + is.read (reinterpret_cast(&hid), sizeof(bool)); + + if (renum != U::GetType()) + ERROR("CGroupTemplate::fromBinary(StdIStream & is)", + << "[ renum = " << renum << "] Bad type !"); + + if (hid) + { + StdSize size = 0; + is.read (reinterpret_cast(&size), sizeof(StdSize)); + StdString id(size, ' '); + is.read (const_cast(id.data()), size * sizeof(char)); + CGroupFactory::CreateChild(group_ptr->getShared(), id)->fromBinary(is); + } + else + { + CGroupFactory::CreateChild(group_ptr->getShared())->fromBinary(is); + } + } + } +*/ + //-------------------------------------------------------------- + + template + StdString CGroupTemplate::toString(void) const + { + StdOStringStream oss; + StdString name = (this->getId().compare(V::GetDefName()) != 0) + ? V::GetName() : V::GetDefName(); + + oss << "<" << name << " "; + if (this->hasId() && (this->getId().compare(V::GetDefName()) != 0)) + oss << " id=\"" << this->getId() << "\" "; + + if (this->hasChild()) + { + oss << SuperClassAttribute::toString() << ">" << std::endl; + + typename std::vector::const_iterator + itg = this->groupList.begin(), endg = this->groupList.end(); + typename std::vector::const_iterator + itc = this->childList.begin(), endc = this->childList.end(); + + for (; itg != endg; itg++) + { + V* group = *itg; + oss << *group << std::endl; + } + + for (; itc != endc; itc++) + { + U* child = *itc; + oss << *child << std::endl; + } + + oss << ""; + } + else + { + oss << SuperClassAttribute::toString() << "/>"; + } + return (oss.str()); + } + + template + void CGroupTemplate::fromString(const StdString & str) + { + ERROR("CGroupTemplate::toString(void)", + << "[ str = " << str << "] Not implemented yet !"); + } + + //--------------------------------------------------------------- + + template + StdString CGroupTemplate::GetName(void) + { + return (U::GetName().append("_group")); + } + + template + StdString CGroupTemplate::GetDefName(void) + { + return (U::GetName().append("_definition")); + } + + //--------------------------------------------------------------- + + template + const std::vector& + CGroupTemplate::getChildList(void) const + { + return (this->childList); + } + + //--------------------------------------------------------------- + + template + const xios_map& + CGroupTemplate::getGroupMap(void) const + { + return (this->groupMap); + } + + //--------------------------------------------------------------- + + template + bool CGroupTemplate::hasChild(void) const + { + return ((groupList.size() + childList.size()) > 0); + } + + //--------------------------------------------------------------- + + template + void CGroupTemplate::parse(xml::CXMLNode & node) + { + this->parse(node, true); + } + + //--------------------------------------------------------------- + + template + void CGroupTemplate::solveDescInheritance(bool apply, const CAttributeMap * const parent) + { + if (parent != NULL) + SuperClassAttribute::setAttributes(parent, apply); + + typename std::vector::const_iterator + itc = this->childList.begin(), endc = this->childList.end(); + typename std::vector::const_iterator + itg = this->groupList.begin(), endg = this->groupList.end(); + + for (; itc != endc; itc++) + { + U* child = *itc; + child->solveDescInheritance(apply,this); + } + + for (; itg != endg; itg++) + { + V* group = *itg; + if (apply) group->solveRefInheritance(); + group->solveDescInheritance(apply,this); + } + } + + //--------------------------------------------------------------- + + template + void CGroupTemplate::getAllChildren(std::vector& allc) const + { + allc.insert (allc.end(), childList.begin(), childList.end()); + typename std::vector::const_iterator + itg = this->groupList.begin(), endg = this->groupList.end(); + + for (; itg != endg; itg++) + { + V* group = *itg; + group->getAllChildren(allc); + } + } + + //--------------------------------------------------------------- + + template + std::vector CGroupTemplate::getAllChildren(void) const + { + std::vector allc; + this->getAllChildren(allc); + return (allc); + } + + //--------------------------------------------------------------- + + template + void CGroupTemplate::solveRefInheritance(void) + { /* Ne rien faire de plus */ } + +// template +// bool CGroupTemplate::has(const string& id) +// { +// return CObjectFactory::HasObject(id) ; +// } + +// template +// boost::shared_ptr CGroupTemplate::get(const string& id) +// { +// return CObjectFactory::GetObject(id) ; +// } + +// template +// boost::shared_ptr CGroupTemplate::get() +// { +// return CObjectFactory::GetObject(this) ; +// } + +// template +// boost::shared_ptr CGroupTemplate::create(const string& id) +// { +// return CObjectFactory::CreateObject(id) ; +// } + ///-------------------------------------------------------------- + + + template + U* CGroupTemplate::createChild(const string& id) + { + return CGroupFactory::CreateChild(this->getShared(), id).get() ; + } + + template + void CGroupTemplate::addChild(U* child) + { + return CGroupFactory::AddChild(this->getShared(),child->getShared()) ; + } + + template + V* CGroupTemplate::createChildGroup(const string& id) + { + return CGroupFactory::CreateGroup(this->getShared(), id).get() ; + } + + template + void CGroupTemplate::addChildGroup(V* childGroup) + { + return CGroupFactory::AddGroup(this->getShared(), childGroup->getShared()) ; + } + + + template + void CGroupTemplate::sendCreateChild(const string& id) + { + CContext* context=CContext::getCurrent() ; + + if (! context->hasServer ) + { + CContextClient* client=context->client ; + + CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + } + + template + void CGroupTemplate::sendCreateChildGroup(const string& id) + { + CContext* context=CContext::getCurrent() ; + if (! context->hasServer ) + { + CContextClient* client=context->client ; + + CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD_GROUP) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + } + + template + void CGroupTemplate::recvCreateChild(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + V::get(id)->recvCreateChild(*buffer) ; + } + + + template + void CGroupTemplate::recvCreateChild(CBufferIn& buffer) + { + string id ; + buffer>>id ; + createChild(id) ; + } + + template + void CGroupTemplate::recvCreateChildGroup(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + V::get(id)->recvCreateChildGroup(*buffer) ; + } + + + template + void CGroupTemplate::recvCreateChildGroup(CBufferIn& buffer) + { + string id ; + buffer>>id ; + createChildGroup(id) ; + } + + + template + bool CGroupTemplate::dispatchEvent(CEventServer& event) + { + if (CObjectTemplate::dispatchEvent(event)) return true ; + else + { + switch(event.type) + { + case EVENT_ID_CREATE_CHILD : + recvCreateChild(event) ; + return true ; + break ; + + case EVENT_ID_CREATE_CHILD_GROUP : + recvCreateChildGroup(event) ; + return true ; + break ; + + default : + return false ; + } + } + } + + template + void CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr) + { + + StdString name = node.getElementName(); + xml::THashAttributes attributes = node.getAttributes(); + if (withAttr) + { + CGroupTemplate::SuperClass::parse(node); + if (attributes.end() != attributes.find("src")) + { + StdIFStream ifs ( attributes["src"].c_str() , StdIFStream::in ); + if ( (ifs.rdstate() & std::ifstream::failbit ) != 0 ) + ERROR("void CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr)", + < file" ); + + if (!ifs.good()) + ERROR("CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr)", + << "[ filename = " << attributes["src"] << " ] Bad xml stream !"); + xml::CXMLParser::ParseInclude(ifs, attributes["src"].c_str(), *this); + } + } + + // PARSING POUR GESTION DES ENFANTS + V* group_ptr = (this->hasId()) + ? V::get(this->getId()) + : boost::polymorphic_downcast(this); + + if (!(node.goToChildElement())) + { + if (this->hasId()) + { + DEBUG(<< "L'objet de type \'" << V::GetName() + << "\' nommé \'" << this->getId() + << "\' ne contient pas d\'enfant !"); + } + } + else + { + do { // Parcours pour traitement. + + StdString name = node.getElementName(); + attributes.clear(); + attributes = node.getAttributes(); + + if (name.compare(V::GetName()) == 0) + { + if (attributes.end() == attributes.find("id")) + CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node); + else + CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node); + continue; + } + + if (name.compare(U::GetName()) == 0) + { + if (attributes.end() == attributes.find("id")) + CGroupFactory::CreateChild(group_ptr->getShared())->parse(node); + else + CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node); + continue; + } + + DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId() + << "\', un objet de type \'" << V::GetName() + << "\' ne peut contenir qu'un objet de type \'" << V::GetName() + << "\' ou de type \'" << U::GetName() + << "\' (reçu : " << name << ") !"); + + } while (node.goToNextElement()); + node.goToParentElement(); // Retour au parent + } + } + + template + void CGroupTemplate::parseChild(xml::CXMLNode & node) + { + + + // PARSING POUR GESTION DES ENFANTS + V* group_ptr = (this->hasId()) + ? V::get(this->getId()) + : boost::polymorphic_downcast(this); + + StdString name = node.getElementName(); + xml::THashAttributes attributes = node.getAttributes(); + + if (name.compare(V::GetName()) == 0) + { + if (attributes.end() == attributes.find("id")) + CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node); + else + CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node); + return ; + } + else if (name.compare(U::GetName()) == 0) + { + if (attributes.end() == attributes.find("id")) + CGroupFactory::CreateChild(group_ptr->getShared())->parse(node); + else + CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node); + return ; + } + + DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId() + << "\', un objet de type \'" << V::GetName() + << "\' ne peut contenir qu'un objet de type \'" << V::GetName() + << "\' ou de type \'" << U::GetName() + << "\' (reçu : " << name << ") !"); + + } +} // namespace xios + + +#endif // __XMLIO_CGroupTemplate_impl__ diff --git a/src/indent.cpp b/src/indent.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74673cf5a2c209bd222f3f88cdd979f9d1b05186 --- /dev/null +++ b/src/indent.cpp @@ -0,0 +1,71 @@ +#include "indent.hpp" +#include +#include + +using namespace std ; + +namespace xios +{ + Cindent iendl ; + Cindent ireset(0,true) ; + int Cindent::defaultIncSize=2 ; + int Cindent::index=ios::xalloc() ; + + Cindent::Cindent(int i,bool r) : offset(i), reset(r), incSize(defaultIncSize) + { } + + Cindent Cindent::operator++() + { + return Cindent(incSize) ; + } + + Cindent Cindent::operator--() + { + return Cindent(-incSize) ; + } + + Cindent Cindent::operator++(int) + { + return Cindent(incSize) ; + } + + Cindent Cindent::operator--(int) + { + return Cindent(-incSize) ; + } + + Cindent Cindent::operator+=(int i) + { + return Cindent(incSize*i) ; + } + + Cindent Cindent::operator-=(int i) + { + return Cindent(-incSize*i) ; + } + + ostream& Cindent::iendl(ostream& o) const + { + if (reset) + { + o.iword(index)=0 ; + return o ; + } + else + { + o.iword(index)+=offset ; + if (o.iword(index)<0) o.iword(index)=0 ; + o<<"\n" ; + int mem=o.width(o.iword(index)) ; + o<<""; + o.width(mem) ; + return o ; + } + } + + ostream& operator <<(ostream& o, const Cindent& indent) + { + return indent.iendl(o) ; + } + +} diff --git a/src/indent.hpp b/src/indent.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8af2f6bed35041ed6a067b180abdd0b2c00d7d05 --- /dev/null +++ b/src/indent.hpp @@ -0,0 +1,34 @@ +#ifndef __XIOS_INDENT_HPP__ +#define __XIOS_INDENT_HPP__ + +#include + +namespace xios +{ + class Cindent + { + public: + static int defaultIncSize; + static int index ; + int incSize ; + int offset ; + bool reset ; + public : + + Cindent(int i=0, bool r=false) ; + Cindent operator++(int) ; + Cindent operator--(int) ; + Cindent operator++() ; + Cindent operator--() ; + Cindent operator+=(int n) ; + Cindent operator-=(int n) ; + std::ostream& iendl(std::ostream& o) const ; + }; + + std::ostream& operator <<(std::ostream& o, const Cindent& indent) ; + + extern Cindent iendl; + extern Cindent ireset; + +} +#endif diff --git a/src/indent_xml.cpp b/src/indent_xml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59cb84f42cc6f8f6e2f9ad2058710770b44aaa7a --- /dev/null +++ b/src/indent_xml.cpp @@ -0,0 +1,53 @@ +#include "indent_xml.hpp" + +/// boost headers /// +#include +#include + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + unsigned int CIndent::Indent = 0; + StdString CIndent::Increm = StdString(" "); + bool CIndent::WithLine = false; + + StdOStream & CIndent::NIndent(StdOStream& out) + { + static unsigned int LineNB = 1; + if (CIndent::WithLine) out << LineNB++ << ". "; + for(unsigned int i = 0; i < CIndent::Indent; out << CIndent::Increm , i++){} + return (out); + } + + StdOStream & CIndent::IncIndent(StdOStream& out) + { CIndent::Indent++; return (CIndent::NIndent(out)); } + + StdOStream & CIndent::DecEndl (StdOStream& out) + { CIndent::Indent--; return (out); } + + ///---------------------------------------- + + StdString CIndentedXml::Indented(const StdString & content) + { + StdOStringStream retvalue; + std::vector str; + boost::split(str, content, boost::is_any_of("\n")); + + std::vector::iterator it = str.begin(), end = str.end(); + + for (; it != end; it++) + { + StdString & line = *it; + if (line.find("") != StdString::npos) + retvalue << CIndent::IncIndent << line << CIndent::DecEndl << std::endl; + else + retvalue << CIndent::IncIndent << line << std::endl; + } + return (retvalue.str()); + } +} // namespace xios diff --git a/src/indent_xml.hpp b/src/indent_xml.hpp new file mode 100644 index 0000000000000000000000000000000000000000..10c699e68ee5b54015476af1885c46490c149e62 --- /dev/null +++ b/src/indent_xml.hpp @@ -0,0 +1,50 @@ +#ifndef __XMLIO_CIndent_XML__ +#define __XMLIO_CIndent_XML__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "xml_node.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CIndent + { + public : + + /// Méthodes statiques /// + static StdOStream & NIndent (StdOStream & out); + static StdOStream & IncIndent(StdOStream & out); + static StdOStream & DecEndl (StdOStream & out); + + private : + + /// Propriétés statiques /// + static unsigned int Indent; + static StdString Increm; + static bool WithLine; + + }; // class CIndent + + ///-------------------------------------------------------------- + + class CIndentedXml + { + public : + + /// Méthode statique /// + static StdString Indented(const StdString & content); + + }; // class CIndentedXml + + ///-------------------------------------------------------------- + +} // namespace xios + + /// ////////////////////// Macros ////////////////////// /// + +#define NIndent CIndent::NIndent +#define IncIndent CIndent::IncIndent +#define DecEndl CIndent::DecEndl + +#endif // __XMLIO_CIndent__ diff --git a/src/input/inetcdf4.cpp b/src/input/inetcdf4.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b29709cf7d01675e338730fbe82e35f49180311 --- /dev/null +++ b/src/input/inetcdf4.cpp @@ -0,0 +1,788 @@ +#include "inetcdf4.hpp" + +#include + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + CINetCDF4::CINetCDF4(const StdString & filename) + { + CheckError(nc_open(filename.c_str(), NC_NOWRITE, &this->ncidp)); + } + + CINetCDF4::~CINetCDF4(void) + { + CheckError(nc_close(this->ncidp)); + } + + ///-------------------------------------------------------------- + + void CINetCDF4::CheckError(int status) + { + if (status != NC_NOERR) + { + StdString errormsg (nc_strerror(status)); // fuite mémoire ici ? + ERROR("CINetCDF4::CheckError(int status)", + << "[ status = " << status << " ] " << errormsg); + } + } + + //--------------------------------------------------------------- + + int CINetCDF4::getGroup(const CVarPath * const path) + { + int retvalue = this->ncidp; + if (path == NULL) return (retvalue); + CVarPath::const_iterator it = path->begin(), end = path->end(); + + for (; it != end; it++) + { + const StdString & groupid = *it; + CheckError(nc_inq_ncid(retvalue, const_cast(groupid.c_str()), &retvalue)); + } + + return (retvalue); + } + + int CINetCDF4::getVariable(const StdString & varname, + const CVarPath * const path) + { + int varid = 0; + int grpid = this->getGroup(path); + CheckError(nc_inq_varid (grpid, varname.c_str(), &varid)); + return (varid); + } + + int CINetCDF4::getDimension(const StdString & dimname, + const CVarPath * const path) + { + int dimid = 0; + int grpid = this->getGroup(path); + CheckError(nc_inq_dimid (grpid, dimname.c_str(), &dimid)); + return (dimid); + } + + std::pair CINetCDF4::getAttribute + (const StdString & attname, + const StdString * const var, + const CVarPath * const path) + { + std::pair retvalue; + int grpid = this->getGroup(path); + int varid = (var != NULL) + ? this->getVariable(*var, path) : NC_GLOBAL; + CheckError(nc_inq_att(grpid, varid, attname.c_str(), + &retvalue.first, &retvalue.second)); + return (retvalue); + } + + int CINetCDF4::getUnlimitedDimension(const CVarPath * const path) + { + int dimid = 0; + int grpid = this->getGroup(path); + CheckError(nc_inq_unlimdim (grpid, &dimid)); + return (dimid); + } + + StdString CINetCDF4::getUnlimitedDimensionName(const CVarPath * const path) + { + char full_name_in[NC_MAX_NAME +1]; + int grpid = this->getGroup(path); + int dimid = this->getUnlimitedDimension(path); + CheckError(nc_inq_dimname(grpid, dimid, full_name_in)); + + StdString dimname(full_name_in); + return (dimname); + } + + //--------------------------------------------------------------- + StdSize CINetCDF4::getNbVertex(const StdString & name, + const CVarPath * const path) + { + + if (this->isRectilinear(name, path) || + this->isCurvilinear(name, path)) + { + if (this->is3Dim(name, path)) return (8); + else return (4); + } + if (this->isUnstructured(name, path)) + { + StdString bound = this->getBoundsId + (this->getCoordinatesIdList(name, path).back(), path); + StdString dim = this->getDimensionsList(&bound, path).back(); + return (this->getDimensions(&bound, path)[dim]); + } + return ((size_t)(-1)); + } + + //--------------------------------------------------------------- + + std::list CINetCDF4::getGroups(const CVarPath * const path) + { + StdSize strlen = 0; + char full_name_in[NC_MAX_NAME +1]; + int nbgroup = 0, *groupid = NULL; + int grpid = this->getGroup(path); + std::list retvalue; + + CheckError(nc_inq_grps(grpid, &nbgroup, NULL)); + groupid = new int[nbgroup](); + CheckError(nc_inq_grps(grpid, NULL, groupid)); + + for (int i = 0; i < nbgroup; i++) + { + CheckError(nc_inq_grpname_full(groupid[i], &strlen, full_name_in)); + StdString groupname(full_name_in, strlen); + retvalue.push_back(groupname); + } + + delete [] groupid; + return (retvalue); + } + + std::list CINetCDF4::getVariables(const CVarPath * const path) + { + char full_name_in[NC_MAX_NAME +1]; + int nbvar = 0, *varid = NULL; + int grpid = this->getGroup(path); + std::list retvalue; + + CheckError(nc_inq_varids(grpid, &nbvar, NULL)); + varid = new int[nbvar](); + CheckError(nc_inq_varids(grpid, NULL, varid)); + + for (int i = 0; i < nbvar; i++) + { + CheckError(nc_inq_varname(grpid, varid[i], full_name_in)); + StdString varname(full_name_in); + retvalue.push_back(varname); + } + + delete [] varid; + return (retvalue); + } + + StdSize CINetCDF4::getNbOfTimestep(const CVarPath * const path) + { + return (this->getDimensions(NULL, path)[this->getUnlimitedDimensionName(path)]); + } + + std::set CINetCDF4::getBoundVariables(const CVarPath * const path) + { + std::set retvalue; + std::list variables = this->getVariables(path); + std::list::const_iterator it = variables.begin(), end = variables.end(); + for (; it != end; it++) + { + const StdString & var = *it; + if (this->hasBounds(var, path)) + retvalue.insert(retvalue.end(), this->getBoundsId(var, path)); + } + return (retvalue); + } + + std::set CINetCDF4::getCoordVariables(const CVarPath * const path) + { + std::set retvalue; + std::list variables = this->getVariables(path); + std::list::const_iterator it = variables.begin(), end = variables.end(); + for (; it != end; it++) + { + const StdString & var = *it; + std::list coords = this->getCoordinatesIdList(var, path); + std::list::const_iterator it = coords.begin(), end = coords.end(); + for (; it != end; it++) + { + const StdString & coord = *it; + if (this->hasVariable(coord, path)) + retvalue.insert(retvalue.end(), coord); + } + } + return (retvalue); + } + + std::list CINetCDF4::getDimensionsList + (const StdString * const var, const CVarPath * const path) + { + char full_name_in[NC_MAX_NAME +1]; + int nbdim = 0, *dimid = NULL; + int grpid = this->getGroup(path); + int varid = (var != NULL) + ? this->getVariable(*var, path) : NC_GLOBAL; + std::list retvalue; + + if (var != NULL) + { + CheckError(nc_inq_varndims(grpid, varid, &nbdim)); + dimid = new int[nbdim](); + CheckError(nc_inq_vardimid(grpid, varid, dimid)); + } + else + { + CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); + dimid = new int[nbdim](); + CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); + } + + for (int i = 0; i < nbdim; i++) + { + CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in)); + StdString dimname(full_name_in); + retvalue.push_back(dimname); + } + delete [] dimid; + + return (retvalue); + } + + std::map CINetCDF4::getDimensions + (const StdString * const var, const CVarPath * const path) + { + StdSize size = 0; + char full_name_in[NC_MAX_NAME +1]; + int nbdim = 0, *dimid = NULL; + int grpid = this->getGroup(path); + int varid = (var != NULL) + ? this->getVariable(*var, path) : NC_GLOBAL; + std::map retvalue; + + if (var != NULL) + { + CheckError(nc_inq_varndims(grpid, varid, &nbdim)); + dimid = new int[nbdim](); + CheckError(nc_inq_vardimid(grpid, varid, dimid)); + } + else + { + CheckError(nc_inq_dimids(grpid, &nbdim, NULL, 1)); + dimid = new int[nbdim](); + CheckError(nc_inq_dimids(grpid, NULL, dimid, 1)); + } + + for (int i = 0; i < nbdim; i++) + { + CheckError(nc_inq_dimname(grpid, dimid[i], full_name_in)); + CheckError(nc_inq_dimlen (grpid, dimid[i], &size)); + + StdString dimname(full_name_in); + retvalue.insert(retvalue.end(), std::make_pair(dimname, size)); + } + delete [] dimid; + + return (retvalue); + } + + std::list CINetCDF4::getAttributes + (const StdString * const var, const CVarPath * const path ) + { + int nbatt = 0; + char full_name_in[NC_MAX_NAME +1]; + std::list retvalue; + int grpid = this->getGroup(path); + int varid = (var != NULL) + ? this->getVariable(*var, path) : NC_GLOBAL; + + if (var != NULL) + CheckError(nc_inq_varnatts (grpid, varid, &nbatt)); + else + CheckError(nc_inq_natts(grpid, &nbatt)); + + for (int i = 0; i < nbatt; i++) + { + CheckError(nc_inq_attname(grpid, varid, i, full_name_in)); + StdString attname(full_name_in); + retvalue.push_back(attname); + } + return (retvalue); + } + + int CINetCDF4::getAttributeId(const StdString & name, + const StdString * const var, + const CVarPath * const path) + { + int retvalue = 0; + std::list atts = this->getAttributes(var, path); + std::list::const_iterator it = atts.begin(), end = atts.end(); + for (; it != end; it++) + { + const StdString & attname = *it; + if (attname.compare(name) == 0) + return (retvalue); + retvalue++; + } + return (-1); + } + + //--------------------------------------------------------------- + + bool CINetCDF4::hasMissingValue(const StdString & name, + const CVarPath * const path) + { + return (this->hasAttribute("missing_value", &name, path) || + this->hasAttribute("_FillValue", &name, path)); + } + + bool CINetCDF4::hasAttribute(const StdString & name, + const StdString * const var , + const CVarPath * const path) + { + std::list atts = this->getAttributes(var, path); + std::list::const_iterator it = atts.begin(), end = atts.end(); + for (; it != end; it++) + { + const StdString & attname = *it; + if (attname.compare(name) == 0) return (true); + } + return (false); + } + + bool CINetCDF4::hasVariable(const StdString & name, + const CVarPath * const path) + { + std::list variables = this->getVariables(path); + std::list::const_iterator it = variables.begin(), end = variables.end(); + for (; it != end; it++) + { + const StdString & varname = *it; + if (varname.compare(name) == 0) return (true); + } + return (false); + } + + bool CINetCDF4::hasCoordinates(const StdString & name, + const CVarPath * const path) + { + return (this->hasAttribute("coordinates", &name, path)); + } + + bool CINetCDF4::hasBounds(const StdString & name, + const CVarPath * const path) + { + return (this->hasAttribute("bounds", &name, path)); + } + + bool CINetCDF4::hasTemporalDim(const CVarPath * const path) + { + return (this->getUnlimitedDimension(path) != -1); + } + + //--------------------------------------------------------------- + +#define GET_ATTRIBUTE_VALUE(type, func_ext, type_enum) \ + template <> \ + std::vector CINetCDF4::getAttributeValue \ + (const StdString & name, const StdString * const var, \ + const CVarPath * const path) \ + { \ + int grpid = this->getGroup(path); \ + int varid = (var != NULL) \ + ? this->getVariable(*var, path) : NC_GLOBAL; \ + std::pair attinfos = \ + this->getAttribute(name, var, path); \ + std::vector retvalue(attinfos.second); \ + if (attinfos.first != type_enum) \ + ERROR("CINetCDF4::getAttributeValue(name, var, path", \ + << "[ name : " << name \ + << ", type requested :" << attinfos.first \ + << ", type stored : " << type_enum << "]" \ + << " Invalid type !"); \ + CheckError(nc_get_att_##func_ext \ + (grpid, varid, name.c_str(), &(retvalue[0]))); \ + return (retvalue); \ + } + + GET_ATTRIBUTE_VALUE(double, double, NC_DOUBLE) + GET_ATTRIBUTE_VALUE(float , float , NC_FLOAT) + GET_ATTRIBUTE_VALUE(int , int , NC_INT) + GET_ATTRIBUTE_VALUE(char , text , NC_CHAR) + + template <> + StdString CINetCDF4::getAttributeValue + (const StdString & name, const StdString * const var, + const CVarPath * const path) + { + std::vector chart = this->getAttributeValue + >(name, var, path); + StdString retvalue(&(chart[0]), chart.size()); + return (retvalue); + } + + template <> + int CINetCDF4::getMissingValue(const StdString & name, + const CVarPath * const path) + { + if (this->hasAttribute("missing_value", &name, path)) + return (this->getAttributeValue >("missing_value", &name, path)[0]); + if (this->hasAttribute("_FillValue", &name, path)) + return (this->getAttributeValue >("_FillValue", &name, path)[0]); + return (0); + } + + template <> + double CINetCDF4::getMissingValue(const StdString & name, + const CVarPath * const path) + { + if (this->hasAttribute("missing_value", &name, path)) + return (this->getAttributeValue >("missing_value", &name, path)[0]); + if (this->hasAttribute("_FillValue", &name, path)) + return (this->getAttributeValue >("_FillValue", &name, path)[0]); + return (0); + } + + template <> + float CINetCDF4::getMissingValue(const StdString & name, + const CVarPath * const path) + { + if (this->hasAttribute("missing_value", &name, path)) + return (this->getAttributeValue >("missing_value", &name, path)[0]); + if (this->hasAttribute("_FillValue", &name, path)) + return (this->getAttributeValue >("_FillValue", &name, path)[0]); + return (0); + } + + //--------------------------------------------------------------- + + std::list CINetCDF4::getCoordinatesIdList + (const StdString & name, const CVarPath * const path) + { + std::list retvalue; + StdString value = this->getCoordinatesId(name, path); + + boost::split(retvalue, value, boost::is_any_of(" ")); + + std::list::iterator it = retvalue.begin(), end = retvalue.end(); + for (; it != end; it++) + { + StdString & coord = *it; + coord.assign(coord.data()); + } + return (retvalue); + } + + StdString CINetCDF4::getCoordinatesId + (const StdString & name, const CVarPath * const path) + { + StdString retvalue; + if (this->hasAttribute("coordinates", &name, path)) + { + return (this->getAttributeValue("coordinates", &name, path)); + } + else + { + std::list dims = this->getDimensionsList(&name, path); + std::list::const_iterator it = dims.begin(), end = dims.end(); + for (; it != end; it++) + { + const StdString & value = *it; + retvalue.append(value).push_back(' '); + } + retvalue.erase (retvalue.end()-1) ; + } + + return (retvalue); + } + + StdString CINetCDF4::getBoundsId(const StdString & name, + const CVarPath * const path) + { + StdString retvalue; + if (this->hasAttribute("bounds", &name, path)) + return (this->getAttributeValue("bounds", &name, path)); + return (retvalue); + } + + //--------------------------------------------------------------- + + bool CINetCDF4::isBound(const StdString & name, + const CVarPath * const path) + { + std::set bounds = this->getBoundVariables(path); + return (bounds.find(name) != bounds.end()); + } + + bool CINetCDF4::isCoordinate(const StdString & name, + const CVarPath * const path) + { + std::set coords = this->getCoordVariables(path); + return (coords.find(name) != coords.end()); + } + + bool CINetCDF4::isRectilinear(const StdString & name, const CVarPath * const path) + { + std::list coords = this->getCoordinatesIdList(name, path); + std::list::const_iterator it = coords.begin(), end = coords.end(); + for (; it != end; it++) + { + const StdString & coord = *it; + if (this->hasVariable(coord, path) && !this->isTemporal(coord, path)) + { + std::map dimvar = this->getDimensions(&coord, path); + if ((dimvar.size() == 1) && (dimvar.find(coord) != dimvar.end())) + continue; + else + return (false); + } + } + return (true); + } + + bool CINetCDF4::isCurvilinear(const StdString & name, const CVarPath * const path) + { + if (this->isRectilinear(name, path) || + !this->hasCoordinates(name, path)) + return (false); + + std::list coords = this->getCoordinatesIdList(name, path); + std::list::const_iterator it = coords.begin(), end = coords.end(); + for (; it != end; it++) + { + const StdString & coord = *it; + if (this->hasVariable(coord, path)) + { + std::map dimvar = this->getDimensions(&coord, path); + if (dimvar.size() != 2) return (false); + } + else return (false); + } + return (true); + } + + bool CINetCDF4::isUnstructured(const StdString & name, const CVarPath * const path) + { + if (this->isRectilinear(name, path) || + this->isCurvilinear(name, path) || + !this->hasCoordinates(name, path)) + return (false); + + StdString dimname = this->getDimensionsList(&name, path).back(); + + std::list coords = this->getCoordinatesIdList(name, path); + std::list::const_iterator it = coords.begin(), end = coords.end(); + for (; it != end; it++) + { + const StdString & coord = *it; + if (this->hasVariable(coord, path)) + { + std::map dimvar = this->getDimensions(&coord, path); + if ((dimvar.size() == 1) && + (dimvar.find(dimname) != dimvar.end())) + continue; + else + return (false); + } + else return (false); + } + + return (true); + } + + bool CINetCDF4::isUnknown(const StdString & name, const CVarPath * const path) + { + return !(this->isRectilinear(name, path) || + this->isCurvilinear(name, path) || + this->isUnstructured(name, path)); + } + + bool CINetCDF4::isTemporal(const StdString & name, const CVarPath * const path) + { + if (!this->hasTemporalDim(path)) return (false); + std::map dims = this->getDimensions(&name, path); + if (dims.find(this->getUnlimitedDimensionName(path)) != dims.end()) + return (true); + return (false); + } + + bool CINetCDF4::is3Dim(const StdString & name, const CVarPath * const path) + { + int i = 0; + std::list coords = this->getCoordinatesIdList(name, path); + std::list::const_iterator it = coords.begin(), end = coords.end(); + for (; it != end; it++) + { + const StdString & coord = *it; + if (this->hasVariable(coord, path)) + { + if (this->isTemporal(coord, path)) + continue; + i++; + } + else + { + if (coord.compare(this->getUnlimitedDimensionName()) == 0) + continue; + i++; + } + } + return (i == 3); + } + + bool CINetCDF4::isCellGrid(const StdString & name, const CVarPath * const path) + { + if (this->isCoordinate(name, path)) + { + return (this->hasBounds(name, path)); + } + else + { + std::list coords = this->getCoordinatesIdList(name, path); + std::list::const_iterator it = coords.begin(), end = coords.end(); + for (; it != end; it++) + { + const StdString & coord = *it; + if (this->hasVariable(coord, path)) + { + if (this->isTemporal(coord, path)) + continue; + if (this->isCellGrid(coord, path)) + continue; + return (false); + } + else + { + if (coord.compare(this->getUnlimitedDimensionName()) == 0) + continue; + return (false); + } + } + } + + return (true); + } + + //--------------------------------------------------------------- + + std::list CINetCDF4::getDataVariables(bool _is3D, bool _isRecti, + bool _isCurvi, bool _isUnstr, + bool _isCellData, bool _isTemporal, + const CVarPath * const path) + { + std::list retvalue; + std::list allvars = this->getVariables(path); + std::set allcoords = this->getCoordVariables(path); + + std::list::const_iterator it = allvars.begin(), end = allvars.end(); + for (; it != end; it++) + { + const StdString & var = *it; + if (this->isCoordinate(var, path)) continue; + + if (!_isRecti && this->isRectilinear(var, path) ) continue; + if (!_isCurvi && this->isCurvilinear(var, path) ) continue; + if (!_isUnstr && this->isUnstructured(var, path)) continue; + + if (!_isTemporal && this->isTemporal(var, path)) continue; + if (!_is3D && this->is3Dim(var, path) ) continue; + if (!_isCellData && this->isCellGrid(var, path)) continue; + + if (this->isUnknown(var, path)) continue; + + retvalue.push_back(var); + } + return (retvalue); + } + + //--------------------------------------------------------------- + + void CINetCDF4::getDataInfo(const StdString & var, const CVarPath * const path, StdSize record, + std::vector & start, std::vector & count, + StdSize & array_size) + { + std::list dimlist = this->getDimensionsList(&var, path); + std::map dimmap = this->getDimensions(&var, path); + std::list::iterator it = dimlist.begin(); + if (this->isTemporal(var, path)) + { + if (record != UNLIMITED_DIM) + start.push_back(record); + else + start.push_back(0); + count.push_back(1); + it++; + } + for (; it != dimlist.end(); it++) + { + start.push_back(0); + count.push_back(dimmap[*it]); + array_size *= dimmap[*it]; + } + } + + template <> + void CINetCDF4::getData(CArray& data, const StdString & var, + const CVarPath * const path, StdSize record) + { + + std::vector start, count; + int grpid = this->getGroup(path); + int varid = this->getVariable(var, path); + StdSize array_size = 1; + this->getDataInfo(var, path, record, start, count, array_size); + data.resize(array_size); + CheckError(nc_get_vara_int (grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); + } + + template <> + void CINetCDF4::getData(CArray& data, const StdString & var, + const CVarPath * const path, StdSize record) + { + std::vector start, count; + int grpid = this->getGroup(path); + int varid = this->getVariable(var, path); + StdSize array_size = 1; + this->getDataInfo(var, path, record, start, count, array_size); + data.resize(array_size); + CheckError(nc_get_vara_double (grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); + } + + template <> + void CINetCDF4::getData(CArray& data, const StdString & var, + const CVarPath * const path, StdSize record) + { + std::vector start, count; + int grpid = this->getGroup(path); + int varid = this->getVariable(var, path); + StdSize array_size = 1; + this->getDataInfo(var, path, record, start, count, array_size); + data.resize(array_size); + CheckError(nc_get_vara_float (grpid, varid, &(start[0]), &(count[0]), data.dataFirst())); + } + + //--------------------------------------------------------------- + StdString CINetCDF4::getLonCoordName(const StdString & varname, + const CVarPath * const path) + { + std::list clist = + this->getCoordinatesIdList(varname, path); + if (this->hasCoordinates(varname, path)) + return (*clist.begin()); + else + return (*clist.rbegin()); + } + + StdString CINetCDF4::getLatCoordName(const StdString & varname, + const CVarPath * const path) + { + std::list clist = + this->getCoordinatesIdList(varname, path); + if (this->hasCoordinates(varname, path)) + return (*(++clist.begin())); + else + return (*(++clist.rbegin())); + } + + StdString CINetCDF4::getVertCoordName(const StdString & varname, + const CVarPath * const path) + { + if (!this->is3Dim(varname, path)) return (""); + std::list clist = + this->getCoordinatesIdList(varname, path); + if (this->hasCoordinates(varname, path)) + return (*(++(++clist.begin()))); + else + return (*(++(++clist.rbegin()))); + } + + ///-------------------------------------------------------------- + +} // namespace xios diff --git a/src/input/inetcdf4.hpp b/src/input/inetcdf4.hpp new file mode 100644 index 0000000000000000000000000000000000000000..528d13215b262a1ac9360bb2a8e6d6c694f0df6f --- /dev/null +++ b/src/input/inetcdf4.hpp @@ -0,0 +1,235 @@ +#ifndef __XMLIO_INETCDF4__ +#define __XMLIO_INETCDF4__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "array_new.hpp" + +#include "mpi.hpp" +#include "netcdf.hpp" + +#ifndef UNLIMITED_DIM + #define UNLIMITED_DIM (size_t)(-1) +#endif //UNLIMITED_DIM + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + typedef std::vector CVarPath; + + class CINetCDF4 + { + public : + + /// Constructeurs /// + CINetCDF4(void); // Not implemented. + CINetCDF4(const StdString & filename); + CINetCDF4(const CINetCDF4 & inetcdf4); // Not implemented. + CINetCDF4(const CINetCDF4 * const inetcdf4); // Not implemented. + + //------------------------------------------------------------- + + /// Accesseurs /// + StdSize getNbOfTimestep(const CVarPath * const path = NULL); + + StdString getUnlimitedDimensionName(const CVarPath * const path = NULL); + + StdString getCoordinatesId(const StdString & name, + const CVarPath * const path = NULL); + + StdString getBoundsId(const StdString & name, + const CVarPath * const path = NULL); + + StdString getLonCoordName(const StdString & varname, + const CVarPath * const path = NULL); + StdString getLatCoordName(const StdString & varname, + const CVarPath * const path = NULL); + StdString getVertCoordName(const StdString & varname, + const CVarPath * const path = NULL); + + std::set getCoordVariables(const CVarPath * const path = NULL); + std::set getBoundVariables(const CVarPath * const path = NULL); + + std::list getGroups (const CVarPath * const path = NULL); + std::list getVariables(const CVarPath * const path = NULL); + + std::list getDataVariables(bool _is3D = true, + bool _isRecti = true, + bool _isCurvi = true, + bool _isUnstr = true, + bool _isCellData = true, + bool _isTemporal = true, + const CVarPath * const path = NULL); + + std::list getAttributes + (const StdString * const var = NULL, + const CVarPath * const path = NULL); + + std::list getDimensionsList + (const StdString * const var = NULL, + const CVarPath * const path = NULL); + + std::list getCoordinatesIdList(const StdString & name, + const CVarPath * const path = NULL); + + std::map getDimensions (const StdString * const var = NULL, + const CVarPath * const path = NULL); + + StdSize getNbVertex(const StdString & name, + const CVarPath * const path = NULL); + //------------------------------------------------------------- + + template + T getMissingValue(const StdString & name, + const CVarPath * const path = NULL); + + template + T getAttributeValue(const StdString & name, + const StdString * const var = NULL, + const CVarPath * const path = NULL); + + template + void getData(CArray& data, + const StdString & var, + const CVarPath * const path = NULL, + StdSize record = UNLIMITED_DIM); + + //------------------------------------------------------------- + + /// Tests /// + bool hasMissingValue(const StdString & name, + const CVarPath * const path = NULL); + + bool hasAttribute(const StdString & name, + const StdString * const var = NULL, + const CVarPath * const path = NULL); + + bool hasVariable(const StdString & name, + const CVarPath * const path = NULL); + + bool hasCoordinates(const StdString & name, + const CVarPath * const path = NULL); + + bool hasTemporalDim(const CVarPath * const path = NULL); + + bool hasBounds(const StdString & name, + const CVarPath * const path = NULL); + + //------------------------------------------------------------- + + bool isBound(const StdString & name, + const CVarPath * const path = NULL); + bool isCoordinate(const StdString & name, + const CVarPath * const path = NULL); + bool isRectilinear(const StdString & name, + const CVarPath * const path = NULL); + bool isCurvilinear(const StdString & name, + const CVarPath * const path = NULL); + bool isUnknown(const StdString & name, + const CVarPath * const path = NULL); + bool isUnstructured(const StdString & name, + const CVarPath * const path = NULL); + + bool isTemporal(const StdString & name, + const CVarPath * const path = NULL); + bool is3Dim(const StdString & name, + const CVarPath * const path = NULL); + bool isCellGrid(const StdString & name, + const CVarPath * const path = NULL); + + //------------------------------------------------------------- + + /// Destructeur /// + virtual ~CINetCDF4(void); + + protected : + + //------------------------------------------------------------- + + /// Accesseurs /// + int getGroup (const CVarPath * const path = NULL); + int getVariable(const StdString & varname, + const CVarPath * const path = NULL); + int getDimension(const StdString & dimname, + const CVarPath * const path = NULL); + int getUnlimitedDimension(const CVarPath * const path = NULL); + int getAttributeId(const StdString & name, + const StdString * const var = NULL, + const CVarPath * const path = NULL); + + std::pair getAttribute(const StdString & attname, + const StdString * const var = NULL, + const CVarPath * const path = NULL); + + //------------------------------------------------------------- + + void getDataInfo(const StdString & var, const CVarPath * const path, StdSize record, + std::vector & start, std::vector & count, + StdSize & array_size); + + private : + + /// Vérification des erreurs NetCDF /// + static void CheckError(int status); + + int ncidp; // Identifiant de fichier netcdf. + + }; // class CINetCDF4 + + ///-------------------------------------------------------------- + template <> + StdString CINetCDF4::getAttributeValue + (const StdString & name, const StdString * const var, + const CVarPath * const path); + + template <> + std::vector CINetCDF4::getAttributeValue + (const StdString & name, const StdString * const var, + const CVarPath * const path); + + template <> + std::vector CINetCDF4::getAttributeValue + (const StdString & name, const StdString * const var, + const CVarPath * const path); + + template <> + std::vector CINetCDF4::getAttributeValue + (const StdString & name, const StdString * const var, + const CVarPath * const path); + + template <> + std::vector CINetCDF4::getAttributeValue + (const StdString & name, const StdString * const var, + const CVarPath * const path); + + //--------------------------------------------------------------- + template <> + int CINetCDF4::getMissingValue + (const StdString & name, const CVarPath * const path); + + template <> + double CINetCDF4::getMissingValue + (const StdString & name, const CVarPath * const path); + + template <> + float CINetCDF4::getMissingValue + (const StdString & name, const CVarPath * const path); + + //--------------------------------------------------------------- + template <> + void CINetCDF4::getData(CArray& data, const StdString & var, + const CVarPath * const path, StdSize record); + + template <> + void CINetCDF4::getData(CArray& data, const StdString & var, + const CVarPath * const path, StdSize record); + + template <> + void CINetCDF4::getData(CArray& data, const StdString & var, + const CVarPath * const path, StdSize record); + ///-------------------------------------------------------------- + +} // namespace xmlioserver + +#endif //__XMLIO_INETCDF4__ diff --git a/src/input/nc4_data_input.cpp b/src/input/nc4_data_input.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e54b50016452d60ebfb5c706bf171ba75300aa41 --- /dev/null +++ b/src/input/nc4_data_input.cpp @@ -0,0 +1,12 @@ +#include "nc4_data_input.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + CNc4DataInput::CNc4DataInput(void) + { /* ne rien faire de plus */ } + + CNc4DataInput::~CNc4DataInput(void) + { /* ne rien faire de plus */ } + +} // namespace xios diff --git a/src/input/nc4_data_input.hpp b/src/input/nc4_data_input.hpp new file mode 100644 index 0000000000000000000000000000000000000000..90f0509df3cdf0eb5c0b9ab108922384976cd1b6 --- /dev/null +++ b/src/input/nc4_data_input.hpp @@ -0,0 +1,28 @@ +#ifndef __XMLIO_NC4_DATA_INPUT__ +#define __XMLIO_NC4_DATA_INPUT__ + +/// xmlioserver headers /// +#include "xmlioserver_spl.hpp" +#include "inetcdf4.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + + class CNc4DataInput + { + public : + + /// Constructeurs /// + CNc4DataInput(void); + CNc4DataInput(const CNc4DataInput & datainput); // Not implemented. + CNc4DataInput(const CNc4DataInput * const datainput); // Not implemented. + + /// Destructeur /// + virtual ~CNc4DataInput(void); + + }; // class CNc4DataInput + +} // namespace xios + +#endif //__XMLIO_NC4_DATA_INPUT__ diff --git a/src/interface/c/icaxis.cpp b/src/interface/c/icaxis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..038f730bb3a96462c64b114dea94db1fd0189fb3 --- /dev/null +++ b/src/interface/c/icaxis.cpp @@ -0,0 +1,70 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "object_template.hpp" +#include "group_template.hpp" +#include "attribute_template.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "axis.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef xios::CAxis * XAxisPtr; + typedef xios::CAxisGroup * XAxisGroupPtr; + + // ------------------------ Création des handle ----------------------------- + + void cxios_axis_handle_create (XAxisPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = xios::CAxis::get(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_axisgroup_handle_create (XAxisGroupPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = xios::CAxisGroup::get(id); + CTimer::get("XIOS").suspend() ; + } + + // -------------------- Vérification des identifiants ----------------------- + + void cxios_axis_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + + CTimer::get("XIOS").resume() ; + *_ret = xios::CAxis::has(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_axisgroup_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + + CTimer::get("XIOS").resume() ; + *_ret = xios::CAxisGroup::has(id); + CTimer::get("XIOS").suspend() ; + + } + +} // extern "C" diff --git a/src/interface/c/iccontext.cpp b/src/interface/c/iccontext.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1cbc185a565db4d00b97782b3d67e7504b4deb3 --- /dev/null +++ b/src/interface/c/iccontext.cpp @@ -0,0 +1,88 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "calendar_type.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "context.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef enum { D360 = 0 , ALLLEAP, NOLEAP, JULIAN, GREGORIAN } XCalendarType ; + + typedef xios::CContext * XContextPtr; + + // ------------------------ Création des handle ----------------------------- + + void cxios_context_handle_create (XContextPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + + std::vector def_vector = + xios::CContext::getRoot()->getChildList(); + + for (std::size_t i = 0; i < def_vector.size(); i++) + { + if (def_vector[i]->getId().compare(id) == 0) + { + *_ret = def_vector[i]; + CTimer::get("XIOS").suspend() ; + return; + } + } + CTimer::get("XIOS").suspend() ; + ERROR("void cxios_context_handle_create (XContextPtr * _ret, const char * _id, int _id_len)", + << "Context "<getId()); + CTimer::get("XIOS").suspend() ; + } + + + // -------------------- Vérification des identifiants ----------------------- + + void cxios_context_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + + CTimer::get("XIOS").resume(); + std::vector def_vector = + xios::CContext::getRoot()->getChildList(); + + *_ret = false; + for (std::size_t i = 0; i < def_vector.size(); i++) + { + if (def_vector[i]->getId().compare(id) == 0) + { + *_ret = true; + break; + } + } + CTimer::get("XIOS").suspend(); + } +} // extern "C" diff --git a/src/interface/c/icdata.cpp b/src/interface/c/icdata.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2e7492c3cb04070af25b35625e2988ca27ce0ee5 --- /dev/null +++ b/src/interface/c/icdata.cpp @@ -0,0 +1,471 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include +#include +#include +#include + + +#include "xmlioserver.hpp" +#include "oasis_cinterface.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "icutil.hpp" +#include "cxios.hpp" +#include "client.hpp" +#include "field.hpp" +#include "context.hpp" +#include "context_client.hpp" +#include "mpi.hpp" +#include "timer.hpp" +#include "array_new.hpp" + + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef enum { NETCDF4 = 0 } XFileType; + + typedef xios::CContext * XContextPtr; + + // -------------------- Traitement des données ------------------------------ + + // This function is not exported to the public Fortran interface, + // it is only used from the parse_xml.exe standalone test tool. + void cxios_init(void) + { + CXios::initialize(); + } + + void cxios_init_server(void) + { + CXios::initServerSide(); + } + + void cxios_init_client(const char * client_id , int len_client_id, MPI_Fint* f_local_comm, MPI_Fint* f_return_comm ) + { + std::string str; + MPI_Comm local_comm ; + MPI_Comm return_comm ; + + if (!cstr2string(client_id, len_client_id, str)) return; + + int initialized ; + MPI_Initialized(&initialized) ; + if (initialized) local_comm=MPI_Comm_f2c(*f_local_comm) ; + else local_comm=MPI_COMM_NULL ; + CXios::initClientSide(str,local_comm,return_comm); + *f_return_comm=MPI_Comm_c2f(return_comm) ; + CTimer::get("XIOS init").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_context_initialize(const char * context_id , int len_context_id, MPI_Fint* f_comm) + { + std::string str; + MPI_Comm comm ; + + if (!cstr2string(context_id, len_context_id, str)) return; + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS init context").resume() ; + comm=MPI_Comm_f2c(*f_comm) ; + CClient::registerContext(str,comm) ; + CTimer::get("XIOS init context").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_context_is_initialized(const char * context_id , int len_context_id, bool* initialized) + { + std::string str; + + if (!cstr2string(context_id, len_context_id, str)) return; + CTimer::get("XIOS").resume() ; + CContext* context = CContext::get(str,str) ; + *initialized=context->isInitialized() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_context_close_definition() + { + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS close definition").resume() ; + CContext* context = CContext::getCurrent() ; + context->closeDefinition() ; + CTimer::get("XIOS close definition").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_context_finalize() + { + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS context finalize").resume() ; + CContext* context = CContext::getCurrent() ; + context->finalize() ; + CTimer::get("XIOS context finalize").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_finalize() + { + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS finalize").resume() ; + CXios::clientFinalize() ; + } + + void cxios_solve_inheritance() + { + CTimer::get("XIOS").resume() ; + CContext* context = CContext::getCurrent() ; + context->solveAllInheritance(false) ; + CTimer::get("XIOS").suspend() ; + } + + /*! \brief This group of functions retrieve variable information from the configuration file (.xml) + * + * These functions provide intermediate C interfaces to get variable information of the configuration file (e.x iodef.xml), + * from a Fortran one, for example the value of a variable with id = "using_server". + * Each function corresponds to each basic type. + * \param varId [in] id of the variable that we'd like to get + * \param varIdSize [in] size of the variable type (integer, float, double, string) + * \param dataInt [in/out] the retrieved data + * \param isVarExisted [in/out] Verify whether variable with varId exists + */ + void cxios_get_variable_data_k8(const char * varId, int varIdSize, double * data, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS get variable data").resume(); + + CContext* context = CContext::getCurrent(); + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + *data = CVariable::get(context->getId(),varIdStr)->getData(); + } + + CTimer::get("XIOS get variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_get_variable_data_k4(const char * varId, int varIdSize, float * data, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS get variable data").resume(); + + CContext* context = CContext::getCurrent(); + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + *data = CVariable::get(context->getId(),varIdStr)->getData(); + } + + CTimer::get("XIOS get variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_get_variable_data_int(const char * varId, int varIdSize, int * data, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS get variable data").resume(); + + CContext* context = CContext::getCurrent(); + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + *data = CVariable::get(context->getId(),varIdStr)->getData(); + } + + CTimer::get("XIOS get variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_get_variable_data_logic(const char * varId, int varIdSize, bool * data, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS get variable data").resume(); + + CContext* context = CContext::getCurrent(); + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + *data = CVariable::get(context->getId(),varIdStr)->getData(); + } + + CTimer::get("XIOS get variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_get_variable_data_char(const char * varId, int varIdSize, char * data, int dataSizeIn, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS get variable data").resume(); + + CContext* context = CContext::getCurrent(); + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + int dataSizeOut = CVariable::get(context->getId(),varIdStr)->getData().length(); + strncpy(data, CVariable::get(context->getId(),varIdStr)->getData().c_str(), std::min(dataSizeIn, dataSizeOut)); + } + + CTimer::get("XIOS get variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + /*! \brief This group of functions write information into existing variable in the configuration file (.xml) + * + * These functions provide intermediate C interfaces to get variable information of the configuration file (e.x iodef.xml), + * from a Fortran one, for example the value of a variable with id = "using_server". + * Each function corresponds to each basic type. + * \param varId [in] id of the variable that we'd like to get + * \param varIdSize [in] size of the variable type (integer, float, double, string) + * \param data [in] the input data + * \param isVarExisted [in/out] Verify whether variable with varId exists + */ + void cxios_set_variable_data_k8(const char * varId, int varIdSize, double data, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS set variable data").resume(); + + CContext* context = CContext::getCurrent() ; + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + CVariable::get(context->getId(),varIdStr)->setData(data); + CVariable::get(context->getId(),varIdStr)->sendValue(); + } + + CTimer::get("XIOS set variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_set_variable_data_k4(const char * varId, int varIdSize, float data, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS set variable data").resume(); + + CContext* context = CContext::getCurrent() ; + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + CVariable::get(context->getId(),varIdStr)->setData(data); + CVariable::get(context->getId(),varIdStr)->sendValue(); + } + + CTimer::get("XIOS set variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_set_variable_data_int(const char * varId, int varIdSize, int data, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS set variable data").resume(); + + CContext* context = CContext::getCurrent() ; + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + CVariable::get(context->getId(),varIdStr)->setData(data); + CVariable::get(context->getId(),varIdStr)->sendValue(); + } + + + CTimer::get("XIOS set variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_set_variable_data_logic(const char * varId, int varIdSize, bool data, bool * isVarExisted) + { + std::string varIdStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS set variable data").resume(); + + CContext* context = CContext::getCurrent() ; + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + CVariable::get(context->getId(),varIdStr)->setData(data); + CVariable::get(context->getId(),varIdStr)->sendValue(); + } + + CTimer::get("XIOS set variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_set_variable_data_char(const char * varId, int varIdSize, const char * data, int dataSizeIn, bool * isVarExisted) + { + std::string varIdStr, dataStr; + if (!cstr2string(varId, varIdSize, varIdStr)) return; + if (!cstr2string(data, dataSizeIn, dataStr)) + { + *isVarExisted = false; + return; + } + + CTimer::get("XIOS").resume(); + CTimer::get("XIOS set variable data").resume(); + + CContext* context = CContext::getCurrent() ; + *isVarExisted = CVariable::has(context->getId(), varIdStr); + + if (*isVarExisted) + { + CVariable::get(context->getId(),varIdStr)->setData(dataStr); + CVariable::get(context->getId(),varIdStr)->sendValue(); + } + + CTimer::get("XIOS set variable data").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + + // ---------------------- Ecriture des données ------------------------------ + + void cxios_write_data_k81(const char * fieldid, int fieldid_size, double * data_k8, int data_Xsize) + { + std::string fieldid_str; + if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return; + + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS send field").resume() ; + CContext* context = CContext::getCurrent() ; + if (!context->hasServer) context->client->checkBuffers() ; + CArray data(data_k8,shape(data_Xsize),neverDeleteData) ; + CField::get(fieldid_str)->setData(data) ; + CTimer::get("XIOS send field").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_write_data_k82(const char * fieldid, int fieldid_size, double * data_k8, int data_Xsize, int data_Ysize) + { + std::string fieldid_str; + if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return; + + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS send field").resume() ; + CContext* context = CContext::getCurrent() ; + if (!context->hasServer) context->client->checkBuffers() ; + + CArraydata(data_k8,shape(data_Xsize,data_Ysize),neverDeleteData) ; + CField::get(fieldid_str)->setData(data) ; + CTimer::get("XIOS send field").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_write_data_k83(const char * fieldid, int fieldid_size, double * data_k8, int data_Xsize, int data_Ysize, int data_Zsize) + { + std::string fieldid_str; + if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return; + + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS send field").resume() ; + CContext* context = CContext::getCurrent() ; + if (!context->hasServer) context->client->checkBuffers() ; + + CArraydata(data_k8,shape(data_Xsize,data_Ysize,data_Zsize),neverDeleteData) ; + CField::get(fieldid_str)->setData(data) ; + CTimer::get("XIOS send field").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_write_data_k41(const char * fieldid, int fieldid_size, float * data_k4, int data_Xsize) + { + std::string fieldid_str; + if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return; + + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS send field").resume() ; + CContext* context = CContext::getCurrent() ; + if (!context->hasServer) context->client->checkBuffers() ; + + CArray data_tmp(data_k4,shape(data_Xsize),neverDeleteData) ; + CArray data(data_Xsize) ; + data=data_tmp ; + CField::get(fieldid_str)->setData(data) ; + CTimer::get("XIOS send field").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_write_data_k42(const char * fieldid, int fieldid_size, float * data_k4, int data_Xsize, int data_Ysize) + { + std::string fieldid_str; + if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return; + + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS send field").resume() ; + CContext* context = CContext::getCurrent() ; + if (!context->hasServer) context->client->checkBuffers() ; + + CArray data_tmp(data_k4,shape(data_Xsize,data_Ysize),neverDeleteData) ; + CArray data(data_Xsize,data_Ysize) ; + data=data_tmp ; + CField::get(fieldid_str)->setData(data) ; + CTimer::get("XIOS send field").suspend() ; + CTimer::get("XIOS").suspend() ; + } + + void cxios_write_data_k43(const char * fieldid, int fieldid_size, float * data_k4, int data_Xsize, int data_Ysize, int data_Zsize) + { + std::string fieldid_str; + + if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return; + + CTimer::get("XIOS").resume() ; + CTimer::get("XIOS send field").resume() ; + CContext* context = CContext::getCurrent() ; + if (!context->hasServer) context->client->checkBuffers() ; + + CArray data_tmp(data_k4,shape(data_Xsize,data_Ysize,data_Zsize),neverDeleteData) ; + CArray data(data_Xsize,data_Ysize,data_Zsize) ; + data=data_tmp ; + + CField::get(fieldid_str)->setData(data) ; + CTimer::get("XIOS send field").suspend() ; + CTimer::get("XIOS").suspend() ; + + } + +} // extern "C" diff --git a/src/interface/c/icdate.cpp b/src/interface/c/icdate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4521f649b6bb53b332f9862cce954fa30d572d0 --- /dev/null +++ b/src/interface/c/icdate.cpp @@ -0,0 +1,56 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "calendar_type.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "context.hpp" +#include "context_client.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + void cxios_set_timestep(double ts_year, double ts_month, double ts_day, + double ts_hour, double ts_minute, double ts_second) + { + try + { + CTimer::get("XIOS").resume() ; + CDuration dur = {ts_year, ts_month, ts_day, ts_hour, ts_minute, ts_second, 0}; + xios::CContext* context = CContext::getCurrent() ; + + context->timestep.setValue(dur.toString()); + context->sendAttributToServer("timestep") ; + CTimer::get("XIOS").suspend() ; + } + catch (xios::CException & exc) + { + std::cerr << exc.getMessage() << std::endl; + exit (EXIT_FAILURE); + } + } + + void cxios_update_calendar(int step) + { + CTimer::get("XIOS").resume() ; + xios::CContext* context = CContext::getCurrent() ; + if (!context->hasServer) context->client->checkBuffers() ; + context->updateCalendar(step) ; + context->sendUpdateCalendar(step) ; + CTimer::get("XIOS").suspend() ; + + } + +} // extern "C" diff --git a/src/interface/c/icdomain.cpp b/src/interface/c/icdomain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..127e6bdfd4841a6baf5cb76c55610244aade626b --- /dev/null +++ b/src/interface/c/icdomain.cpp @@ -0,0 +1,68 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "domain.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef xios::CDomain * XDomainPtr; + typedef xios::CDomainGroup * XDomainGroupPtr; + + // ------------------------ Création des handle ----------------------------- + + void cxios_domain_handle_create (XDomainPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CDomain::get(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_domaingroup_handle_create (XDomainGroupPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + + CTimer::get("XIOS").resume() ; + *_ret = CDomainGroup::get(id); + CTimer::get("XIOS").suspend() ; + } + + // -------------------- Vérification des identifiants ----------------------- + + void cxios_domain_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + + CTimer::get("XIOS").resume() ; + *_ret = CDomain::has(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_domaingroup_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CDomainGroup::has(id); + CTimer::get("XIOS").suspend() ; + } +} // extern "C" diff --git a/src/interface/c/icfield.cpp b/src/interface/c/icfield.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eed52513e2ab58773cf6b59bd022a38e9e4b4614 --- /dev/null +++ b/src/interface/c/icfield.cpp @@ -0,0 +1,81 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "field.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef xios::CField * XFieldPtr; + typedef xios::CFieldGroup * XFieldGroupPtr; + +// -------------------------------------------------------------------------- +// ------------------------ Création des handle ----------------------------- +// -------------------------------------------------------------------------- + + void cxios_field_handle_create (XFieldPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CField::get(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_fieldgroup_handle_create (XFieldGroupPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CFieldGroup::get(id); + CTimer::get("XIOS").suspend() ; + } + + + // -------------------- Vérification des identifiants ----------------------- + + void cxios_field_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CField::has(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_fieldgroup_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CFieldGroup::has(id); + CTimer::get("XIOS").suspend() ; + } + +// ----------------------------------------------------------------------------------------------------- +// ------------------------- other function---------- --------------------------- --------------------- +// ----------------------------------------------------------------------------------------------------- + + void cxios_field_is_active (XFieldPtr field_hdl, bool* ret) + { + CTimer::get("XIOS").resume() ; + *ret = field_hdl->isActive(); + CTimer::get("XIOS").suspend() ; + } + +} // extern "C" diff --git a/src/interface/c/icfile.cpp b/src/interface/c/icfile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe57090f81baa19580fdd4388f8afb058faf348b --- /dev/null +++ b/src/interface/c/icfile.cpp @@ -0,0 +1,66 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "file.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef xios::CFile * XFilePtr; + typedef xios::CFileGroup * XFileGroupPtr; + + // ------------------------ Création des handle ----------------------------- + + void cxios_file_handle_create (XFilePtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CFile::get(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_filegroup_handle_create (XFileGroupPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CFileGroup::get(id); + CTimer::get("XIOS").suspend() ; + } + + // -------------------- Vérification des identifiants ----------------------- + + void cxios_file_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CFile::has(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_filegroup_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CFileGroup::has(id); + CTimer::get("XIOS").suspend() ; + } +} // extern "C" diff --git a/src/interface/c/icgrid.cpp b/src/interface/c/icgrid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad1b642c5df11060f58a4761f7fba42aca1f5cf0 --- /dev/null +++ b/src/interface/c/icgrid.cpp @@ -0,0 +1,66 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "grid.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef xios::CGrid * XGridPtr; + typedef xios::CGridGroup * XGridGroupPtr; + + // ------------------------ Création des handle ----------------------------- + + void cxios_grid_handle_create (XGridPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CGrid::get(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_gridgroup_handle_create (XGridGroupPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CGridGroup::get(id); + CTimer::get("XIOS").suspend() ; + } + + // -------------------- Vérification des identifiants ----------------------- + + void cxios_grid_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CGrid::has(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_gridgroup_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = CGridGroup::has(id); + CTimer::get("XIOS").suspend() ; + } +} // extern "C" diff --git a/src/interface/c/icutil.hpp b/src/interface/c/icutil.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4a2d90124981844309817dbccd6deae7a648489e --- /dev/null +++ b/src/interface/c/icutil.hpp @@ -0,0 +1,68 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + + +#ifndef __ICUTIL_HPP__ +#define __ICUTIL_HPP__ + +#include +#include +// ///////////////////////// Définitions/Déclarations /////////////////////// // + +inline bool cstr2string(const char * cstr, int cstr_size, std::string & str) +{ + std::string valtemp; + std::size_t d, f = 0; + if (cstr_size != -1) + { + valtemp.append (cstr, cstr_size); + d = valtemp.find_first_not_of(' '); + f = valtemp.find_last_not_of (' '); + str = valtemp.substr(d, f-d+1); + return (true); + } + else + { + return (false); + } +} + +inline bool string_copy(const string& str, char* cstr,int cstr_size) +{ + + if (str.size()>cstr_size) return false ; + else + { + std::memset (cstr,' ',cstr_size); + str.copy(cstr,cstr_size) ; + return true ; + } +} +/* + template + inline bool array_copy(ARRAY(T,1) array_in, T* array_out, size_t extent1) + { + if (array_in->num_elements() != extent1) return false ; + std::copy(array_in->data(), array_in->data() + array_in->num_elements(), array_out); + return true ; + } + + template + inline bool array_copy(ARRAY(T,2) array_in, T* array_out, size_t extent1, size_t extent2) + { + if (array_in->num_elements() != extent1*extent2) return false ; + std::copy(array_in->data(), array_in->data() + array_in->num_elements(), array_out); + return true ; + } + + template + inline bool array_copy(ARRAY(T,3) array_in, T* array_out, size_t extent1, size_t extent2, size_t extent3) + { + if (array_in->num_elements() != extent1*extent2*extent3) return false ; + std::copy(array_in->data(), array_in->data() + array_in->num_elements(), array_out); + return true ; + } +*/ + +#endif // __ICUTIL_HPP__ diff --git a/src/interface/c/icvariable.cpp b/src/interface/c/icvariable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2012973a84bd56f71bde8971cd1517fa5673b0a5 --- /dev/null +++ b/src/interface/c/icvariable.cpp @@ -0,0 +1,71 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "object_template.hpp" +#include "group_template.hpp" +#include "attribute_template.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "variable.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef xios::CVariable * XVariablePtr; + typedef xios::CVariableGroup * XVariableGroupPtr; + + // ------------------------ Création des handle ----------------------------- + + void cxios_variable_handle_create (XVariablePtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = xios::CVariable::get(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_variablegroup_handle_create (XVariableGroupPtr * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + CTimer::get("XIOS").resume() ; + *_ret = xios::CVariableGroup::get(id); + CTimer::get("XIOS").suspend() ; + } + + // -------------------- Vérification des identifiants ----------------------- + + void cxios_variable_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + + CTimer::get("XIOS").resume() ; + *_ret = xios::CVariable::has(id); + CTimer::get("XIOS").suspend() ; + } + + void cxios_variablegroup_valid_id (bool * _ret, const char * _id, int _id_len) + { + std::string id; + if (!cstr2string(_id, _id_len, id)) return; + + CTimer::get("XIOS").resume() ; + *_ret = xios::CVariableGroup::has(id); + CTimer::get("XIOS").suspend() ; + + } + +} // extern "C" + diff --git a/src/interface/c/icxml_tree.cpp b/src/interface/c/icxml_tree.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7424ddc4696ef66e414701c28e2539fcf1c5155e --- /dev/null +++ b/src/interface/c/icxml_tree.cpp @@ -0,0 +1,401 @@ +/* ************************************************************************** * + * Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011 * + * ************************************************************************** */ + +#include +#include + +#include "xmlioserver.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "icutil.hpp" +#include "timer.hpp" +#include "context.hpp" +#include "grid.hpp" +#include "file.hpp" +#include "field.hpp" +#include "axis.hpp" +#include "domain.hpp" +#include "variable.hpp" + +extern "C" +{ +// /////////////////////////////// Définitions ////////////////////////////// // + + // ----------------------- Redéfinition de types ---------------------------- + + typedef xios::CContext * XContextPtr; + + typedef xios::CGrid * XGridPtr; + typedef xios::CGridGroup * XGridGroupPtr; + + typedef xios::CFile * XFilePtr; + typedef xios::CFileGroup * XFileGroupPtr; + + typedef xios::CField * XFieldPtr; + typedef xios::CFieldGroup * XFieldGroupPtr; + + typedef xios::CDomain * XDomainPtr; + typedef xios::CDomainGroup * XDomainGroupPtr; + + typedef xios::CAxis * XAxisPtr; + typedef xios::CAxisGroup * XAxisGroupPtr; + + typedef xios::CVariable * XVariablePtr; + typedef xios::CVariableGroup * XVariableGroupPtr; + + // ----------------------- Ajout d'enfant à un parent ----------------------- + + void cxios_xml_tree_add_field + (XFieldGroupPtr parent_, XFieldPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChild(child_id_str) ; + parent_->sendCreateChild(child_id_str) ; + } + else + { + *child_ = parent_->createChild() ; + parent_->sendCreateChild() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_grid + (XGridGroupPtr parent_, XGridPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChild(child_id_str) ; + parent_->sendCreateChild(child_id_str) ; + } + else + { + *child_ = parent_->createChild() ; + parent_->sendCreateChild() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_file + (XFileGroupPtr parent_, XFilePtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChild(child_id_str) ; + parent_->sendCreateChild(child_id_str) ; + } + else + { + *child_ = parent_->createChild() ; + parent_->sendCreateChild() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_axis + (XAxisGroupPtr parent_, XAxisPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChild(child_id_str) ; + parent_->sendCreateChild(child_id_str) ; + } + else + { + *child_ = parent_->createChild() ; + parent_->sendCreateChild() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_domain + (XDomainGroupPtr parent_, XDomainPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChild(child_id_str) ; + parent_->sendCreateChild(child_id_str) ; + } + else + { + *child_ = parent_->createChild() ; + parent_->sendCreateChild() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_fieldtofile + (XFilePtr parent_, XFieldPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->addField(child_id_str); + parent_->sendAddField(child_id_str) ; + } + else + { + *child_ = parent_->addField(); + parent_->sendAddField() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_variabletofile + (XFilePtr parent_, XVariablePtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->addVariable(child_id_str); + parent_->sendAddVariable(child_id_str) ; + } + else + { + *child_ = parent_->addVariable(); + parent_->sendAddVariable() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_variabletofield + (XFieldPtr parent_, XVariablePtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->addVariable(child_id_str); + parent_->sendAddVariable(child_id_str) ; + } + else + { + *child_ = parent_->addVariable(); + parent_->sendAddVariable() ; + } + CTimer::get("XIOS").suspend() ; + } + // ----------------------- Ajout de groupe à un parent ---------------------- + + void cxios_xml_tree_add_fieldgroup + (XFieldGroupPtr parent_, XFieldGroupPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChildGroup(child_id_str) ; + parent_->sendCreateChildGroup(child_id_str) ; + } + else + { + *child_ = parent_->createChildGroup() ; + parent_->sendCreateChildGroup(child_id_str) ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_gridgroup + (XGridGroupPtr parent_, XGridGroupPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChildGroup(child_id_str) ; + parent_->sendCreateChildGroup(child_id_str) ; + } + else + { + *child_ = parent_->createChildGroup() ; + parent_->sendCreateChildGroup(child_id_str) ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_filegroup + (XFileGroupPtr parent_, XFileGroupPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChildGroup(child_id_str) ; + parent_->sendCreateChildGroup(child_id_str) ; + } + else + { + *child_ = parent_->createChildGroup() ; + parent_->sendCreateChildGroup(child_id_str) ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_axisgroup + (XAxisGroupPtr parent_, XAxisGroupPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChildGroup(child_id_str) ; + parent_->sendCreateChildGroup(child_id_str) ; + } + else + { + *child_ = parent_->createChildGroup() ; + parent_->sendCreateChildGroup(child_id_str) ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_domaingroup + (XDomainGroupPtr parent_, XDomainGroupPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->createChildGroup(child_id_str) ; + parent_->sendCreateChildGroup(child_id_str) ; + } + else + { + *child_ = parent_->createChildGroup() ; + parent_->sendCreateChildGroup(child_id_str) ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_fieldgrouptofile + (XFilePtr parent_, XFieldGroupPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->addFieldGroup(child_id_str); + parent_->sendAddFieldGroup(child_id_str) ; + } + else + { + *child_ = parent_->addFieldGroup(); + parent_->sendAddFieldGroup() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_variablegrouptofile + (XFilePtr parent_, XVariableGroupPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->addVariableGroup(child_id_str); + parent_->sendAddVariableGroup(child_id_str) ; + } + else + { + *child_ = parent_->addVariableGroup(); + parent_->sendAddVariableGroup() ; + } + CTimer::get("XIOS").suspend() ; + } + + void cxios_xml_tree_add_variablegrouptofield + (XFieldPtr parent_, XVariableGroupPtr * child_, const char * child_id, int child_id_size) + { + std::string child_id_str; + CTimer::get("XIOS").resume() ; + if (cstr2string(child_id, child_id_size, child_id_str)) + { + *child_ = parent_->addVariableGroup(child_id_str); + parent_->sendAddVariableGroup(child_id_str) ; + } + else + { + *child_ = parent_->addVariableGroup(); + parent_->sendAddVariableGroup() ; + } + CTimer::get("XIOS").suspend() ; + } + + + // ----------------------- Affichage de l'arborescence ---------------------- + +// void cxios_xml_tree_show (const char * filename, int filename_size) +// { +// std::string filename_str; +// try +// { +// if (cstr2string(filename, filename_size, filename_str)) +// xios::CTreeManager::PrintTreeToFile(filename_str); +// else +// xios::CTreeManager::PrintTreeToStream(std::clog); +// } +// catch (xios::CException & exc) +// { +// std::cerr << exc.getMessage() << std::endl; +// exit (EXIT_FAILURE); +// } +// } + + + // ----------------------- Parsing de document xml -------------------------- + +// void cxios_xml_parse_file (const char * filename , int filename_size)// +// { +// std::string filename_str; +// if (!cstr2string(filename, filename_size, filename_str)) return; +// +// try +// { +// xios::CTreeManager::ParseFile(filename_str); +// } +// catch (xios::CException & exc) +// { +// std::cerr << exc.getMessage() << std::endl; +// exit (EXIT_FAILURE); +// } +// } + +// void cxios_xml_parse_string(const char * xmlcontent, int xmlcontent_size) +// { +// std::string xmlcontent_str; +// if (!cstr2string(xmlcontent, xmlcontent_size, xmlcontent_str)) return; +// +// try +// { +// xios::CTreeManager::ParseString(xmlcontent_str); +// } +// catch (xios::CException & exc) +// { +// std::cerr << exc.getMessage() << std::endl; +// exit (EXIT_FAILURE); +// } +// } + + + +} // extern "C" diff --git a/src/interface/c/oasis_cinterface.cpp b/src/interface/c/oasis_cinterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..61c9aa586b3da8823d3094dfc13a39b60e41a804 --- /dev/null +++ b/src/interface/c/oasis_cinterface.cpp @@ -0,0 +1,46 @@ +#include "oasis_cinterface.hpp" +#include +#include "mpi.hpp" + +namespace xios +{ + + void oasis_init(const std::string& server_id) + { + fxios_oasis_init(server_id.data(),server_id.size()) ; + } + + void oasis_finalize(void) + { + fxios_oasis_finalize() ; + } + + void oasis_enddef(void) + { + fxios_oasis_enddef() ; + } + + void oasis_get_localcomm(MPI_Comm& comm) + { + MPI_Fint f_comm ; + + fxios_oasis_get_localcomm(&f_comm) ; + comm=MPI_Comm_f2c(f_comm) ; + } + + void oasis_get_intracomm(MPI_Comm& comm_client_server,const std::string& server_id) + { + MPI_Fint f_comm ; + + fxios_oasis_get_intracomm(&f_comm,server_id.data(),server_id.size()) ; + comm_client_server=MPI_Comm_f2c(f_comm) ; + } + + void oasis_get_intercomm(MPI_Comm& comm_client_server,const std::string& server_id) + { + MPI_Fint f_comm ; + + fxios_oasis_get_intercomm(&f_comm,server_id.data(),server_id.size()) ; + comm_client_server=MPI_Comm_f2c(f_comm) ; + } +} diff --git a/src/interface/c/oasis_cinterface.hpp b/src/interface/c/oasis_cinterface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6cff58b32742d08663a1f6bd6681098ca323bfae --- /dev/null +++ b/src/interface/c/oasis_cinterface.hpp @@ -0,0 +1,26 @@ +#ifndef __OASIS_CINTERFACE__ +#define __OASIS_CINTERFACE__ +#include +#include "mpi.hpp" + +extern "C" +{ + + void fxios_oasis_init(const char* server_id,int str_len) ; + void fxios_oasis_enddef(void) ; + void fxios_oasis_finalize(void) ; + void fxios_oasis_get_localcomm(MPI_Fint* f_comm) ; + void fxios_oasis_get_intracomm(MPI_Fint* f_comm_client_server,const char* client_id,int str_len) ; + void fxios_oasis_get_intercomm(MPI_Fint* f_comm_client_server,const char* client_id,int str_len) ; +} + +namespace xios +{ + void oasis_init(const std::string& server_id) ; + void oasis_enddef(void) ; + void oasis_finalize(void) ; + void oasis_get_localcomm(MPI_Comm& comm) ; + void oasis_get_intracomm(MPI_Comm& comm_client_server,const std::string& server_id) ; + void oasis_get_intercomm(MPI_Comm& comm_client_server,const std::string& server_id) ; +} +#endif diff --git a/src/interface/c_attr/icaxis_attr.cpp b/src/interface/c_attr/icaxis_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e96f665eda25f3db638e0bb913ef83ddd3fec51c --- /dev/null +++ b/src/interface/c_attr/icaxis_attr.cpp @@ -0,0 +1,279 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CAxis* axis_Ptr; + + void cxios_set_axis_long_name(axis_Ptr axis_hdl, const char * long_name, int long_name_size) + { + std::string long_name_str; + if(!cstr2string(long_name, long_name_size, long_name_str)) return; + CTimer::get("XIOS").resume(); + axis_hdl->long_name.setValue(long_name_str); + axis_hdl->sendAttributToServer(axis_hdl->long_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_long_name(axis_Ptr axis_hdl, char * long_name, int long_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axis_hdl->long_name.getInheritedValue(),long_name , long_name_size)) + ERROR("void cxios_get_axis_long_name(axis_Ptr axis_hdl, char * long_name, int long_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axis_long_name(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->long_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_name(axis_Ptr axis_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + axis_hdl->name.setValue(name_str); + axis_hdl->sendAttributToServer(axis_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_name(axis_Ptr axis_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axis_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_axis_name(axis_Ptr axis_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axis_name(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_positive(axis_Ptr axis_hdl, const char * positive, int positive_size) + { + std::string positive_str; + if(!cstr2string(positive, positive_size, positive_str)) return; + CTimer::get("XIOS").resume(); + axis_hdl->positive.fromString(positive_str); + axis_hdl->sendAttributToServer(axis_hdl->positive); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_positive(axis_Ptr axis_hdl, char * positive, int positive_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axis_hdl->positive.getInheritedStringValue(),positive , positive_size)) + ERROR("void cxios_get_axis_positive(axis_Ptr axis_hdl, char * positive, int positive_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axis_positive(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->positive.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_size(axis_Ptr axis_hdl, int size) + { + CTimer::get("XIOS").resume(); + axis_hdl->size.setValue(size); + axis_hdl->sendAttributToServer(axis_hdl->size); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_size(axis_Ptr axis_hdl, int* size) + { + *size = axis_hdl->size.getInheritedValue(); + } + + bool cxios_is_defined_axis_size(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->size.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_standard_name(axis_Ptr axis_hdl, const char * standard_name, int standard_name_size) + { + std::string standard_name_str; + if(!cstr2string(standard_name, standard_name_size, standard_name_str)) return; + CTimer::get("XIOS").resume(); + axis_hdl->standard_name.setValue(standard_name_str); + axis_hdl->sendAttributToServer(axis_hdl->standard_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_standard_name(axis_Ptr axis_hdl, char * standard_name, int standard_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axis_hdl->standard_name.getInheritedValue(),standard_name , standard_name_size)) + ERROR("void cxios_get_axis_standard_name(axis_Ptr axis_hdl, char * standard_name, int standard_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axis_standard_name(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->standard_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_unit(axis_Ptr axis_hdl, const char * unit, int unit_size) + { + std::string unit_str; + if(!cstr2string(unit, unit_size, unit_str)) return; + CTimer::get("XIOS").resume(); + axis_hdl->unit.setValue(unit_str); + axis_hdl->sendAttributToServer(axis_hdl->unit); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_unit(axis_Ptr axis_hdl, char * unit, int unit_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axis_hdl->unit.getInheritedValue(),unit , unit_size)) + ERROR("void cxios_get_axis_unit(axis_Ptr axis_hdl, char * unit, int unit_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axis_unit(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->unit.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_value(axis_Ptr axis_hdl, double* value, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(value,shape(extent1),neverDeleteData) ; + axis_hdl->value.reference(tmp.copy()); + axis_hdl->sendAttributToServer(axis_hdl->value); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_value(axis_Ptr axis_hdl, double* value, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(value,shape(extent1),neverDeleteData) ; + tmp=axis_hdl->value.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axis_value(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->value.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_zoom_begin(axis_Ptr axis_hdl, int zoom_begin) + { + CTimer::get("XIOS").resume(); + axis_hdl->zoom_begin.setValue(zoom_begin); + axis_hdl->sendAttributToServer(axis_hdl->zoom_begin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_zoom_begin(axis_Ptr axis_hdl, int* zoom_begin) + { + *zoom_begin = axis_hdl->zoom_begin.getInheritedValue(); + } + + bool cxios_is_defined_axis_zoom_begin(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->zoom_begin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_zoom_end(axis_Ptr axis_hdl, int zoom_end) + { + CTimer::get("XIOS").resume(); + axis_hdl->zoom_end.setValue(zoom_end); + axis_hdl->sendAttributToServer(axis_hdl->zoom_end); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_zoom_end(axis_Ptr axis_hdl, int* zoom_end) + { + *zoom_end = axis_hdl->zoom_end.getInheritedValue(); + } + + bool cxios_is_defined_axis_zoom_end(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->zoom_end.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axis_zoom_size(axis_Ptr axis_hdl, int zoom_size) + { + CTimer::get("XIOS").resume(); + axis_hdl->zoom_size.setValue(zoom_size); + axis_hdl->sendAttributToServer(axis_hdl->zoom_size); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axis_zoom_size(axis_Ptr axis_hdl, int* zoom_size) + { + *zoom_size = axis_hdl->zoom_size.getInheritedValue(); + } + + bool cxios_is_defined_axis_zoom_size(axis_Ptr axis_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axis_hdl->zoom_size.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icaxisgroup_attr.cpp b/src/interface/c_attr/icaxisgroup_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f255ca9ab0c46a016b0d8fdfc0d94a470e97a18a --- /dev/null +++ b/src/interface/c_attr/icaxisgroup_attr.cpp @@ -0,0 +1,307 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CAxisGroup* axisgroup_Ptr; + + void cxios_set_axisgroup_group_ref(axisgroup_Ptr axisgroup_hdl, const char * group_ref, int group_ref_size) + { + std::string group_ref_str; + if(!cstr2string(group_ref, group_ref_size, group_ref_str)) return; + CTimer::get("XIOS").resume(); + axisgroup_hdl->group_ref.setValue(group_ref_str); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->group_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_group_ref(axisgroup_Ptr axisgroup_hdl, char * group_ref, int group_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axisgroup_hdl->group_ref.getInheritedValue(),group_ref , group_ref_size)) + ERROR("void cxios_get_axisgroup_group_ref(axisgroup_Ptr axisgroup_hdl, char * group_ref, int group_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axisgroup_group_ref(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->group_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_long_name(axisgroup_Ptr axisgroup_hdl, const char * long_name, int long_name_size) + { + std::string long_name_str; + if(!cstr2string(long_name, long_name_size, long_name_str)) return; + CTimer::get("XIOS").resume(); + axisgroup_hdl->long_name.setValue(long_name_str); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->long_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_long_name(axisgroup_Ptr axisgroup_hdl, char * long_name, int long_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axisgroup_hdl->long_name.getInheritedValue(),long_name , long_name_size)) + ERROR("void cxios_get_axisgroup_long_name(axisgroup_Ptr axisgroup_hdl, char * long_name, int long_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axisgroup_long_name(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->long_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_name(axisgroup_Ptr axisgroup_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + axisgroup_hdl->name.setValue(name_str); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_name(axisgroup_Ptr axisgroup_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axisgroup_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_axisgroup_name(axisgroup_Ptr axisgroup_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axisgroup_name(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_positive(axisgroup_Ptr axisgroup_hdl, const char * positive, int positive_size) + { + std::string positive_str; + if(!cstr2string(positive, positive_size, positive_str)) return; + CTimer::get("XIOS").resume(); + axisgroup_hdl->positive.fromString(positive_str); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->positive); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_positive(axisgroup_Ptr axisgroup_hdl, char * positive, int positive_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axisgroup_hdl->positive.getInheritedStringValue(),positive , positive_size)) + ERROR("void cxios_get_axisgroup_positive(axisgroup_Ptr axisgroup_hdl, char * positive, int positive_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axisgroup_positive(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->positive.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_size(axisgroup_Ptr axisgroup_hdl, int size) + { + CTimer::get("XIOS").resume(); + axisgroup_hdl->size.setValue(size); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->size); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_size(axisgroup_Ptr axisgroup_hdl, int* size) + { + *size = axisgroup_hdl->size.getInheritedValue(); + } + + bool cxios_is_defined_axisgroup_size(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->size.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_standard_name(axisgroup_Ptr axisgroup_hdl, const char * standard_name, int standard_name_size) + { + std::string standard_name_str; + if(!cstr2string(standard_name, standard_name_size, standard_name_str)) return; + CTimer::get("XIOS").resume(); + axisgroup_hdl->standard_name.setValue(standard_name_str); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->standard_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_standard_name(axisgroup_Ptr axisgroup_hdl, char * standard_name, int standard_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axisgroup_hdl->standard_name.getInheritedValue(),standard_name , standard_name_size)) + ERROR("void cxios_get_axisgroup_standard_name(axisgroup_Ptr axisgroup_hdl, char * standard_name, int standard_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axisgroup_standard_name(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->standard_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_unit(axisgroup_Ptr axisgroup_hdl, const char * unit, int unit_size) + { + std::string unit_str; + if(!cstr2string(unit, unit_size, unit_str)) return; + CTimer::get("XIOS").resume(); + axisgroup_hdl->unit.setValue(unit_str); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->unit); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_unit(axisgroup_Ptr axisgroup_hdl, char * unit, int unit_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(axisgroup_hdl->unit.getInheritedValue(),unit , unit_size)) + ERROR("void cxios_get_axisgroup_unit(axisgroup_Ptr axisgroup_hdl, char * unit, int unit_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axisgroup_unit(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->unit.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_value(axisgroup_Ptr axisgroup_hdl, double* value, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(value,shape(extent1),neverDeleteData) ; + axisgroup_hdl->value.reference(tmp.copy()); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->value); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_value(axisgroup_Ptr axisgroup_hdl, double* value, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(value,shape(extent1),neverDeleteData) ; + tmp=axisgroup_hdl->value.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_axisgroup_value(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->value.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_zoom_begin(axisgroup_Ptr axisgroup_hdl, int zoom_begin) + { + CTimer::get("XIOS").resume(); + axisgroup_hdl->zoom_begin.setValue(zoom_begin); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->zoom_begin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_zoom_begin(axisgroup_Ptr axisgroup_hdl, int* zoom_begin) + { + *zoom_begin = axisgroup_hdl->zoom_begin.getInheritedValue(); + } + + bool cxios_is_defined_axisgroup_zoom_begin(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->zoom_begin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_zoom_end(axisgroup_Ptr axisgroup_hdl, int zoom_end) + { + CTimer::get("XIOS").resume(); + axisgroup_hdl->zoom_end.setValue(zoom_end); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->zoom_end); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_zoom_end(axisgroup_Ptr axisgroup_hdl, int* zoom_end) + { + *zoom_end = axisgroup_hdl->zoom_end.getInheritedValue(); + } + + bool cxios_is_defined_axisgroup_zoom_end(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->zoom_end.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_axisgroup_zoom_size(axisgroup_Ptr axisgroup_hdl, int zoom_size) + { + CTimer::get("XIOS").resume(); + axisgroup_hdl->zoom_size.setValue(zoom_size); + axisgroup_hdl->sendAttributToServer(axisgroup_hdl->zoom_size); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_axisgroup_zoom_size(axisgroup_Ptr axisgroup_hdl, int* zoom_size) + { + *zoom_size = axisgroup_hdl->zoom_size.getInheritedValue(); + } + + bool cxios_is_defined_axisgroup_zoom_size(axisgroup_Ptr axisgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = axisgroup_hdl->zoom_size.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/iccontext_attr.cpp b/src/interface/c_attr/iccontext_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6bfc4a2e7ff35a5532a07824c03111e8ac793fdd --- /dev/null +++ b/src/interface/c_attr/iccontext_attr.cpp @@ -0,0 +1,160 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CContext* context_Ptr; + + void cxios_set_context_calendar_type(context_Ptr context_hdl, const char * calendar_type, int calendar_type_size) + { + std::string calendar_type_str; + if(!cstr2string(calendar_type, calendar_type_size, calendar_type_str)) return; + CTimer::get("XIOS").resume(); + context_hdl->calendar_type.setValue(calendar_type_str); + context_hdl->sendAttributToServer(context_hdl->calendar_type); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_context_calendar_type(context_Ptr context_hdl, char * calendar_type, int calendar_type_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(context_hdl->calendar_type.getInheritedValue(),calendar_type , calendar_type_size)) + ERROR("void cxios_get_context_calendar_type(context_Ptr context_hdl, char * calendar_type, int calendar_type_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_context_calendar_type(context_Ptr context_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = context_hdl->calendar_type.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_context_output_dir(context_Ptr context_hdl, const char * output_dir, int output_dir_size) + { + std::string output_dir_str; + if(!cstr2string(output_dir, output_dir_size, output_dir_str)) return; + CTimer::get("XIOS").resume(); + context_hdl->output_dir.setValue(output_dir_str); + context_hdl->sendAttributToServer(context_hdl->output_dir); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_context_output_dir(context_Ptr context_hdl, char * output_dir, int output_dir_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(context_hdl->output_dir.getInheritedValue(),output_dir , output_dir_size)) + ERROR("void cxios_get_context_output_dir(context_Ptr context_hdl, char * output_dir, int output_dir_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_context_output_dir(context_Ptr context_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = context_hdl->output_dir.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_context_start_date(context_Ptr context_hdl, const char * start_date, int start_date_size) + { + std::string start_date_str; + if(!cstr2string(start_date, start_date_size, start_date_str)) return; + CTimer::get("XIOS").resume(); + context_hdl->start_date.setValue(start_date_str); + context_hdl->sendAttributToServer(context_hdl->start_date); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_context_start_date(context_Ptr context_hdl, char * start_date, int start_date_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(context_hdl->start_date.getInheritedValue(),start_date , start_date_size)) + ERROR("void cxios_get_context_start_date(context_Ptr context_hdl, char * start_date, int start_date_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_context_start_date(context_Ptr context_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = context_hdl->start_date.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_context_time_origin(context_Ptr context_hdl, const char * time_origin, int time_origin_size) + { + std::string time_origin_str; + if(!cstr2string(time_origin, time_origin_size, time_origin_str)) return; + CTimer::get("XIOS").resume(); + context_hdl->time_origin.setValue(time_origin_str); + context_hdl->sendAttributToServer(context_hdl->time_origin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_context_time_origin(context_Ptr context_hdl, char * time_origin, int time_origin_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(context_hdl->time_origin.getInheritedValue(),time_origin , time_origin_size)) + ERROR("void cxios_get_context_time_origin(context_Ptr context_hdl, char * time_origin, int time_origin_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_context_time_origin(context_Ptr context_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = context_hdl->time_origin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_context_timestep(context_Ptr context_hdl, const char * timestep, int timestep_size) + { + std::string timestep_str; + if(!cstr2string(timestep, timestep_size, timestep_str)) return; + CTimer::get("XIOS").resume(); + context_hdl->timestep.setValue(timestep_str); + context_hdl->sendAttributToServer(context_hdl->timestep); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_context_timestep(context_Ptr context_hdl, char * timestep, int timestep_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(context_hdl->timestep.getInheritedValue(),timestep , timestep_size)) + ERROR("void cxios_get_context_timestep(context_Ptr context_hdl, char * timestep, int timestep_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_context_timestep(context_Ptr context_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = context_hdl->timestep.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icdomain_attr.cpp b/src/interface/c_attr/icdomain_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..76ec822f5370afd842c224869831a1f14e391334 --- /dev/null +++ b/src/interface/c_attr/icdomain_attr.cpp @@ -0,0 +1,932 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CDomain* domain_Ptr; + + void cxios_set_domain_bounds_lat(domain_Ptr domain_hdl, double* bounds_lat, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(bounds_lat,shape(extent1,extent2),neverDeleteData) ; + domain_hdl->bounds_lat.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->bounds_lat); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_bounds_lat(domain_Ptr domain_hdl, double* bounds_lat, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(bounds_lat,shape(extent1,extent2),neverDeleteData) ; + tmp=domain_hdl->bounds_lat.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_bounds_lat(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->bounds_lat.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_bounds_lon(domain_Ptr domain_hdl, double* bounds_lon, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(bounds_lon,shape(extent1,extent2),neverDeleteData) ; + domain_hdl->bounds_lon.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->bounds_lon); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_bounds_lon(domain_Ptr domain_hdl, double* bounds_lon, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(bounds_lon,shape(extent1,extent2),neverDeleteData) ; + tmp=domain_hdl->bounds_lon.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_bounds_lon(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->bounds_lon.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_data_dim(domain_Ptr domain_hdl, int data_dim) + { + CTimer::get("XIOS").resume(); + domain_hdl->data_dim.setValue(data_dim); + domain_hdl->sendAttributToServer(domain_hdl->data_dim); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_data_dim(domain_Ptr domain_hdl, int* data_dim) + { + *data_dim = domain_hdl->data_dim.getInheritedValue(); + } + + bool cxios_is_defined_domain_data_dim(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->data_dim.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_data_i_index(domain_Ptr domain_hdl, int* data_i_index, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(data_i_index,shape(extent1),neverDeleteData) ; + domain_hdl->data_i_index.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->data_i_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_data_i_index(domain_Ptr domain_hdl, int* data_i_index, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(data_i_index,shape(extent1),neverDeleteData) ; + tmp=domain_hdl->data_i_index.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_data_i_index(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->data_i_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_data_ibegin(domain_Ptr domain_hdl, int data_ibegin) + { + CTimer::get("XIOS").resume(); + domain_hdl->data_ibegin.setValue(data_ibegin); + domain_hdl->sendAttributToServer(domain_hdl->data_ibegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_data_ibegin(domain_Ptr domain_hdl, int* data_ibegin) + { + *data_ibegin = domain_hdl->data_ibegin.getInheritedValue(); + } + + bool cxios_is_defined_domain_data_ibegin(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->data_ibegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_data_j_index(domain_Ptr domain_hdl, int* data_j_index, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(data_j_index,shape(extent1),neverDeleteData) ; + domain_hdl->data_j_index.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->data_j_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_data_j_index(domain_Ptr domain_hdl, int* data_j_index, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(data_j_index,shape(extent1),neverDeleteData) ; + tmp=domain_hdl->data_j_index.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_data_j_index(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->data_j_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_data_jbegin(domain_Ptr domain_hdl, int data_jbegin) + { + CTimer::get("XIOS").resume(); + domain_hdl->data_jbegin.setValue(data_jbegin); + domain_hdl->sendAttributToServer(domain_hdl->data_jbegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_data_jbegin(domain_Ptr domain_hdl, int* data_jbegin) + { + *data_jbegin = domain_hdl->data_jbegin.getInheritedValue(); + } + + bool cxios_is_defined_domain_data_jbegin(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->data_jbegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_data_n_index(domain_Ptr domain_hdl, int data_n_index) + { + CTimer::get("XIOS").resume(); + domain_hdl->data_n_index.setValue(data_n_index); + domain_hdl->sendAttributToServer(domain_hdl->data_n_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_data_n_index(domain_Ptr domain_hdl, int* data_n_index) + { + *data_n_index = domain_hdl->data_n_index.getInheritedValue(); + } + + bool cxios_is_defined_domain_data_n_index(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->data_n_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_data_ni(domain_Ptr domain_hdl, int data_ni) + { + CTimer::get("XIOS").resume(); + domain_hdl->data_ni.setValue(data_ni); + domain_hdl->sendAttributToServer(domain_hdl->data_ni); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_data_ni(domain_Ptr domain_hdl, int* data_ni) + { + *data_ni = domain_hdl->data_ni.getInheritedValue(); + } + + bool cxios_is_defined_domain_data_ni(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->data_ni.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_data_nj(domain_Ptr domain_hdl, int data_nj) + { + CTimer::get("XIOS").resume(); + domain_hdl->data_nj.setValue(data_nj); + domain_hdl->sendAttributToServer(domain_hdl->data_nj); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_data_nj(domain_Ptr domain_hdl, int* data_nj) + { + *data_nj = domain_hdl->data_nj.getInheritedValue(); + } + + bool cxios_is_defined_domain_data_nj(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->data_nj.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_domain_group_ref(domain_Ptr domain_hdl, const char * domain_group_ref, int domain_group_ref_size) + { + std::string domain_group_ref_str; + if(!cstr2string(domain_group_ref, domain_group_ref_size, domain_group_ref_str)) return; + CTimer::get("XIOS").resume(); + domain_hdl->domain_group_ref.setValue(domain_group_ref_str); + domain_hdl->sendAttributToServer(domain_hdl->domain_group_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_domain_group_ref(domain_Ptr domain_hdl, char * domain_group_ref, int domain_group_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domain_hdl->domain_group_ref.getInheritedValue(),domain_group_ref , domain_group_ref_size)) + ERROR("void cxios_get_domain_domain_group_ref(domain_Ptr domain_hdl, char * domain_group_ref, int domain_group_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_domain_group_ref(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->domain_group_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_i_index(domain_Ptr domain_hdl, int* i_index, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(i_index,shape(extent1,extent2),neverDeleteData) ; + domain_hdl->i_index.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->i_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_i_index(domain_Ptr domain_hdl, int* i_index, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(i_index,shape(extent1,extent2),neverDeleteData) ; + tmp=domain_hdl->i_index.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_i_index(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->i_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_ibegin(domain_Ptr domain_hdl, int ibegin) + { + CTimer::get("XIOS").resume(); + domain_hdl->ibegin.setValue(ibegin); + domain_hdl->sendAttributToServer(domain_hdl->ibegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_ibegin(domain_Ptr domain_hdl, int* ibegin) + { + *ibegin = domain_hdl->ibegin.getInheritedValue(); + } + + bool cxios_is_defined_domain_ibegin(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->ibegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_iend(domain_Ptr domain_hdl, int iend) + { + CTimer::get("XIOS").resume(); + domain_hdl->iend.setValue(iend); + domain_hdl->sendAttributToServer(domain_hdl->iend); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_iend(domain_Ptr domain_hdl, int* iend) + { + *iend = domain_hdl->iend.getInheritedValue(); + } + + bool cxios_is_defined_domain_iend(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->iend.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_j_index(domain_Ptr domain_hdl, int* j_index, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(j_index,shape(extent1,extent2),neverDeleteData) ; + domain_hdl->j_index.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->j_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_j_index(domain_Ptr domain_hdl, int* j_index, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(j_index,shape(extent1,extent2),neverDeleteData) ; + tmp=domain_hdl->j_index.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_j_index(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->j_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_jbegin(domain_Ptr domain_hdl, int jbegin) + { + CTimer::get("XIOS").resume(); + domain_hdl->jbegin.setValue(jbegin); + domain_hdl->sendAttributToServer(domain_hdl->jbegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_jbegin(domain_Ptr domain_hdl, int* jbegin) + { + *jbegin = domain_hdl->jbegin.getInheritedValue(); + } + + bool cxios_is_defined_domain_jbegin(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->jbegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_jend(domain_Ptr domain_hdl, int jend) + { + CTimer::get("XIOS").resume(); + domain_hdl->jend.setValue(jend); + domain_hdl->sendAttributToServer(domain_hdl->jend); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_jend(domain_Ptr domain_hdl, int* jend) + { + *jend = domain_hdl->jend.getInheritedValue(); + } + + bool cxios_is_defined_domain_jend(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->jend.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_latvalue(domain_Ptr domain_hdl, double* latvalue, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(latvalue,shape(extent1),neverDeleteData) ; + domain_hdl->latvalue.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->latvalue); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_latvalue(domain_Ptr domain_hdl, double* latvalue, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(latvalue,shape(extent1),neverDeleteData) ; + tmp=domain_hdl->latvalue.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_latvalue(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->latvalue.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_long_name(domain_Ptr domain_hdl, const char * long_name, int long_name_size) + { + std::string long_name_str; + if(!cstr2string(long_name, long_name_size, long_name_str)) return; + CTimer::get("XIOS").resume(); + domain_hdl->long_name.setValue(long_name_str); + domain_hdl->sendAttributToServer(domain_hdl->long_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_long_name(domain_Ptr domain_hdl, char * long_name, int long_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domain_hdl->long_name.getInheritedValue(),long_name , long_name_size)) + ERROR("void cxios_get_domain_long_name(domain_Ptr domain_hdl, char * long_name, int long_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_long_name(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->long_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_lonvalue(domain_Ptr domain_hdl, double* lonvalue, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(lonvalue,shape(extent1),neverDeleteData) ; + domain_hdl->lonvalue.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->lonvalue); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_lonvalue(domain_Ptr domain_hdl, double* lonvalue, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(lonvalue,shape(extent1),neverDeleteData) ; + tmp=domain_hdl->lonvalue.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_lonvalue(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->lonvalue.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_mask(domain_Ptr domain_hdl, bool* mask, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(mask,shape(extent1,extent2),neverDeleteData) ; + domain_hdl->mask.reference(tmp.copy()); + domain_hdl->sendAttributToServer(domain_hdl->mask); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_mask(domain_Ptr domain_hdl, bool* mask, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(mask,shape(extent1,extent2),neverDeleteData) ; + tmp=domain_hdl->mask.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_mask(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->mask.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_name(domain_Ptr domain_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + domain_hdl->name.setValue(name_str); + domain_hdl->sendAttributToServer(domain_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_name(domain_Ptr domain_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domain_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_domain_name(domain_Ptr domain_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_name(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_ni(domain_Ptr domain_hdl, int ni) + { + CTimer::get("XIOS").resume(); + domain_hdl->ni.setValue(ni); + domain_hdl->sendAttributToServer(domain_hdl->ni); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_ni(domain_Ptr domain_hdl, int* ni) + { + *ni = domain_hdl->ni.getInheritedValue(); + } + + bool cxios_is_defined_domain_ni(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->ni.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_ni_glo(domain_Ptr domain_hdl, int ni_glo) + { + CTimer::get("XIOS").resume(); + domain_hdl->ni_glo.setValue(ni_glo); + domain_hdl->sendAttributToServer(domain_hdl->ni_glo); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_ni_glo(domain_Ptr domain_hdl, int* ni_glo) + { + *ni_glo = domain_hdl->ni_glo.getInheritedValue(); + } + + bool cxios_is_defined_domain_ni_glo(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->ni_glo.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_nj(domain_Ptr domain_hdl, int nj) + { + CTimer::get("XIOS").resume(); + domain_hdl->nj.setValue(nj); + domain_hdl->sendAttributToServer(domain_hdl->nj); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_nj(domain_Ptr domain_hdl, int* nj) + { + *nj = domain_hdl->nj.getInheritedValue(); + } + + bool cxios_is_defined_domain_nj(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->nj.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_nj_glo(domain_Ptr domain_hdl, int nj_glo) + { + CTimer::get("XIOS").resume(); + domain_hdl->nj_glo.setValue(nj_glo); + domain_hdl->sendAttributToServer(domain_hdl->nj_glo); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_nj_glo(domain_Ptr domain_hdl, int* nj_glo) + { + *nj_glo = domain_hdl->nj_glo.getInheritedValue(); + } + + bool cxios_is_defined_domain_nj_glo(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->nj_glo.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_nvertex(domain_Ptr domain_hdl, int nvertex) + { + CTimer::get("XIOS").resume(); + domain_hdl->nvertex.setValue(nvertex); + domain_hdl->sendAttributToServer(domain_hdl->nvertex); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_nvertex(domain_Ptr domain_hdl, int* nvertex) + { + *nvertex = domain_hdl->nvertex.getInheritedValue(); + } + + bool cxios_is_defined_domain_nvertex(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->nvertex.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_standard_name(domain_Ptr domain_hdl, const char * standard_name, int standard_name_size) + { + std::string standard_name_str; + if(!cstr2string(standard_name, standard_name_size, standard_name_str)) return; + CTimer::get("XIOS").resume(); + domain_hdl->standard_name.setValue(standard_name_str); + domain_hdl->sendAttributToServer(domain_hdl->standard_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_standard_name(domain_Ptr domain_hdl, char * standard_name, int standard_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domain_hdl->standard_name.getInheritedValue(),standard_name , standard_name_size)) + ERROR("void cxios_get_domain_standard_name(domain_Ptr domain_hdl, char * standard_name, int standard_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_standard_name(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->standard_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_type(domain_Ptr domain_hdl, const char * type, int type_size) + { + std::string type_str; + if(!cstr2string(type, type_size, type_str)) return; + CTimer::get("XIOS").resume(); + domain_hdl->type.fromString(type_str); + domain_hdl->sendAttributToServer(domain_hdl->type); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_type(domain_Ptr domain_hdl, char * type, int type_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domain_hdl->type.getInheritedStringValue(),type , type_size)) + ERROR("void cxios_get_domain_type(domain_Ptr domain_hdl, char * type, int type_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domain_type(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->type.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_zoom_ibegin(domain_Ptr domain_hdl, int zoom_ibegin) + { + CTimer::get("XIOS").resume(); + domain_hdl->zoom_ibegin.setValue(zoom_ibegin); + domain_hdl->sendAttributToServer(domain_hdl->zoom_ibegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_zoom_ibegin(domain_Ptr domain_hdl, int* zoom_ibegin) + { + *zoom_ibegin = domain_hdl->zoom_ibegin.getInheritedValue(); + } + + bool cxios_is_defined_domain_zoom_ibegin(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->zoom_ibegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_zoom_ibegin_loc(domain_Ptr domain_hdl, int zoom_ibegin_loc) + { + CTimer::get("XIOS").resume(); + domain_hdl->zoom_ibegin_loc.setValue(zoom_ibegin_loc); + domain_hdl->sendAttributToServer(domain_hdl->zoom_ibegin_loc); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_zoom_ibegin_loc(domain_Ptr domain_hdl, int* zoom_ibegin_loc) + { + *zoom_ibegin_loc = domain_hdl->zoom_ibegin_loc.getInheritedValue(); + } + + bool cxios_is_defined_domain_zoom_ibegin_loc(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->zoom_ibegin_loc.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_zoom_jbegin(domain_Ptr domain_hdl, int zoom_jbegin) + { + CTimer::get("XIOS").resume(); + domain_hdl->zoom_jbegin.setValue(zoom_jbegin); + domain_hdl->sendAttributToServer(domain_hdl->zoom_jbegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_zoom_jbegin(domain_Ptr domain_hdl, int* zoom_jbegin) + { + *zoom_jbegin = domain_hdl->zoom_jbegin.getInheritedValue(); + } + + bool cxios_is_defined_domain_zoom_jbegin(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->zoom_jbegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_zoom_jbegin_loc(domain_Ptr domain_hdl, int zoom_jbegin_loc) + { + CTimer::get("XIOS").resume(); + domain_hdl->zoom_jbegin_loc.setValue(zoom_jbegin_loc); + domain_hdl->sendAttributToServer(domain_hdl->zoom_jbegin_loc); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_zoom_jbegin_loc(domain_Ptr domain_hdl, int* zoom_jbegin_loc) + { + *zoom_jbegin_loc = domain_hdl->zoom_jbegin_loc.getInheritedValue(); + } + + bool cxios_is_defined_domain_zoom_jbegin_loc(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->zoom_jbegin_loc.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_zoom_ni(domain_Ptr domain_hdl, int zoom_ni) + { + CTimer::get("XIOS").resume(); + domain_hdl->zoom_ni.setValue(zoom_ni); + domain_hdl->sendAttributToServer(domain_hdl->zoom_ni); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_zoom_ni(domain_Ptr domain_hdl, int* zoom_ni) + { + *zoom_ni = domain_hdl->zoom_ni.getInheritedValue(); + } + + bool cxios_is_defined_domain_zoom_ni(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->zoom_ni.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_zoom_ni_loc(domain_Ptr domain_hdl, int zoom_ni_loc) + { + CTimer::get("XIOS").resume(); + domain_hdl->zoom_ni_loc.setValue(zoom_ni_loc); + domain_hdl->sendAttributToServer(domain_hdl->zoom_ni_loc); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_zoom_ni_loc(domain_Ptr domain_hdl, int* zoom_ni_loc) + { + *zoom_ni_loc = domain_hdl->zoom_ni_loc.getInheritedValue(); + } + + bool cxios_is_defined_domain_zoom_ni_loc(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->zoom_ni_loc.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_zoom_nj(domain_Ptr domain_hdl, int zoom_nj) + { + CTimer::get("XIOS").resume(); + domain_hdl->zoom_nj.setValue(zoom_nj); + domain_hdl->sendAttributToServer(domain_hdl->zoom_nj); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_zoom_nj(domain_Ptr domain_hdl, int* zoom_nj) + { + *zoom_nj = domain_hdl->zoom_nj.getInheritedValue(); + } + + bool cxios_is_defined_domain_zoom_nj(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->zoom_nj.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domain_zoom_nj_loc(domain_Ptr domain_hdl, int zoom_nj_loc) + { + CTimer::get("XIOS").resume(); + domain_hdl->zoom_nj_loc.setValue(zoom_nj_loc); + domain_hdl->sendAttributToServer(domain_hdl->zoom_nj_loc); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domain_zoom_nj_loc(domain_Ptr domain_hdl, int* zoom_nj_loc) + { + *zoom_nj_loc = domain_hdl->zoom_nj_loc.getInheritedValue(); + } + + bool cxios_is_defined_domain_zoom_nj_loc(domain_Ptr domain_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domain_hdl->zoom_nj_loc.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icdomaingroup_attr.cpp b/src/interface/c_attr/icdomaingroup_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bb4d46871e516155a07a369abdc13f0811429c34 --- /dev/null +++ b/src/interface/c_attr/icdomaingroup_attr.cpp @@ -0,0 +1,960 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CDomainGroup* domaingroup_Ptr; + + void cxios_set_domaingroup_bounds_lat(domaingroup_Ptr domaingroup_hdl, double* bounds_lat, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(bounds_lat,shape(extent1,extent2),neverDeleteData) ; + domaingroup_hdl->bounds_lat.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->bounds_lat); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_bounds_lat(domaingroup_Ptr domaingroup_hdl, double* bounds_lat, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(bounds_lat,shape(extent1,extent2),neverDeleteData) ; + tmp=domaingroup_hdl->bounds_lat.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_bounds_lat(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->bounds_lat.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_bounds_lon(domaingroup_Ptr domaingroup_hdl, double* bounds_lon, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(bounds_lon,shape(extent1,extent2),neverDeleteData) ; + domaingroup_hdl->bounds_lon.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->bounds_lon); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_bounds_lon(domaingroup_Ptr domaingroup_hdl, double* bounds_lon, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(bounds_lon,shape(extent1,extent2),neverDeleteData) ; + tmp=domaingroup_hdl->bounds_lon.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_bounds_lon(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->bounds_lon.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_data_dim(domaingroup_Ptr domaingroup_hdl, int data_dim) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->data_dim.setValue(data_dim); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->data_dim); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_data_dim(domaingroup_Ptr domaingroup_hdl, int* data_dim) + { + *data_dim = domaingroup_hdl->data_dim.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_data_dim(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->data_dim.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_data_i_index(domaingroup_Ptr domaingroup_hdl, int* data_i_index, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(data_i_index,shape(extent1),neverDeleteData) ; + domaingroup_hdl->data_i_index.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->data_i_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_data_i_index(domaingroup_Ptr domaingroup_hdl, int* data_i_index, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(data_i_index,shape(extent1),neverDeleteData) ; + tmp=domaingroup_hdl->data_i_index.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_data_i_index(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->data_i_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_data_ibegin(domaingroup_Ptr domaingroup_hdl, int data_ibegin) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->data_ibegin.setValue(data_ibegin); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->data_ibegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_data_ibegin(domaingroup_Ptr domaingroup_hdl, int* data_ibegin) + { + *data_ibegin = domaingroup_hdl->data_ibegin.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_data_ibegin(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->data_ibegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_data_j_index(domaingroup_Ptr domaingroup_hdl, int* data_j_index, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(data_j_index,shape(extent1),neverDeleteData) ; + domaingroup_hdl->data_j_index.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->data_j_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_data_j_index(domaingroup_Ptr domaingroup_hdl, int* data_j_index, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(data_j_index,shape(extent1),neverDeleteData) ; + tmp=domaingroup_hdl->data_j_index.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_data_j_index(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->data_j_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_data_jbegin(domaingroup_Ptr domaingroup_hdl, int data_jbegin) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->data_jbegin.setValue(data_jbegin); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->data_jbegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_data_jbegin(domaingroup_Ptr domaingroup_hdl, int* data_jbegin) + { + *data_jbegin = domaingroup_hdl->data_jbegin.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_data_jbegin(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->data_jbegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_data_n_index(domaingroup_Ptr domaingroup_hdl, int data_n_index) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->data_n_index.setValue(data_n_index); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->data_n_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_data_n_index(domaingroup_Ptr domaingroup_hdl, int* data_n_index) + { + *data_n_index = domaingroup_hdl->data_n_index.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_data_n_index(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->data_n_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_data_ni(domaingroup_Ptr domaingroup_hdl, int data_ni) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->data_ni.setValue(data_ni); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->data_ni); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_data_ni(domaingroup_Ptr domaingroup_hdl, int* data_ni) + { + *data_ni = domaingroup_hdl->data_ni.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_data_ni(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->data_ni.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_data_nj(domaingroup_Ptr domaingroup_hdl, int data_nj) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->data_nj.setValue(data_nj); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->data_nj); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_data_nj(domaingroup_Ptr domaingroup_hdl, int* data_nj) + { + *data_nj = domaingroup_hdl->data_nj.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_data_nj(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->data_nj.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_domain_group_ref(domaingroup_Ptr domaingroup_hdl, const char * domain_group_ref, int domain_group_ref_size) + { + std::string domain_group_ref_str; + if(!cstr2string(domain_group_ref, domain_group_ref_size, domain_group_ref_str)) return; + CTimer::get("XIOS").resume(); + domaingroup_hdl->domain_group_ref.setValue(domain_group_ref_str); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->domain_group_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_domain_group_ref(domaingroup_Ptr domaingroup_hdl, char * domain_group_ref, int domain_group_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domaingroup_hdl->domain_group_ref.getInheritedValue(),domain_group_ref , domain_group_ref_size)) + ERROR("void cxios_get_domaingroup_domain_group_ref(domaingroup_Ptr domaingroup_hdl, char * domain_group_ref, int domain_group_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_domain_group_ref(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->domain_group_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_group_ref(domaingroup_Ptr domaingroup_hdl, const char * group_ref, int group_ref_size) + { + std::string group_ref_str; + if(!cstr2string(group_ref, group_ref_size, group_ref_str)) return; + CTimer::get("XIOS").resume(); + domaingroup_hdl->group_ref.setValue(group_ref_str); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->group_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_group_ref(domaingroup_Ptr domaingroup_hdl, char * group_ref, int group_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domaingroup_hdl->group_ref.getInheritedValue(),group_ref , group_ref_size)) + ERROR("void cxios_get_domaingroup_group_ref(domaingroup_Ptr domaingroup_hdl, char * group_ref, int group_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_group_ref(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->group_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_i_index(domaingroup_Ptr domaingroup_hdl, int* i_index, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(i_index,shape(extent1,extent2),neverDeleteData) ; + domaingroup_hdl->i_index.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->i_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_i_index(domaingroup_Ptr domaingroup_hdl, int* i_index, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(i_index,shape(extent1,extent2),neverDeleteData) ; + tmp=domaingroup_hdl->i_index.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_i_index(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->i_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_ibegin(domaingroup_Ptr domaingroup_hdl, int ibegin) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->ibegin.setValue(ibegin); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->ibegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_ibegin(domaingroup_Ptr domaingroup_hdl, int* ibegin) + { + *ibegin = domaingroup_hdl->ibegin.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_ibegin(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->ibegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_iend(domaingroup_Ptr domaingroup_hdl, int iend) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->iend.setValue(iend); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->iend); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_iend(domaingroup_Ptr domaingroup_hdl, int* iend) + { + *iend = domaingroup_hdl->iend.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_iend(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->iend.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_j_index(domaingroup_Ptr domaingroup_hdl, int* j_index, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(j_index,shape(extent1,extent2),neverDeleteData) ; + domaingroup_hdl->j_index.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->j_index); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_j_index(domaingroup_Ptr domaingroup_hdl, int* j_index, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(j_index,shape(extent1,extent2),neverDeleteData) ; + tmp=domaingroup_hdl->j_index.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_j_index(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->j_index.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_jbegin(domaingroup_Ptr domaingroup_hdl, int jbegin) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->jbegin.setValue(jbegin); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->jbegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_jbegin(domaingroup_Ptr domaingroup_hdl, int* jbegin) + { + *jbegin = domaingroup_hdl->jbegin.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_jbegin(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->jbegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_jend(domaingroup_Ptr domaingroup_hdl, int jend) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->jend.setValue(jend); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->jend); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_jend(domaingroup_Ptr domaingroup_hdl, int* jend) + { + *jend = domaingroup_hdl->jend.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_jend(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->jend.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_latvalue(domaingroup_Ptr domaingroup_hdl, double* latvalue, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(latvalue,shape(extent1),neverDeleteData) ; + domaingroup_hdl->latvalue.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->latvalue); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_latvalue(domaingroup_Ptr domaingroup_hdl, double* latvalue, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(latvalue,shape(extent1),neverDeleteData) ; + tmp=domaingroup_hdl->latvalue.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_latvalue(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->latvalue.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_long_name(domaingroup_Ptr domaingroup_hdl, const char * long_name, int long_name_size) + { + std::string long_name_str; + if(!cstr2string(long_name, long_name_size, long_name_str)) return; + CTimer::get("XIOS").resume(); + domaingroup_hdl->long_name.setValue(long_name_str); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->long_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_long_name(domaingroup_Ptr domaingroup_hdl, char * long_name, int long_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domaingroup_hdl->long_name.getInheritedValue(),long_name , long_name_size)) + ERROR("void cxios_get_domaingroup_long_name(domaingroup_Ptr domaingroup_hdl, char * long_name, int long_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_long_name(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->long_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_lonvalue(domaingroup_Ptr domaingroup_hdl, double* lonvalue, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(lonvalue,shape(extent1),neverDeleteData) ; + domaingroup_hdl->lonvalue.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->lonvalue); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_lonvalue(domaingroup_Ptr domaingroup_hdl, double* lonvalue, int extent1) + { + CTimer::get("XIOS").resume(); + CArray tmp(lonvalue,shape(extent1),neverDeleteData) ; + tmp=domaingroup_hdl->lonvalue.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_lonvalue(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->lonvalue.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_mask(domaingroup_Ptr domaingroup_hdl, bool* mask, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(mask,shape(extent1,extent2),neverDeleteData) ; + domaingroup_hdl->mask.reference(tmp.copy()); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->mask); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_mask(domaingroup_Ptr domaingroup_hdl, bool* mask, int extent1, int extent2) + { + CTimer::get("XIOS").resume(); + CArray tmp(mask,shape(extent1,extent2),neverDeleteData) ; + tmp=domaingroup_hdl->mask.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_mask(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->mask.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_name(domaingroup_Ptr domaingroup_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + domaingroup_hdl->name.setValue(name_str); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_name(domaingroup_Ptr domaingroup_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domaingroup_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_domaingroup_name(domaingroup_Ptr domaingroup_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_name(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_ni(domaingroup_Ptr domaingroup_hdl, int ni) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->ni.setValue(ni); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->ni); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_ni(domaingroup_Ptr domaingroup_hdl, int* ni) + { + *ni = domaingroup_hdl->ni.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_ni(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->ni.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_ni_glo(domaingroup_Ptr domaingroup_hdl, int ni_glo) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->ni_glo.setValue(ni_glo); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->ni_glo); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_ni_glo(domaingroup_Ptr domaingroup_hdl, int* ni_glo) + { + *ni_glo = domaingroup_hdl->ni_glo.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_ni_glo(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->ni_glo.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_nj(domaingroup_Ptr domaingroup_hdl, int nj) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->nj.setValue(nj); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->nj); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_nj(domaingroup_Ptr domaingroup_hdl, int* nj) + { + *nj = domaingroup_hdl->nj.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_nj(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->nj.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_nj_glo(domaingroup_Ptr domaingroup_hdl, int nj_glo) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->nj_glo.setValue(nj_glo); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->nj_glo); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_nj_glo(domaingroup_Ptr domaingroup_hdl, int* nj_glo) + { + *nj_glo = domaingroup_hdl->nj_glo.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_nj_glo(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->nj_glo.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_nvertex(domaingroup_Ptr domaingroup_hdl, int nvertex) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->nvertex.setValue(nvertex); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->nvertex); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_nvertex(domaingroup_Ptr domaingroup_hdl, int* nvertex) + { + *nvertex = domaingroup_hdl->nvertex.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_nvertex(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->nvertex.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_standard_name(domaingroup_Ptr domaingroup_hdl, const char * standard_name, int standard_name_size) + { + std::string standard_name_str; + if(!cstr2string(standard_name, standard_name_size, standard_name_str)) return; + CTimer::get("XIOS").resume(); + domaingroup_hdl->standard_name.setValue(standard_name_str); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->standard_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_standard_name(domaingroup_Ptr domaingroup_hdl, char * standard_name, int standard_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domaingroup_hdl->standard_name.getInheritedValue(),standard_name , standard_name_size)) + ERROR("void cxios_get_domaingroup_standard_name(domaingroup_Ptr domaingroup_hdl, char * standard_name, int standard_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_standard_name(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->standard_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_type(domaingroup_Ptr domaingroup_hdl, const char * type, int type_size) + { + std::string type_str; + if(!cstr2string(type, type_size, type_str)) return; + CTimer::get("XIOS").resume(); + domaingroup_hdl->type.fromString(type_str); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->type); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_type(domaingroup_Ptr domaingroup_hdl, char * type, int type_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(domaingroup_hdl->type.getInheritedStringValue(),type , type_size)) + ERROR("void cxios_get_domaingroup_type(domaingroup_Ptr domaingroup_hdl, char * type, int type_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_domaingroup_type(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->type.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_zoom_ibegin(domaingroup_Ptr domaingroup_hdl, int zoom_ibegin) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->zoom_ibegin.setValue(zoom_ibegin); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->zoom_ibegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_zoom_ibegin(domaingroup_Ptr domaingroup_hdl, int* zoom_ibegin) + { + *zoom_ibegin = domaingroup_hdl->zoom_ibegin.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_zoom_ibegin(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->zoom_ibegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_zoom_ibegin_loc(domaingroup_Ptr domaingroup_hdl, int zoom_ibegin_loc) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->zoom_ibegin_loc.setValue(zoom_ibegin_loc); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->zoom_ibegin_loc); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_zoom_ibegin_loc(domaingroup_Ptr domaingroup_hdl, int* zoom_ibegin_loc) + { + *zoom_ibegin_loc = domaingroup_hdl->zoom_ibegin_loc.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_zoom_ibegin_loc(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->zoom_ibegin_loc.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_zoom_jbegin(domaingroup_Ptr domaingroup_hdl, int zoom_jbegin) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->zoom_jbegin.setValue(zoom_jbegin); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->zoom_jbegin); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_zoom_jbegin(domaingroup_Ptr domaingroup_hdl, int* zoom_jbegin) + { + *zoom_jbegin = domaingroup_hdl->zoom_jbegin.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_zoom_jbegin(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->zoom_jbegin.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_zoom_jbegin_loc(domaingroup_Ptr domaingroup_hdl, int zoom_jbegin_loc) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->zoom_jbegin_loc.setValue(zoom_jbegin_loc); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->zoom_jbegin_loc); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_zoom_jbegin_loc(domaingroup_Ptr domaingroup_hdl, int* zoom_jbegin_loc) + { + *zoom_jbegin_loc = domaingroup_hdl->zoom_jbegin_loc.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_zoom_jbegin_loc(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->zoom_jbegin_loc.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_zoom_ni(domaingroup_Ptr domaingroup_hdl, int zoom_ni) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->zoom_ni.setValue(zoom_ni); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->zoom_ni); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_zoom_ni(domaingroup_Ptr domaingroup_hdl, int* zoom_ni) + { + *zoom_ni = domaingroup_hdl->zoom_ni.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_zoom_ni(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->zoom_ni.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_zoom_ni_loc(domaingroup_Ptr domaingroup_hdl, int zoom_ni_loc) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->zoom_ni_loc.setValue(zoom_ni_loc); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->zoom_ni_loc); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_zoom_ni_loc(domaingroup_Ptr domaingroup_hdl, int* zoom_ni_loc) + { + *zoom_ni_loc = domaingroup_hdl->zoom_ni_loc.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_zoom_ni_loc(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->zoom_ni_loc.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_zoom_nj(domaingroup_Ptr domaingroup_hdl, int zoom_nj) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->zoom_nj.setValue(zoom_nj); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->zoom_nj); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_zoom_nj(domaingroup_Ptr domaingroup_hdl, int* zoom_nj) + { + *zoom_nj = domaingroup_hdl->zoom_nj.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_zoom_nj(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->zoom_nj.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_domaingroup_zoom_nj_loc(domaingroup_Ptr domaingroup_hdl, int zoom_nj_loc) + { + CTimer::get("XIOS").resume(); + domaingroup_hdl->zoom_nj_loc.setValue(zoom_nj_loc); + domaingroup_hdl->sendAttributToServer(domaingroup_hdl->zoom_nj_loc); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_domaingroup_zoom_nj_loc(domaingroup_Ptr domaingroup_hdl, int* zoom_nj_loc) + { + *zoom_nj_loc = domaingroup_hdl->zoom_nj_loc.getInheritedValue(); + } + + bool cxios_is_defined_domaingroup_zoom_nj_loc(domaingroup_Ptr domaingroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = domaingroup_hdl->zoom_nj_loc.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icfield_attr.cpp b/src/interface/c_attr/icfield_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69754051e12c15765ad5bf91b4e9f71f51e56580 --- /dev/null +++ b/src/interface/c_attr/icfield_attr.cpp @@ -0,0 +1,535 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CField* field_Ptr; + + void cxios_set_field_add_offset(field_Ptr field_hdl, double add_offset) + { + CTimer::get("XIOS").resume(); + field_hdl->add_offset.setValue(add_offset); + field_hdl->sendAttributToServer(field_hdl->add_offset); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_add_offset(field_Ptr field_hdl, double* add_offset) + { + *add_offset = field_hdl->add_offset.getInheritedValue(); + } + + bool cxios_is_defined_field_add_offset(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->add_offset.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_axis_ref(field_Ptr field_hdl, const char * axis_ref, int axis_ref_size) + { + std::string axis_ref_str; + if(!cstr2string(axis_ref, axis_ref_size, axis_ref_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->axis_ref.setValue(axis_ref_str); + field_hdl->sendAttributToServer(field_hdl->axis_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_axis_ref(field_Ptr field_hdl, char * axis_ref, int axis_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->axis_ref.getInheritedValue(),axis_ref , axis_ref_size)) + ERROR("void cxios_get_field_axis_ref(field_Ptr field_hdl, char * axis_ref, int axis_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_axis_ref(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->axis_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_default_value(field_Ptr field_hdl, double default_value) + { + CTimer::get("XIOS").resume(); + field_hdl->default_value.setValue(default_value); + field_hdl->sendAttributToServer(field_hdl->default_value); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_default_value(field_Ptr field_hdl, double* default_value) + { + *default_value = field_hdl->default_value.getInheritedValue(); + } + + bool cxios_is_defined_field_default_value(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->default_value.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_detect_missing_value(field_Ptr field_hdl, bool detect_missing_value) + { + CTimer::get("XIOS").resume(); + field_hdl->detect_missing_value.setValue(detect_missing_value); + field_hdl->sendAttributToServer(field_hdl->detect_missing_value); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_detect_missing_value(field_Ptr field_hdl, bool* detect_missing_value) + { + *detect_missing_value = field_hdl->detect_missing_value.getInheritedValue(); + } + + bool cxios_is_defined_field_detect_missing_value(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->detect_missing_value.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_domain_ref(field_Ptr field_hdl, const char * domain_ref, int domain_ref_size) + { + std::string domain_ref_str; + if(!cstr2string(domain_ref, domain_ref_size, domain_ref_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->domain_ref.setValue(domain_ref_str); + field_hdl->sendAttributToServer(field_hdl->domain_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_domain_ref(field_Ptr field_hdl, char * domain_ref, int domain_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->domain_ref.getInheritedValue(),domain_ref , domain_ref_size)) + ERROR("void cxios_get_field_domain_ref(field_Ptr field_hdl, char * domain_ref, int domain_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_domain_ref(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->domain_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_enabled(field_Ptr field_hdl, bool enabled) + { + CTimer::get("XIOS").resume(); + field_hdl->enabled.setValue(enabled); + field_hdl->sendAttributToServer(field_hdl->enabled); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_enabled(field_Ptr field_hdl, bool* enabled) + { + *enabled = field_hdl->enabled.getInheritedValue(); + } + + bool cxios_is_defined_field_enabled(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->enabled.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_field_ref(field_Ptr field_hdl, const char * field_ref, int field_ref_size) + { + std::string field_ref_str; + if(!cstr2string(field_ref, field_ref_size, field_ref_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->field_ref.setValue(field_ref_str); + field_hdl->sendAttributToServer(field_hdl->field_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_field_ref(field_Ptr field_hdl, char * field_ref, int field_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->field_ref.getInheritedValue(),field_ref , field_ref_size)) + ERROR("void cxios_get_field_field_ref(field_Ptr field_hdl, char * field_ref, int field_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_field_ref(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->field_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_freq_offset(field_Ptr field_hdl, const char * freq_offset, int freq_offset_size) + { + std::string freq_offset_str; + if(!cstr2string(freq_offset, freq_offset_size, freq_offset_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->freq_offset.setValue(freq_offset_str); + field_hdl->sendAttributToServer(field_hdl->freq_offset); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_freq_offset(field_Ptr field_hdl, char * freq_offset, int freq_offset_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->freq_offset.getInheritedValue(),freq_offset , freq_offset_size)) + ERROR("void cxios_get_field_freq_offset(field_Ptr field_hdl, char * freq_offset, int freq_offset_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_freq_offset(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->freq_offset.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_freq_op(field_Ptr field_hdl, const char * freq_op, int freq_op_size) + { + std::string freq_op_str; + if(!cstr2string(freq_op, freq_op_size, freq_op_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->freq_op.setValue(freq_op_str); + field_hdl->sendAttributToServer(field_hdl->freq_op); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_freq_op(field_Ptr field_hdl, char * freq_op, int freq_op_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->freq_op.getInheritedValue(),freq_op , freq_op_size)) + ERROR("void cxios_get_field_freq_op(field_Ptr field_hdl, char * freq_op, int freq_op_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_freq_op(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->freq_op.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_grid_ref(field_Ptr field_hdl, const char * grid_ref, int grid_ref_size) + { + std::string grid_ref_str; + if(!cstr2string(grid_ref, grid_ref_size, grid_ref_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->grid_ref.setValue(grid_ref_str); + field_hdl->sendAttributToServer(field_hdl->grid_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_grid_ref(field_Ptr field_hdl, char * grid_ref, int grid_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->grid_ref.getInheritedValue(),grid_ref , grid_ref_size)) + ERROR("void cxios_get_field_grid_ref(field_Ptr field_hdl, char * grid_ref, int grid_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_grid_ref(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->grid_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_level(field_Ptr field_hdl, int level) + { + CTimer::get("XIOS").resume(); + field_hdl->level.setValue(level); + field_hdl->sendAttributToServer(field_hdl->level); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_level(field_Ptr field_hdl, int* level) + { + *level = field_hdl->level.getInheritedValue(); + } + + bool cxios_is_defined_field_level(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->level.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_long_name(field_Ptr field_hdl, const char * long_name, int long_name_size) + { + std::string long_name_str; + if(!cstr2string(long_name, long_name_size, long_name_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->long_name.setValue(long_name_str); + field_hdl->sendAttributToServer(field_hdl->long_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_long_name(field_Ptr field_hdl, char * long_name, int long_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->long_name.getInheritedValue(),long_name , long_name_size)) + ERROR("void cxios_get_field_long_name(field_Ptr field_hdl, char * long_name, int long_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_long_name(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->long_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_name(field_Ptr field_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->name.setValue(name_str); + field_hdl->sendAttributToServer(field_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_name(field_Ptr field_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_field_name(field_Ptr field_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_name(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_operation(field_Ptr field_hdl, const char * operation, int operation_size) + { + std::string operation_str; + if(!cstr2string(operation, operation_size, operation_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->operation.setValue(operation_str); + field_hdl->sendAttributToServer(field_hdl->operation); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_operation(field_Ptr field_hdl, char * operation, int operation_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->operation.getInheritedValue(),operation , operation_size)) + ERROR("void cxios_get_field_operation(field_Ptr field_hdl, char * operation, int operation_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_operation(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->operation.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_prec(field_Ptr field_hdl, int prec) + { + CTimer::get("XIOS").resume(); + field_hdl->prec.setValue(prec); + field_hdl->sendAttributToServer(field_hdl->prec); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_prec(field_Ptr field_hdl, int* prec) + { + *prec = field_hdl->prec.getInheritedValue(); + } + + bool cxios_is_defined_field_prec(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->prec.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_scale_factor(field_Ptr field_hdl, double scale_factor) + { + CTimer::get("XIOS").resume(); + field_hdl->scale_factor.setValue(scale_factor); + field_hdl->sendAttributToServer(field_hdl->scale_factor); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_scale_factor(field_Ptr field_hdl, double* scale_factor) + { + *scale_factor = field_hdl->scale_factor.getInheritedValue(); + } + + bool cxios_is_defined_field_scale_factor(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->scale_factor.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_standard_name(field_Ptr field_hdl, const char * standard_name, int standard_name_size) + { + std::string standard_name_str; + if(!cstr2string(standard_name, standard_name_size, standard_name_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->standard_name.setValue(standard_name_str); + field_hdl->sendAttributToServer(field_hdl->standard_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_standard_name(field_Ptr field_hdl, char * standard_name, int standard_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->standard_name.getInheritedValue(),standard_name , standard_name_size)) + ERROR("void cxios_get_field_standard_name(field_Ptr field_hdl, char * standard_name, int standard_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_standard_name(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->standard_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_unit(field_Ptr field_hdl, const char * unit, int unit_size) + { + std::string unit_str; + if(!cstr2string(unit, unit_size, unit_str)) return; + CTimer::get("XIOS").resume(); + field_hdl->unit.setValue(unit_str); + field_hdl->sendAttributToServer(field_hdl->unit); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_unit(field_Ptr field_hdl, char * unit, int unit_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(field_hdl->unit.getInheritedValue(),unit , unit_size)) + ERROR("void cxios_get_field_unit(field_Ptr field_hdl, char * unit, int unit_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_field_unit(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->unit.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_valid_max(field_Ptr field_hdl, double valid_max) + { + CTimer::get("XIOS").resume(); + field_hdl->valid_max.setValue(valid_max); + field_hdl->sendAttributToServer(field_hdl->valid_max); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_valid_max(field_Ptr field_hdl, double* valid_max) + { + *valid_max = field_hdl->valid_max.getInheritedValue(); + } + + bool cxios_is_defined_field_valid_max(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->valid_max.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_field_valid_min(field_Ptr field_hdl, double valid_min) + { + CTimer::get("XIOS").resume(); + field_hdl->valid_min.setValue(valid_min); + field_hdl->sendAttributToServer(field_hdl->valid_min); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_field_valid_min(field_Ptr field_hdl, double* valid_min) + { + *valid_min = field_hdl->valid_min.getInheritedValue(); + } + + bool cxios_is_defined_field_valid_min(field_Ptr field_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = field_hdl->valid_min.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icfieldgroup_attr.cpp b/src/interface/c_attr/icfieldgroup_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9373ddd5a8a6b3f3c1948b7202aaea30fa9d0cb2 --- /dev/null +++ b/src/interface/c_attr/icfieldgroup_attr.cpp @@ -0,0 +1,563 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CFieldGroup* fieldgroup_Ptr; + + void cxios_set_fieldgroup_add_offset(fieldgroup_Ptr fieldgroup_hdl, double add_offset) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->add_offset.setValue(add_offset); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->add_offset); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_add_offset(fieldgroup_Ptr fieldgroup_hdl, double* add_offset) + { + *add_offset = fieldgroup_hdl->add_offset.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_add_offset(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->add_offset.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_axis_ref(fieldgroup_Ptr fieldgroup_hdl, const char * axis_ref, int axis_ref_size) + { + std::string axis_ref_str; + if(!cstr2string(axis_ref, axis_ref_size, axis_ref_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->axis_ref.setValue(axis_ref_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->axis_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_axis_ref(fieldgroup_Ptr fieldgroup_hdl, char * axis_ref, int axis_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->axis_ref.getInheritedValue(),axis_ref , axis_ref_size)) + ERROR("void cxios_get_fieldgroup_axis_ref(fieldgroup_Ptr fieldgroup_hdl, char * axis_ref, int axis_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_axis_ref(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->axis_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_default_value(fieldgroup_Ptr fieldgroup_hdl, double default_value) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->default_value.setValue(default_value); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->default_value); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_default_value(fieldgroup_Ptr fieldgroup_hdl, double* default_value) + { + *default_value = fieldgroup_hdl->default_value.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_default_value(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->default_value.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_detect_missing_value(fieldgroup_Ptr fieldgroup_hdl, bool detect_missing_value) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->detect_missing_value.setValue(detect_missing_value); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->detect_missing_value); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_detect_missing_value(fieldgroup_Ptr fieldgroup_hdl, bool* detect_missing_value) + { + *detect_missing_value = fieldgroup_hdl->detect_missing_value.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_detect_missing_value(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->detect_missing_value.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_domain_ref(fieldgroup_Ptr fieldgroup_hdl, const char * domain_ref, int domain_ref_size) + { + std::string domain_ref_str; + if(!cstr2string(domain_ref, domain_ref_size, domain_ref_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->domain_ref.setValue(domain_ref_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->domain_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_domain_ref(fieldgroup_Ptr fieldgroup_hdl, char * domain_ref, int domain_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->domain_ref.getInheritedValue(),domain_ref , domain_ref_size)) + ERROR("void cxios_get_fieldgroup_domain_ref(fieldgroup_Ptr fieldgroup_hdl, char * domain_ref, int domain_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_domain_ref(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->domain_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_enabled(fieldgroup_Ptr fieldgroup_hdl, bool enabled) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->enabled.setValue(enabled); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->enabled); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_enabled(fieldgroup_Ptr fieldgroup_hdl, bool* enabled) + { + *enabled = fieldgroup_hdl->enabled.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_enabled(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->enabled.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_field_ref(fieldgroup_Ptr fieldgroup_hdl, const char * field_ref, int field_ref_size) + { + std::string field_ref_str; + if(!cstr2string(field_ref, field_ref_size, field_ref_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->field_ref.setValue(field_ref_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->field_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_field_ref(fieldgroup_Ptr fieldgroup_hdl, char * field_ref, int field_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->field_ref.getInheritedValue(),field_ref , field_ref_size)) + ERROR("void cxios_get_fieldgroup_field_ref(fieldgroup_Ptr fieldgroup_hdl, char * field_ref, int field_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_field_ref(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->field_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_freq_offset(fieldgroup_Ptr fieldgroup_hdl, const char * freq_offset, int freq_offset_size) + { + std::string freq_offset_str; + if(!cstr2string(freq_offset, freq_offset_size, freq_offset_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->freq_offset.setValue(freq_offset_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->freq_offset); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_freq_offset(fieldgroup_Ptr fieldgroup_hdl, char * freq_offset, int freq_offset_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->freq_offset.getInheritedValue(),freq_offset , freq_offset_size)) + ERROR("void cxios_get_fieldgroup_freq_offset(fieldgroup_Ptr fieldgroup_hdl, char * freq_offset, int freq_offset_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_freq_offset(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->freq_offset.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_freq_op(fieldgroup_Ptr fieldgroup_hdl, const char * freq_op, int freq_op_size) + { + std::string freq_op_str; + if(!cstr2string(freq_op, freq_op_size, freq_op_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->freq_op.setValue(freq_op_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->freq_op); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_freq_op(fieldgroup_Ptr fieldgroup_hdl, char * freq_op, int freq_op_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->freq_op.getInheritedValue(),freq_op , freq_op_size)) + ERROR("void cxios_get_fieldgroup_freq_op(fieldgroup_Ptr fieldgroup_hdl, char * freq_op, int freq_op_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_freq_op(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->freq_op.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_grid_ref(fieldgroup_Ptr fieldgroup_hdl, const char * grid_ref, int grid_ref_size) + { + std::string grid_ref_str; + if(!cstr2string(grid_ref, grid_ref_size, grid_ref_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->grid_ref.setValue(grid_ref_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->grid_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_grid_ref(fieldgroup_Ptr fieldgroup_hdl, char * grid_ref, int grid_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->grid_ref.getInheritedValue(),grid_ref , grid_ref_size)) + ERROR("void cxios_get_fieldgroup_grid_ref(fieldgroup_Ptr fieldgroup_hdl, char * grid_ref, int grid_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_grid_ref(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->grid_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_group_ref(fieldgroup_Ptr fieldgroup_hdl, const char * group_ref, int group_ref_size) + { + std::string group_ref_str; + if(!cstr2string(group_ref, group_ref_size, group_ref_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->group_ref.setValue(group_ref_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->group_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_group_ref(fieldgroup_Ptr fieldgroup_hdl, char * group_ref, int group_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->group_ref.getInheritedValue(),group_ref , group_ref_size)) + ERROR("void cxios_get_fieldgroup_group_ref(fieldgroup_Ptr fieldgroup_hdl, char * group_ref, int group_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_group_ref(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->group_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_level(fieldgroup_Ptr fieldgroup_hdl, int level) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->level.setValue(level); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->level); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_level(fieldgroup_Ptr fieldgroup_hdl, int* level) + { + *level = fieldgroup_hdl->level.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_level(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->level.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_long_name(fieldgroup_Ptr fieldgroup_hdl, const char * long_name, int long_name_size) + { + std::string long_name_str; + if(!cstr2string(long_name, long_name_size, long_name_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->long_name.setValue(long_name_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->long_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_long_name(fieldgroup_Ptr fieldgroup_hdl, char * long_name, int long_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->long_name.getInheritedValue(),long_name , long_name_size)) + ERROR("void cxios_get_fieldgroup_long_name(fieldgroup_Ptr fieldgroup_hdl, char * long_name, int long_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_long_name(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->long_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_name(fieldgroup_Ptr fieldgroup_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->name.setValue(name_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_name(fieldgroup_Ptr fieldgroup_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_fieldgroup_name(fieldgroup_Ptr fieldgroup_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_name(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_operation(fieldgroup_Ptr fieldgroup_hdl, const char * operation, int operation_size) + { + std::string operation_str; + if(!cstr2string(operation, operation_size, operation_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->operation.setValue(operation_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->operation); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_operation(fieldgroup_Ptr fieldgroup_hdl, char * operation, int operation_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->operation.getInheritedValue(),operation , operation_size)) + ERROR("void cxios_get_fieldgroup_operation(fieldgroup_Ptr fieldgroup_hdl, char * operation, int operation_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_operation(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->operation.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_prec(fieldgroup_Ptr fieldgroup_hdl, int prec) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->prec.setValue(prec); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->prec); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_prec(fieldgroup_Ptr fieldgroup_hdl, int* prec) + { + *prec = fieldgroup_hdl->prec.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_prec(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->prec.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_scale_factor(fieldgroup_Ptr fieldgroup_hdl, double scale_factor) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->scale_factor.setValue(scale_factor); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->scale_factor); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_scale_factor(fieldgroup_Ptr fieldgroup_hdl, double* scale_factor) + { + *scale_factor = fieldgroup_hdl->scale_factor.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_scale_factor(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->scale_factor.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_standard_name(fieldgroup_Ptr fieldgroup_hdl, const char * standard_name, int standard_name_size) + { + std::string standard_name_str; + if(!cstr2string(standard_name, standard_name_size, standard_name_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->standard_name.setValue(standard_name_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->standard_name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_standard_name(fieldgroup_Ptr fieldgroup_hdl, char * standard_name, int standard_name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->standard_name.getInheritedValue(),standard_name , standard_name_size)) + ERROR("void cxios_get_fieldgroup_standard_name(fieldgroup_Ptr fieldgroup_hdl, char * standard_name, int standard_name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_standard_name(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->standard_name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_unit(fieldgroup_Ptr fieldgroup_hdl, const char * unit, int unit_size) + { + std::string unit_str; + if(!cstr2string(unit, unit_size, unit_str)) return; + CTimer::get("XIOS").resume(); + fieldgroup_hdl->unit.setValue(unit_str); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->unit); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_unit(fieldgroup_Ptr fieldgroup_hdl, char * unit, int unit_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(fieldgroup_hdl->unit.getInheritedValue(),unit , unit_size)) + ERROR("void cxios_get_fieldgroup_unit(fieldgroup_Ptr fieldgroup_hdl, char * unit, int unit_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_fieldgroup_unit(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->unit.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_valid_max(fieldgroup_Ptr fieldgroup_hdl, double valid_max) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->valid_max.setValue(valid_max); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->valid_max); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_valid_max(fieldgroup_Ptr fieldgroup_hdl, double* valid_max) + { + *valid_max = fieldgroup_hdl->valid_max.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_valid_max(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->valid_max.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_fieldgroup_valid_min(fieldgroup_Ptr fieldgroup_hdl, double valid_min) + { + CTimer::get("XIOS").resume(); + fieldgroup_hdl->valid_min.setValue(valid_min); + fieldgroup_hdl->sendAttributToServer(fieldgroup_hdl->valid_min); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_fieldgroup_valid_min(fieldgroup_Ptr fieldgroup_hdl, double* valid_min) + { + *valid_min = fieldgroup_hdl->valid_min.getInheritedValue(); + } + + bool cxios_is_defined_fieldgroup_valid_min(fieldgroup_Ptr fieldgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = fieldgroup_hdl->valid_min.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icfile_attr.cpp b/src/interface/c_attr/icfile_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e929f6a83b9cc938f8ee48b4c5bfb08257cf12ea --- /dev/null +++ b/src/interface/c_attr/icfile_attr.cpp @@ -0,0 +1,341 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CFile* file_Ptr; + + void cxios_set_file_description(file_Ptr file_hdl, const char * description, int description_size) + { + std::string description_str; + if(!cstr2string(description, description_size, description_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->description.setValue(description_str); + file_hdl->sendAttributToServer(file_hdl->description); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_description(file_Ptr file_hdl, char * description, int description_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->description.getInheritedValue(),description , description_size)) + ERROR("void cxios_get_file_description(file_Ptr file_hdl, char * description, int description_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_description(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->description.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_enabled(file_Ptr file_hdl, bool enabled) + { + CTimer::get("XIOS").resume(); + file_hdl->enabled.setValue(enabled); + file_hdl->sendAttributToServer(file_hdl->enabled); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_enabled(file_Ptr file_hdl, bool* enabled) + { + *enabled = file_hdl->enabled.getInheritedValue(); + } + + bool cxios_is_defined_file_enabled(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->enabled.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_min_digits(file_Ptr file_hdl, int min_digits) + { + CTimer::get("XIOS").resume(); + file_hdl->min_digits.setValue(min_digits); + file_hdl->sendAttributToServer(file_hdl->min_digits); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_min_digits(file_Ptr file_hdl, int* min_digits) + { + *min_digits = file_hdl->min_digits.getInheritedValue(); + } + + bool cxios_is_defined_file_min_digits(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->min_digits.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_name(file_Ptr file_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->name.setValue(name_str); + file_hdl->sendAttributToServer(file_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_name(file_Ptr file_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_file_name(file_Ptr file_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_name(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_name_suffix(file_Ptr file_hdl, const char * name_suffix, int name_suffix_size) + { + std::string name_suffix_str; + if(!cstr2string(name_suffix, name_suffix_size, name_suffix_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->name_suffix.setValue(name_suffix_str); + file_hdl->sendAttributToServer(file_hdl->name_suffix); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_name_suffix(file_Ptr file_hdl, char * name_suffix, int name_suffix_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->name_suffix.getInheritedValue(),name_suffix , name_suffix_size)) + ERROR("void cxios_get_file_name_suffix(file_Ptr file_hdl, char * name_suffix, int name_suffix_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_name_suffix(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->name_suffix.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_output_freq(file_Ptr file_hdl, const char * output_freq, int output_freq_size) + { + std::string output_freq_str; + if(!cstr2string(output_freq, output_freq_size, output_freq_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->output_freq.setValue(output_freq_str); + file_hdl->sendAttributToServer(file_hdl->output_freq); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_output_freq(file_Ptr file_hdl, char * output_freq, int output_freq_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->output_freq.getInheritedValue(),output_freq , output_freq_size)) + ERROR("void cxios_get_file_output_freq(file_Ptr file_hdl, char * output_freq, int output_freq_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_output_freq(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->output_freq.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_output_level(file_Ptr file_hdl, int output_level) + { + CTimer::get("XIOS").resume(); + file_hdl->output_level.setValue(output_level); + file_hdl->sendAttributToServer(file_hdl->output_level); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_output_level(file_Ptr file_hdl, int* output_level) + { + *output_level = file_hdl->output_level.getInheritedValue(); + } + + bool cxios_is_defined_file_output_level(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->output_level.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_par_access(file_Ptr file_hdl, const char * par_access, int par_access_size) + { + std::string par_access_str; + if(!cstr2string(par_access, par_access_size, par_access_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->par_access.setValue(par_access_str); + file_hdl->sendAttributToServer(file_hdl->par_access); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_par_access(file_Ptr file_hdl, char * par_access, int par_access_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->par_access.getInheritedValue(),par_access , par_access_size)) + ERROR("void cxios_get_file_par_access(file_Ptr file_hdl, char * par_access, int par_access_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_par_access(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->par_access.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_split_freq(file_Ptr file_hdl, const char * split_freq, int split_freq_size) + { + std::string split_freq_str; + if(!cstr2string(split_freq, split_freq_size, split_freq_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->split_freq.setValue(split_freq_str); + file_hdl->sendAttributToServer(file_hdl->split_freq); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_split_freq(file_Ptr file_hdl, char * split_freq, int split_freq_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->split_freq.getInheritedValue(),split_freq , split_freq_size)) + ERROR("void cxios_get_file_split_freq(file_Ptr file_hdl, char * split_freq, int split_freq_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_split_freq(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->split_freq.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_split_freq_format(file_Ptr file_hdl, const char * split_freq_format, int split_freq_format_size) + { + std::string split_freq_format_str; + if(!cstr2string(split_freq_format, split_freq_format_size, split_freq_format_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->split_freq_format.setValue(split_freq_format_str); + file_hdl->sendAttributToServer(file_hdl->split_freq_format); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_split_freq_format(file_Ptr file_hdl, char * split_freq_format, int split_freq_format_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->split_freq_format.getInheritedValue(),split_freq_format , split_freq_format_size)) + ERROR("void cxios_get_file_split_freq_format(file_Ptr file_hdl, char * split_freq_format, int split_freq_format_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_split_freq_format(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->split_freq_format.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_sync_freq(file_Ptr file_hdl, const char * sync_freq, int sync_freq_size) + { + std::string sync_freq_str; + if(!cstr2string(sync_freq, sync_freq_size, sync_freq_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->sync_freq.setValue(sync_freq_str); + file_hdl->sendAttributToServer(file_hdl->sync_freq); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_sync_freq(file_Ptr file_hdl, char * sync_freq, int sync_freq_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->sync_freq.getInheritedValue(),sync_freq , sync_freq_size)) + ERROR("void cxios_get_file_sync_freq(file_Ptr file_hdl, char * sync_freq, int sync_freq_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_sync_freq(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->sync_freq.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_file_type(file_Ptr file_hdl, const char * type, int type_size) + { + std::string type_str; + if(!cstr2string(type, type_size, type_str)) return; + CTimer::get("XIOS").resume(); + file_hdl->type.fromString(type_str); + file_hdl->sendAttributToServer(file_hdl->type); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_file_type(file_Ptr file_hdl, char * type, int type_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(file_hdl->type.getInheritedStringValue(),type , type_size)) + ERROR("void cxios_get_file_type(file_Ptr file_hdl, char * type, int type_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_file_type(file_Ptr file_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = file_hdl->type.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icfilegroup_attr.cpp b/src/interface/c_attr/icfilegroup_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..083fde01eb6129a7cedf149617a021ec3cdc81f0 --- /dev/null +++ b/src/interface/c_attr/icfilegroup_attr.cpp @@ -0,0 +1,369 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CFileGroup* filegroup_Ptr; + + void cxios_set_filegroup_description(filegroup_Ptr filegroup_hdl, const char * description, int description_size) + { + std::string description_str; + if(!cstr2string(description, description_size, description_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->description.setValue(description_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->description); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_description(filegroup_Ptr filegroup_hdl, char * description, int description_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->description.getInheritedValue(),description , description_size)) + ERROR("void cxios_get_filegroup_description(filegroup_Ptr filegroup_hdl, char * description, int description_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_description(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->description.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_enabled(filegroup_Ptr filegroup_hdl, bool enabled) + { + CTimer::get("XIOS").resume(); + filegroup_hdl->enabled.setValue(enabled); + filegroup_hdl->sendAttributToServer(filegroup_hdl->enabled); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_enabled(filegroup_Ptr filegroup_hdl, bool* enabled) + { + *enabled = filegroup_hdl->enabled.getInheritedValue(); + } + + bool cxios_is_defined_filegroup_enabled(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->enabled.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_group_ref(filegroup_Ptr filegroup_hdl, const char * group_ref, int group_ref_size) + { + std::string group_ref_str; + if(!cstr2string(group_ref, group_ref_size, group_ref_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->group_ref.setValue(group_ref_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->group_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_group_ref(filegroup_Ptr filegroup_hdl, char * group_ref, int group_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->group_ref.getInheritedValue(),group_ref , group_ref_size)) + ERROR("void cxios_get_filegroup_group_ref(filegroup_Ptr filegroup_hdl, char * group_ref, int group_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_group_ref(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->group_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_min_digits(filegroup_Ptr filegroup_hdl, int min_digits) + { + CTimer::get("XIOS").resume(); + filegroup_hdl->min_digits.setValue(min_digits); + filegroup_hdl->sendAttributToServer(filegroup_hdl->min_digits); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_min_digits(filegroup_Ptr filegroup_hdl, int* min_digits) + { + *min_digits = filegroup_hdl->min_digits.getInheritedValue(); + } + + bool cxios_is_defined_filegroup_min_digits(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->min_digits.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_name(filegroup_Ptr filegroup_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->name.setValue(name_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_name(filegroup_Ptr filegroup_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_filegroup_name(filegroup_Ptr filegroup_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_name(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_name_suffix(filegroup_Ptr filegroup_hdl, const char * name_suffix, int name_suffix_size) + { + std::string name_suffix_str; + if(!cstr2string(name_suffix, name_suffix_size, name_suffix_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->name_suffix.setValue(name_suffix_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->name_suffix); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_name_suffix(filegroup_Ptr filegroup_hdl, char * name_suffix, int name_suffix_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->name_suffix.getInheritedValue(),name_suffix , name_suffix_size)) + ERROR("void cxios_get_filegroup_name_suffix(filegroup_Ptr filegroup_hdl, char * name_suffix, int name_suffix_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_name_suffix(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->name_suffix.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_output_freq(filegroup_Ptr filegroup_hdl, const char * output_freq, int output_freq_size) + { + std::string output_freq_str; + if(!cstr2string(output_freq, output_freq_size, output_freq_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->output_freq.setValue(output_freq_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->output_freq); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_output_freq(filegroup_Ptr filegroup_hdl, char * output_freq, int output_freq_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->output_freq.getInheritedValue(),output_freq , output_freq_size)) + ERROR("void cxios_get_filegroup_output_freq(filegroup_Ptr filegroup_hdl, char * output_freq, int output_freq_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_output_freq(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->output_freq.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_output_level(filegroup_Ptr filegroup_hdl, int output_level) + { + CTimer::get("XIOS").resume(); + filegroup_hdl->output_level.setValue(output_level); + filegroup_hdl->sendAttributToServer(filegroup_hdl->output_level); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_output_level(filegroup_Ptr filegroup_hdl, int* output_level) + { + *output_level = filegroup_hdl->output_level.getInheritedValue(); + } + + bool cxios_is_defined_filegroup_output_level(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->output_level.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_par_access(filegroup_Ptr filegroup_hdl, const char * par_access, int par_access_size) + { + std::string par_access_str; + if(!cstr2string(par_access, par_access_size, par_access_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->par_access.setValue(par_access_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->par_access); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_par_access(filegroup_Ptr filegroup_hdl, char * par_access, int par_access_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->par_access.getInheritedValue(),par_access , par_access_size)) + ERROR("void cxios_get_filegroup_par_access(filegroup_Ptr filegroup_hdl, char * par_access, int par_access_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_par_access(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->par_access.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_split_freq(filegroup_Ptr filegroup_hdl, const char * split_freq, int split_freq_size) + { + std::string split_freq_str; + if(!cstr2string(split_freq, split_freq_size, split_freq_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->split_freq.setValue(split_freq_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->split_freq); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_split_freq(filegroup_Ptr filegroup_hdl, char * split_freq, int split_freq_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->split_freq.getInheritedValue(),split_freq , split_freq_size)) + ERROR("void cxios_get_filegroup_split_freq(filegroup_Ptr filegroup_hdl, char * split_freq, int split_freq_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_split_freq(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->split_freq.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_split_freq_format(filegroup_Ptr filegroup_hdl, const char * split_freq_format, int split_freq_format_size) + { + std::string split_freq_format_str; + if(!cstr2string(split_freq_format, split_freq_format_size, split_freq_format_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->split_freq_format.setValue(split_freq_format_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->split_freq_format); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_split_freq_format(filegroup_Ptr filegroup_hdl, char * split_freq_format, int split_freq_format_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->split_freq_format.getInheritedValue(),split_freq_format , split_freq_format_size)) + ERROR("void cxios_get_filegroup_split_freq_format(filegroup_Ptr filegroup_hdl, char * split_freq_format, int split_freq_format_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_split_freq_format(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->split_freq_format.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_sync_freq(filegroup_Ptr filegroup_hdl, const char * sync_freq, int sync_freq_size) + { + std::string sync_freq_str; + if(!cstr2string(sync_freq, sync_freq_size, sync_freq_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->sync_freq.setValue(sync_freq_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->sync_freq); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_sync_freq(filegroup_Ptr filegroup_hdl, char * sync_freq, int sync_freq_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->sync_freq.getInheritedValue(),sync_freq , sync_freq_size)) + ERROR("void cxios_get_filegroup_sync_freq(filegroup_Ptr filegroup_hdl, char * sync_freq, int sync_freq_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_sync_freq(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->sync_freq.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_filegroup_type(filegroup_Ptr filegroup_hdl, const char * type, int type_size) + { + std::string type_str; + if(!cstr2string(type, type_size, type_str)) return; + CTimer::get("XIOS").resume(); + filegroup_hdl->type.fromString(type_str); + filegroup_hdl->sendAttributToServer(filegroup_hdl->type); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_filegroup_type(filegroup_Ptr filegroup_hdl, char * type, int type_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(filegroup_hdl->type.getInheritedStringValue(),type , type_size)) + ERROR("void cxios_get_filegroup_type(filegroup_Ptr filegroup_hdl, char * type, int type_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_filegroup_type(filegroup_Ptr filegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = filegroup_hdl->type.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icgrid_attr.cpp b/src/interface/c_attr/icgrid_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c5842fc58471654c1abe966e3ed87e8a57b3d70 --- /dev/null +++ b/src/interface/c_attr/icgrid_attr.cpp @@ -0,0 +1,159 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CGrid* grid_Ptr; + + void cxios_set_grid_axis_ref(grid_Ptr grid_hdl, const char * axis_ref, int axis_ref_size) + { + std::string axis_ref_str; + if(!cstr2string(axis_ref, axis_ref_size, axis_ref_str)) return; + CTimer::get("XIOS").resume(); + grid_hdl->axis_ref.setValue(axis_ref_str); + grid_hdl->sendAttributToServer(grid_hdl->axis_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_grid_axis_ref(grid_Ptr grid_hdl, char * axis_ref, int axis_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(grid_hdl->axis_ref.getInheritedValue(),axis_ref , axis_ref_size)) + ERROR("void cxios_get_grid_axis_ref(grid_Ptr grid_hdl, char * axis_ref, int axis_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_grid_axis_ref(grid_Ptr grid_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = grid_hdl->axis_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_grid_description(grid_Ptr grid_hdl, const char * description, int description_size) + { + std::string description_str; + if(!cstr2string(description, description_size, description_str)) return; + CTimer::get("XIOS").resume(); + grid_hdl->description.setValue(description_str); + grid_hdl->sendAttributToServer(grid_hdl->description); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_grid_description(grid_Ptr grid_hdl, char * description, int description_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(grid_hdl->description.getInheritedValue(),description , description_size)) + ERROR("void cxios_get_grid_description(grid_Ptr grid_hdl, char * description, int description_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_grid_description(grid_Ptr grid_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = grid_hdl->description.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_grid_domain_ref(grid_Ptr grid_hdl, const char * domain_ref, int domain_ref_size) + { + std::string domain_ref_str; + if(!cstr2string(domain_ref, domain_ref_size, domain_ref_str)) return; + CTimer::get("XIOS").resume(); + grid_hdl->domain_ref.setValue(domain_ref_str); + grid_hdl->sendAttributToServer(grid_hdl->domain_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_grid_domain_ref(grid_Ptr grid_hdl, char * domain_ref, int domain_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(grid_hdl->domain_ref.getInheritedValue(),domain_ref , domain_ref_size)) + ERROR("void cxios_get_grid_domain_ref(grid_Ptr grid_hdl, char * domain_ref, int domain_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_grid_domain_ref(grid_Ptr grid_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = grid_hdl->domain_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_grid_mask(grid_Ptr grid_hdl, bool* mask, int extent1, int extent2, int extent3) + { + CTimer::get("XIOS").resume(); + CArray tmp(mask,shape(extent1,extent2,extent3),neverDeleteData) ; + grid_hdl->mask.reference(tmp.copy()); + grid_hdl->sendAttributToServer(grid_hdl->mask); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_grid_mask(grid_Ptr grid_hdl, bool* mask, int extent1, int extent2, int extent3) + { + CTimer::get("XIOS").resume(); + CArray tmp(mask,shape(extent1,extent2,extent3),neverDeleteData) ; + tmp=grid_hdl->mask.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_grid_mask(grid_Ptr grid_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = grid_hdl->mask.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_grid_name(grid_Ptr grid_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + grid_hdl->name.setValue(name_str); + grid_hdl->sendAttributToServer(grid_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_grid_name(grid_Ptr grid_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(grid_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_grid_name(grid_Ptr grid_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_grid_name(grid_Ptr grid_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = grid_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icgridgroup_attr.cpp b/src/interface/c_attr/icgridgroup_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..776875c8af2a14fad6d482b8004636e01891cc85 --- /dev/null +++ b/src/interface/c_attr/icgridgroup_attr.cpp @@ -0,0 +1,187 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CGridGroup* gridgroup_Ptr; + + void cxios_set_gridgroup_axis_ref(gridgroup_Ptr gridgroup_hdl, const char * axis_ref, int axis_ref_size) + { + std::string axis_ref_str; + if(!cstr2string(axis_ref, axis_ref_size, axis_ref_str)) return; + CTimer::get("XIOS").resume(); + gridgroup_hdl->axis_ref.setValue(axis_ref_str); + gridgroup_hdl->sendAttributToServer(gridgroup_hdl->axis_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_gridgroup_axis_ref(gridgroup_Ptr gridgroup_hdl, char * axis_ref, int axis_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(gridgroup_hdl->axis_ref.getInheritedValue(),axis_ref , axis_ref_size)) + ERROR("void cxios_get_gridgroup_axis_ref(gridgroup_Ptr gridgroup_hdl, char * axis_ref, int axis_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_gridgroup_axis_ref(gridgroup_Ptr gridgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = gridgroup_hdl->axis_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_gridgroup_description(gridgroup_Ptr gridgroup_hdl, const char * description, int description_size) + { + std::string description_str; + if(!cstr2string(description, description_size, description_str)) return; + CTimer::get("XIOS").resume(); + gridgroup_hdl->description.setValue(description_str); + gridgroup_hdl->sendAttributToServer(gridgroup_hdl->description); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_gridgroup_description(gridgroup_Ptr gridgroup_hdl, char * description, int description_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(gridgroup_hdl->description.getInheritedValue(),description , description_size)) + ERROR("void cxios_get_gridgroup_description(gridgroup_Ptr gridgroup_hdl, char * description, int description_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_gridgroup_description(gridgroup_Ptr gridgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = gridgroup_hdl->description.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_gridgroup_domain_ref(gridgroup_Ptr gridgroup_hdl, const char * domain_ref, int domain_ref_size) + { + std::string domain_ref_str; + if(!cstr2string(domain_ref, domain_ref_size, domain_ref_str)) return; + CTimer::get("XIOS").resume(); + gridgroup_hdl->domain_ref.setValue(domain_ref_str); + gridgroup_hdl->sendAttributToServer(gridgroup_hdl->domain_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_gridgroup_domain_ref(gridgroup_Ptr gridgroup_hdl, char * domain_ref, int domain_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(gridgroup_hdl->domain_ref.getInheritedValue(),domain_ref , domain_ref_size)) + ERROR("void cxios_get_gridgroup_domain_ref(gridgroup_Ptr gridgroup_hdl, char * domain_ref, int domain_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_gridgroup_domain_ref(gridgroup_Ptr gridgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = gridgroup_hdl->domain_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_gridgroup_group_ref(gridgroup_Ptr gridgroup_hdl, const char * group_ref, int group_ref_size) + { + std::string group_ref_str; + if(!cstr2string(group_ref, group_ref_size, group_ref_str)) return; + CTimer::get("XIOS").resume(); + gridgroup_hdl->group_ref.setValue(group_ref_str); + gridgroup_hdl->sendAttributToServer(gridgroup_hdl->group_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_gridgroup_group_ref(gridgroup_Ptr gridgroup_hdl, char * group_ref, int group_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(gridgroup_hdl->group_ref.getInheritedValue(),group_ref , group_ref_size)) + ERROR("void cxios_get_gridgroup_group_ref(gridgroup_Ptr gridgroup_hdl, char * group_ref, int group_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_gridgroup_group_ref(gridgroup_Ptr gridgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = gridgroup_hdl->group_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_gridgroup_mask(gridgroup_Ptr gridgroup_hdl, bool* mask, int extent1, int extent2, int extent3) + { + CTimer::get("XIOS").resume(); + CArray tmp(mask,shape(extent1,extent2,extent3),neverDeleteData) ; + gridgroup_hdl->mask.reference(tmp.copy()); + gridgroup_hdl->sendAttributToServer(gridgroup_hdl->mask); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_gridgroup_mask(gridgroup_Ptr gridgroup_hdl, bool* mask, int extent1, int extent2, int extent3) + { + CTimer::get("XIOS").resume(); + CArray tmp(mask,shape(extent1,extent2,extent3),neverDeleteData) ; + tmp=gridgroup_hdl->mask.getInheritedValue() ; + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_gridgroup_mask(gridgroup_Ptr gridgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = gridgroup_hdl->mask.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_gridgroup_name(gridgroup_Ptr gridgroup_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + gridgroup_hdl->name.setValue(name_str); + gridgroup_hdl->sendAttributToServer(gridgroup_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_gridgroup_name(gridgroup_Ptr gridgroup_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(gridgroup_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_gridgroup_name(gridgroup_Ptr gridgroup_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_gridgroup_name(gridgroup_Ptr gridgroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = gridgroup_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icvariable_attr.cpp b/src/interface/c_attr/icvariable_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3434fa864e3c5551efa11314db7e1061c3ee67fe --- /dev/null +++ b/src/interface/c_attr/icvariable_attr.cpp @@ -0,0 +1,76 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CVariable* variable_Ptr; + + void cxios_set_variable_name(variable_Ptr variable_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + variable_hdl->name.setValue(name_str); + variable_hdl->sendAttributToServer(variable_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_variable_name(variable_Ptr variable_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(variable_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_variable_name(variable_Ptr variable_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_variable_name(variable_Ptr variable_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = variable_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_variable_type(variable_Ptr variable_hdl, const char * type, int type_size) + { + std::string type_str; + if(!cstr2string(type, type_size, type_str)) return; + CTimer::get("XIOS").resume(); + variable_hdl->type.setValue(type_str); + variable_hdl->sendAttributToServer(variable_hdl->type); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_variable_type(variable_Ptr variable_hdl, char * type, int type_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(variable_hdl->type.getInheritedValue(),type , type_size)) + ERROR("void cxios_get_variable_type(variable_Ptr variable_hdl, char * type, int type_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_variable_type(variable_Ptr variable_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = variable_hdl->type.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/c_attr/icvariablegroup_attr.cpp b/src/interface/c_attr/icvariablegroup_attr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e85f47b52902ed8f31234d197eaf4c4087f1ba3 --- /dev/null +++ b/src/interface/c_attr/icvariablegroup_attr.cpp @@ -0,0 +1,104 @@ +/* ************************************************************************** * + * Interface auto generated - do not modify * + * ************************************************************************** */ + +#include +#include +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "icutil.hpp" +#include "timer.hpp" +#include "node_type.hpp" + +extern "C" +{ + typedef xios::CVariableGroup* variablegroup_Ptr; + + void cxios_set_variablegroup_group_ref(variablegroup_Ptr variablegroup_hdl, const char * group_ref, int group_ref_size) + { + std::string group_ref_str; + if(!cstr2string(group_ref, group_ref_size, group_ref_str)) return; + CTimer::get("XIOS").resume(); + variablegroup_hdl->group_ref.setValue(group_ref_str); + variablegroup_hdl->sendAttributToServer(variablegroup_hdl->group_ref); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_variablegroup_group_ref(variablegroup_Ptr variablegroup_hdl, char * group_ref, int group_ref_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(variablegroup_hdl->group_ref.getInheritedValue(),group_ref , group_ref_size)) + ERROR("void cxios_get_variablegroup_group_ref(variablegroup_Ptr variablegroup_hdl, char * group_ref, int group_ref_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_variablegroup_group_ref(variablegroup_Ptr variablegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = variablegroup_hdl->group_ref.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_variablegroup_name(variablegroup_Ptr variablegroup_hdl, const char * name, int name_size) + { + std::string name_str; + if(!cstr2string(name, name_size, name_str)) return; + CTimer::get("XIOS").resume(); + variablegroup_hdl->name.setValue(name_str); + variablegroup_hdl->sendAttributToServer(variablegroup_hdl->name); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_variablegroup_name(variablegroup_Ptr variablegroup_hdl, char * name, int name_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(variablegroup_hdl->name.getInheritedValue(),name , name_size)) + ERROR("void cxios_get_variablegroup_name(variablegroup_Ptr variablegroup_hdl, char * name, int name_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_variablegroup_name(variablegroup_Ptr variablegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = variablegroup_hdl->name.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + void cxios_set_variablegroup_type(variablegroup_Ptr variablegroup_hdl, const char * type, int type_size) + { + std::string type_str; + if(!cstr2string(type, type_size, type_str)) return; + CTimer::get("XIOS").resume(); + variablegroup_hdl->type.setValue(type_str); + variablegroup_hdl->sendAttributToServer(variablegroup_hdl->type); + CTimer::get("XIOS").suspend(); + } + + void cxios_get_variablegroup_type(variablegroup_Ptr variablegroup_hdl, char * type, int type_size) + { + CTimer::get("XIOS").resume(); + if(!string_copy(variablegroup_hdl->type.getInheritedValue(),type , type_size)) + ERROR("void cxios_get_variablegroup_type(variablegroup_Ptr variablegroup_hdl, char * type, int type_size)", <<"Input string is to short"); + CTimer::get("XIOS").suspend(); + } + + bool cxios_is_defined_variablegroup_type(variablegroup_Ptr variablegroup_hdl ) + { + CTimer::get("XIOS").resume(); + bool isDefined = variablegroup_hdl->type.hasInheritedValue(); + CTimer::get("XIOS").suspend(); + return isDefined; + } + + + + +} diff --git a/src/interface/fortran/axis_interface.f90 b/src/interface/fortran/axis_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..614341e8c1ef04360af446d0fc093ec7b8b2f69d --- /dev/null +++ b/src/interface/fortran/axis_interface.f90 @@ -0,0 +1,22 @@ +MODULE AXIS_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_axis_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_axis_handle_create + + SUBROUTINE cxios_axis_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_axis_valid_id + + END INTERFACE + +END MODULE AXIS_INTERFACE diff --git a/src/interface/fortran/axisgroup_interface.f90 b/src/interface/fortran/axisgroup_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..fc0c88427047fa2af20f9c8602d97f2aa665b4dc --- /dev/null +++ b/src/interface/fortran/axisgroup_interface.f90 @@ -0,0 +1,23 @@ +MODULE AXISGROUP_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_axisgroup_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_axisgroup_handle_create + + SUBROUTINE cxios_axisgroup_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_axisgroup_valid_id + + END INTERFACE + +END MODULE AXISGROUP_INTERFACE diff --git a/src/interface/fortran/context_interface.f90 b/src/interface/fortran/context_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..7625cc45cbeaf74cf79972cafb2435efacf371d3 --- /dev/null +++ b/src/interface/fortran/context_interface.f90 @@ -0,0 +1,28 @@ +MODULE CONTEXT_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_context_handle_create(ret, idt, idt_size) BIND(C) + import C_CHAR, C_INTPTR_T, C_INT + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_context_handle_create + + SUBROUTINE cxios_context_set_current(context, withswap) BIND(C) + import C_BOOL, C_INT, C_INTPTR_T + INTEGER (kind = C_INTPTR_T), VALUE :: context + LOGICAL (kind = C_BOOL) , VALUE :: withswap + END SUBROUTINE cxios_context_set_current + + SUBROUTINE cxios_context_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_context_valid_id + + END INTERFACE + +END MODULE CONTEXT_INTERFACE diff --git a/src/interface/fortran/domain_interface.f90 b/src/interface/fortran/domain_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..72d7a0fad0f8a9aa87d89aa5573bba4b475b8654 --- /dev/null +++ b/src/interface/fortran/domain_interface.f90 @@ -0,0 +1,22 @@ +MODULE DOMAIN_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_domain_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_domain_handle_create + + SUBROUTINE cxios_domain_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_domain_valid_id + + END INTERFACE + +END MODULE DOMAIN_INTERFACE diff --git a/src/interface/fortran/domaingroup_interface.f90 b/src/interface/fortran/domaingroup_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..7130687a67df85f35274563872199460d517fa95 --- /dev/null +++ b/src/interface/fortran/domaingroup_interface.f90 @@ -0,0 +1,22 @@ +MODULE DOMAINGROUP_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_domaingroup_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_domaingroup_handle_create + + SUBROUTINE cxios_domaingroup_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_domaingroup_valid_id + + END INTERFACE + +END MODULE DOMAINGROUP_INTERFACE diff --git a/src/interface/fortran/field_interface.f90 b/src/interface/fortran/field_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..e44c7bba6294d834f3ab211103c35fe4b9ded738 --- /dev/null +++ b/src/interface/fortran/field_interface.f90 @@ -0,0 +1,28 @@ +MODULE FIELD_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_field_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_field_handle_create + + SUBROUTINE cxios_field_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_field_valid_id + + SUBROUTINE cxios_field_is_active(field_hdl, ret) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + LOGICAL (kind = C_BOOL) :: ret + END SUBROUTINE cxios_field_is_active + + END INTERFACE + +END MODULE FIELD_INTERFACE diff --git a/src/interface/fortran/fieldgroup_interface.f90 b/src/interface/fortran/fieldgroup_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..88aa4d877ffebe542484eb1f01d57d86d7a92581 --- /dev/null +++ b/src/interface/fortran/fieldgroup_interface.f90 @@ -0,0 +1,22 @@ +MODULE FIELDGROUP_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_fieldgroup_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_fieldgroup_handle_create + + SUBROUTINE cxios_fieldgroup_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_fieldgroup_valid_id + + END INTERFACE + +END MODULE FIELDGROUP_INTERFACE diff --git a/src/interface/fortran/file_interface.f90 b/src/interface/fortran/file_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..94e2cd0b0730337e5e5afd55f0d17bdfae527c06 --- /dev/null +++ b/src/interface/fortran/file_interface.f90 @@ -0,0 +1,22 @@ +MODULE FILE_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_file_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_file_handle_create + + SUBROUTINE cxios_file_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_file_valid_id + + END INTERFACE + +END MODULE FILE_INTERFACE diff --git a/src/interface/fortran/filegroup_interface.f90 b/src/interface/fortran/filegroup_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..173c70ec97436d6a95c04510da8696afc11e8c43 --- /dev/null +++ b/src/interface/fortran/filegroup_interface.f90 @@ -0,0 +1,22 @@ +MODULE FILEGROUP_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_filegroup_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_filegroup_handle_create + + SUBROUTINE cxios_filegroup_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_filegroup_valid_id + + END INTERFACE + +END MODULE FILEGROUP_INTERFACE diff --git a/src/interface/fortran/grid_interface.f90 b/src/interface/fortran/grid_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..1f1cf95adb07faad99d6167fc1892ac274e76110 --- /dev/null +++ b/src/interface/fortran/grid_interface.f90 @@ -0,0 +1,22 @@ +MODULE GRID_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_grid_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_grid_handle_create + + SUBROUTINE cxios_grid_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_grid_valid_id + + END INTERFACE + +END MODULE GRID_INTERFACE diff --git a/src/interface/fortran/gridgroup_interface.f90 b/src/interface/fortran/gridgroup_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..4636a740da2998a243f5d61e58b716b61f329b54 --- /dev/null +++ b/src/interface/fortran/gridgroup_interface.f90 @@ -0,0 +1,22 @@ +MODULE GRIDGROUP_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_gridgroup_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_gridgroup_handle_create + + SUBROUTINE cxios_gridgroup_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_gridgroup_valid_id + + END INTERFACE + +END MODULE GRIDGROUP_INTERFACE diff --git a/src/interface/fortran/iaxis.F90 b/src/interface/fortran/iaxis.F90 new file mode 100644 index 0000000000000000000000000000000000000000..7363bddd608b46ee972ec08d4cd3577708841ebb --- /dev/null +++ b/src/interface/fortran/iaxis.F90 @@ -0,0 +1,56 @@ +#include "xios_fortran_prefix.hpp" + +MODULE IAXIS + USE, INTRINSIC :: ISO_C_BINDING + USE AXIS_INTERFACE + USE AXISGROUP_INTERFACE + + TYPE txios(axis) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(axis) + + TYPE txios(axisgroup) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(axisgroup) + + + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + SUBROUTINE xios(get_axis_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *), INTENT(IN) :: idt + TYPE(txios(axis)) , INTENT(OUT):: ret + CALL cxios_axis_handle_create(ret%daddr, idt, len(idt)) + END SUBROUTINE xios(get_axis_handle) + + SUBROUTINE xios(get_axisgroup_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + TYPE(txios(axisgroup)), INTENT(OUT):: ret + + CALL cxios_axisgroup_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_axisgroup_handle) + + LOGICAL FUNCTION xios(is_valid_axis)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_axis_valid_id(val, idt, len(idt)) + xios(is_valid_axis) = val + + END FUNCTION xios(is_valid_axis) + + LOGICAL FUNCTION xios(is_valid_axisgroup)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_axisgroup_valid_id(val, idt, len(idt)) + xios(is_valid_axisgroup) = val + + END FUNCTION xios(is_valid_axisgroup) + +END MODULE IAXIS diff --git a/src/interface/fortran/icontext.F90 b/src/interface/fortran/icontext.F90 new file mode 100644 index 0000000000000000000000000000000000000000..33fa7d99ec5378a6708f521f5e9600242f355682 --- /dev/null +++ b/src/interface/fortran/icontext.F90 @@ -0,0 +1,52 @@ +#include "xios_fortran_prefix.hpp" + +MODULE ICONTEXT + USE, INTRINSIC :: ISO_C_BINDING + USE CONTEXT_INTERFACE +! USE icontext_attr + USE IDATE + + + TYPE txios(context) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(context) + + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + SUBROUTINE xios(get_context_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + TYPE(txios(context)), INTENT(OUT):: ret + + CALL cxios_context_handle_create(ret%daddr, idt, len(idt)) + END SUBROUTINE xios(get_context_handle) + + SUBROUTINE xios(set_current_context)(context, withswap) + IMPLICIT NONE + + TYPE(txios(context)) , INTENT(IN) :: context + LOGICAL , OPTIONAL, INTENT(IN) :: withswap + LOGICAL (kind = 1) :: wswap + + IF (PRESENT(withswap)) THEN + wswap = withswap + ELSE + wswap = .FALSE. + END IF + CALL cxios_context_set_current(context%daddr, wswap) + + END SUBROUTINE xios(set_current_context) + + LOGICAL FUNCTION xios(is_valid_context)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_context_valid_id(val, idt, len(idt)); + xios(is_valid_context) = val + + END FUNCTION xios(is_valid_context) + + +END MODULE ICONTEXT diff --git a/src/interface/fortran/idata.F90 b/src/interface/fortran/idata.F90 new file mode 100644 index 0000000000000000000000000000000000000000..60b89b5e46fb4e472918adc03494549a22ab4540 --- /dev/null +++ b/src/interface/fortran/idata.F90 @@ -0,0 +1,417 @@ +#include "xios_fortran_prefix.hpp" + +MODULE IDATA + USE, INTRINSIC :: ISO_C_BINDING + USE ICONTEXT + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_init_server() BIND(C) + END SUBROUTINE cxios_init_server + + SUBROUTINE cxios_init_client(client_id, len_client_id, f_local_comm, f_return_comm) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: client_id + INTEGER (kind = C_INT) , VALUE :: len_client_id + INTEGER (kind = C_INT) :: f_local_comm + INTEGER (kind = C_INT) :: f_return_comm + END SUBROUTINE cxios_init_client + + SUBROUTINE cxios_context_initialize(context_id,len_context_id,f_comm) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: context_id + INTEGER (kind = C_INT) , VALUE :: len_context_id + INTEGER (kind = C_INT) :: f_comm + END SUBROUTINE cxios_context_initialize + + SUBROUTINE cxios_context_is_initialized(context_id,len_context_id,initialized) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: context_id + INTEGER (kind = C_INT) , VALUE :: len_context_id + LOGICAL (kind = C_BOOL) :: initialized + END SUBROUTINE cxios_context_is_initialized + + + SUBROUTINE cxios_context_close_definition() BIND(C) + USE ISO_C_BINDING + END SUBROUTINE cxios_context_close_definition + + + SUBROUTINE cxios_context_finalize() BIND(C) + USE ISO_C_BINDING + END SUBROUTINE cxios_context_finalize + + + SUBROUTINE cxios_finalize() BIND(C) + END SUBROUTINE cxios_finalize + + SUBROUTINE cxios_solve_inheritance() BIND(C) + END SUBROUTINE cxios_solve_inheritance + + + SUBROUTINE cxios_write_data_k81(fieldid, fieldid_size, data_k8, data_Xsize) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: fieldid + REAL (kind = C_DOUBLE), DIMENSION(*) :: data_k8 + INTEGER (kind = C_INT) , VALUE :: fieldid_size + INTEGER (kind = C_INT) , VALUE :: data_Xsize + END SUBROUTINE cxios_write_data_k81 + + SUBROUTINE cxios_write_data_k82(fieldid, fieldid_size, data_k8, data_Xsize, data_Ysize) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: fieldid + REAL (kind = C_DOUBLE), DIMENSION(*) :: data_k8 + INTEGER (kind = C_INT) , VALUE :: fieldid_size + INTEGER (kind = C_INT) , VALUE :: data_Xsize, data_Ysize + END SUBROUTINE cxios_write_data_k82 + + SUBROUTINE cxios_write_data_k83(fieldid, fieldid_size, data_k8, data_Xsize, data_Ysize, data_Zsize) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: fieldid + REAL (kind = C_DOUBLE), DIMENSION(*) :: data_k8 + INTEGER (kind = C_INT) , VALUE :: fieldid_size + INTEGER (kind = C_INT) , VALUE :: data_Xsize, data_Ysize, data_Zsize + END SUBROUTINE cxios_write_data_k83 + + SUBROUTINE cxios_write_data_k41(fieldid, fieldid_size, data_k4, data_Xsize) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: fieldid + REAL (kind = C_FLOAT) , DIMENSION(*) :: data_k4 + INTEGER (kind = C_INT) , VALUE :: fieldid_size + INTEGER (kind = C_INT) , VALUE :: data_Xsize + END SUBROUTINE cxios_write_data_k41 + + SUBROUTINE cxios_write_data_k42(fieldid, fieldid_size, data_k4, data_Xsize, data_Ysize) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: fieldid + REAL (kind = C_FLOAT) , DIMENSION(*) :: data_k4 + INTEGER (kind = C_INT) , VALUE :: fieldid_size + INTEGER (kind = C_INT) , VALUE :: data_Xsize, data_Ysize + END SUBROUTINE cxios_write_data_k42 + + SUBROUTINE cxios_write_data_k43(fieldid, fieldid_size, data_k4, data_Xsize, data_Ysize, data_Zsize) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: fieldid + REAL (kind = C_FLOAT) , DIMENSION(*) :: data_k4 + INTEGER (kind = C_INT) , VALUE :: fieldid_size + INTEGER (kind = C_INT) , VALUE :: data_Xsize, data_Ysize, data_Zsize + END SUBROUTINE cxios_write_data_k43 + + ! Binding C and Fortran interface of get_variable (icdata.cpp) + SUBROUTINE cxios_get_variable_data_k8(vardid, varid_size, data_k8, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + REAL (kind = C_DOUBLE) :: data_k8 + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_get_variable_data_k8 + + SUBROUTINE cxios_get_variable_data_k4(vardid, varid_size, data_k4, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + REAL (kind = C_FLOAT) :: data_k4 + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_get_variable_data_k4 + + SUBROUTINE cxios_get_variable_data_int(vardid, varid_size, data_int, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + INTEGER (kind = C_INT) :: data_int + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_get_variable_data_int + + SUBROUTINE cxios_get_variable_data_logic(vardid, varid_size, data_logic, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + LOGICAL (kind = 4) :: data_logic + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_get_variable_data_logic + + SUBROUTINE cxios_get_variable_data_char(vardid, varid_size, data_char, data_size_in, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + INTEGER (kind = C_INT) , VALUE :: data_size_in + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: data_char + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_get_variable_data_char + + ! Binding C and Fortran interface of set_variable (icdata.cpp) + SUBROUTINE cxios_set_variable_data_k8(vardid, varid_size, data_k8, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + REAL (kind = C_DOUBLE), VALUE :: data_k8 + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_set_variable_data_k8 + + SUBROUTINE cxios_set_variable_data_k4(vardid, varid_size, data_k4, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + REAL (kind = C_FLOAT) , VALUE :: data_k4 + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_set_variable_data_k4 + + SUBROUTINE cxios_set_variable_data_int(vardid, varid_size, data_int, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + INTEGER (kind = C_INT) , VALUE :: data_int + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_set_variable_data_int + + SUBROUTINE cxios_set_variable_data_logic(vardid, varid_size, data_logic, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + LOGICAL (kind = 4) , VALUE :: data_logic + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_set_variable_data_logic + + SUBROUTINE cxios_set_variable_data_char(vardid, varid_size, data_char, data_size_in, is_var_existed) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: vardid + INTEGER (kind = C_INT) , VALUE :: varid_size + INTEGER (kind = C_INT) , VALUE :: data_size_in + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: data_char + LOGICAL (kind = C_BOOL) :: is_var_existed + END SUBROUTINE cxios_set_variable_data_char + + END INTERFACE + + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + SUBROUTINE xios(init_server)() + IMPLICIT NONE + CALL cxios_init_server() + END SUBROUTINE xios(init_server) + + SUBROUTINE xios(initialize)(client_id, local_comm, return_comm) + IMPLICIT NONE + INCLUDE 'mpif.h' + CHARACTER(LEN=*),INTENT(IN) :: client_id + INTEGER,INTENT(IN),OPTIONAL :: local_comm + INTEGER,INTENT(OUT),OPTIONAL :: return_comm + INTEGER :: f_local_comm + INTEGER :: f_return_comm + + IF (PRESENT(local_comm)) THEN + f_local_comm=local_comm + ELSE + f_local_comm = MPI_COMM_NULL + ENDIF + + CALL cxios_init_client(client_id,LEN(client_id),f_local_comm,f_return_comm) + + IF (PRESENT(return_comm)) return_comm=f_return_comm + + END SUBROUTINE xios(initialize) + + + SUBROUTINE xios(context_initialize)(context_id,comm) + IMPLICIT NONE + CHARACTER(LEN=*),INTENT(IN) :: context_id + INTEGER, INTENT(IN) :: comm + + CALL cxios_context_initialize(context_id,LEN(context_id),comm) + + END SUBROUTINE xios(context_initialize) + + + LOGICAL FUNCTION xios(context_is_initialized)(context_id) + USE ISO_C_BINDING + IMPLICIT NONE + CHARACTER(LEN=*),INTENT(IN) :: context_id + LOGICAL(KIND=C_BOOL) :: is_init + + CALL cxios_context_is_initialized(context_id, LEN(context_id), is_init) + xios(context_is_initialized) = is_init + + END FUNCTION xios(context_is_initialized) + + + SUBROUTINE xios(finalize) + IMPLICIT NONE + + CALL cxios_finalize + + END SUBROUTINE xios(finalize) + + + SUBROUTINE xios(close_context_definition)() + IMPLICIT NONE + CALL cxios_context_close_definition() + END SUBROUTINE xios(close_context_definition) + + + SUBROUTINE xios(context_finalize)() + IMPLICIT NONE + CALL cxios_context_finalize() + END SUBROUTINE xios(context_finalize) + + SUBROUTINE xios(solve_inheritance)() + IMPLICIT NONE + CALL cxios_solve_inheritance() + END SUBROUTINE xios(solve_inheritance) + + + SUBROUTINE xios(send_field_r8_1d)(fieldid, data1d_k8) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: fieldid + REAL (kind = 8), DIMENSION(*), INTENT(IN) :: data1d_k8(:) + CALL cxios_write_data_k81(fieldid, len(fieldid), data1d_k8, size(data1d_k8, 1)) + END SUBROUTINE xios(send_field_r8_1d) + + SUBROUTINE xios(send_field_r8_2d)(fieldid, data2d_k8) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: fieldid + REAL (kind = 8), DIMENSION(*), INTENT(IN) :: data2d_k8(:,:) + CALL cxios_write_data_k82(fieldid, len(fieldid), data2d_k8, size(data2d_k8, 1), size(data2d_k8, 2)) + END SUBROUTINE xios(send_field_r8_2d) + + SUBROUTINE xios(send_field_r8_3d)(fieldid, data3d_k8) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: fieldid + REAL (kind = 8), DIMENSION(*), INTENT(IN) :: data3d_k8(:,:,:) + CALL cxios_write_data_k83(fieldid, len(fieldid), data3d_k8, size(data3d_k8, 1), size(data3d_k8, 2), size(data3d_k8, 3)) + END SUBROUTINE xios(send_field_r8_3d) + + SUBROUTINE xios(send_field_r4_1d)(fieldid, data1d_k4) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: fieldid + REAL (kind = 4), DIMENSION(*), INTENT(IN) :: data1d_k4(:) + CALL cxios_write_data_k41(fieldid, len(fieldid), data1d_k4, size(data1d_k4, 1)) + END SUBROUTINE xios(send_field_r4_1d) + + SUBROUTINE xios(send_field_r4_2d)(fieldid, data2d_k4) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: fieldid + REAL (kind = 4), DIMENSION(*), INTENT(IN) :: data2d_k4(:,:) + CALL cxios_write_data_k42(fieldid, len(fieldid), data2d_k4, size(data2d_k4, 1), size(data2d_k4, 2)) + END SUBROUTINE xios(send_field_r4_2d) + + SUBROUTINE xios(send_field_r4_3d)(fieldid, data3d_k4) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: fieldid + REAL (kind = 4), DIMENSION(*), INTENT(IN) :: data3d_k4(:,:,:) + CALL cxios_write_data_k43(fieldid, len(fieldid), data3d_k4, size(data3d_k4, 1), size(data3d_k4, 2), size(data3d_k4, 3)) + END SUBROUTINE xios(send_field_r4_3d) + + ! Get variable functions + LOGICAL FUNCTION xios(getVar_k8)(varId, data_k8) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + REAL (kind = 8) , INTENT(OUT):: data_k8 + + CALL cxios_get_variable_data_k8(varId, len(varId), data_k8, val) + + xios(getVar_k8) = val + END FUNCTION xios(getVar_k8) + + LOGICAL FUNCTION xios(getVar_k4)(varId, data_k4) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + REAL (kind = 4) , INTENT(OUT):: data_k4 + + CALL cxios_get_variable_data_k4(varId, len(varId), data_k4, val) + + xios(getVar_k4) = val + END FUNCTION xios(getVar_k4) + + LOGICAL FUNCTION xios(getVar_int)(varId, data_int) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + INTEGER , INTENT(OUT):: data_int + + CALL cxios_get_variable_data_int(varId, len(varId), data_int, val) + + xios(getVar_int) = val + END FUNCTION xios(getVar_int) + + LOGICAL FUNCTION xios(getVar_logic)(varId, data_logic) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + LOGICAL (kind = 4) , INTENT(OUT):: data_logic + + CALL cxios_get_variable_data_logic(varId, len(varId), data_logic, val) + + xios(getVar_logic) = val + END FUNCTION xios(getVar_logic) + + LOGICAL FUNCTION xios(getVar_char)(varId, data_char) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + CHARACTER(len = *) , INTENT(OUT):: data_char + + CALL cxios_get_variable_data_char(varId, len(varId), data_char, len(data_char), val) + + xios(getVar_char) = val + END FUNCTION xios(getVar_char) + + ! Set variable functions + LOGICAL FUNCTION xios(setVar_k8)(varId, data_k8) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + REAL (kind = 8) , INTENT(IN) :: data_k8 + + CALL cxios_set_variable_data_k8(varId, len(varId), data_k8, val) + + xios(setVar_k8) = val + END FUNCTION xios(setVar_k8) + + LOGICAL FUNCTION xios(setVar_k4)(varId, data_k4) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + REAL (kind = 4) , INTENT(IN) :: data_k4 + + CALL cxios_set_variable_data_k4(varId, len(varId), data_k4, val) + + xios(setVar_k4) = val + END FUNCTION xios(setVar_k4) + + LOGICAL FUNCTION xios(setVar_int)(varId, data_int) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + INTEGER , INTENT(IN) :: data_int + + CALL cxios_set_variable_data_int(varId, len(varId), data_int, val) + + xios(setVar_int) = val + END FUNCTION xios(setVar_int) + + LOGICAL FUNCTION xios(setVar_logic)(varId, data_logic) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + LOGICAL (kind = 4) , INTENT(IN) :: data_logic + + CALL cxios_set_variable_data_logic(varId, len(varId), data_logic, val) + + xios(setVar_logic) = val + END FUNCTION xios(setVar_logic) + + LOGICAL FUNCTION xios(setVar_char)(varId, data_char) + IMPLICIT NONE + LOGICAL (kind = 1) :: val + CHARACTER(len = *) , INTENT(IN) :: varId + CHARACTER(len = *) , INTENT(IN) :: data_char + + CALL cxios_set_variable_data_char(varId, len(varId), data_char, len(data_char), val) + + xios(setVar_char) = val + END FUNCTION xios(setVar_char) + +END MODULE IDATA diff --git a/src/interface/fortran/idate.F90 b/src/interface/fortran/idate.F90 new file mode 100644 index 0000000000000000000000000000000000000000..27d5dc7a5ecb569e8fdef952c78e762ffbf53a7b --- /dev/null +++ b/src/interface/fortran/idate.F90 @@ -0,0 +1,58 @@ +#include "xios_fortran_prefix.hpp" +MODULE IDATE + USE, INTRINSIC :: ISO_C_BINDING + + ! enum XCalendarType + INTEGER(kind = C_INT), PARAMETER :: D360 = 0 , ALLLEAP = 1 , NOLEAP = 2 , JULIAN = 3 , GREGORIAN = 4 + + TYPE txios(date) + INTEGER :: year, month, day, hour, minute, second + END TYPE txios(date) + + TYPE txios(time) + REAL(kind = 8) :: year=0, month=0, day=0, hour=0, minute=0, second=0 + END TYPE txios(time) + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_set_timestep(ts_year, ts_month, ts_day, ts_hour, ts_minute, ts_second) BIND(C) + IMPORT C_DOUBLE + REAL (kind = C_DOUBLE), VALUE :: ts_year, ts_month , ts_day , & + ts_hour, ts_minute, ts_second + END SUBROUTINE cxios_set_timestep + + SUBROUTINE cxios_update_calendar(step) BIND(C) + IMPORT C_INT + INTEGER (kind = C_INT), VALUE :: step + END SUBROUTINE cxios_update_calendar + + END INTERFACE + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + + SUBROUTINE xios(set_timestep)(timestep) + IMPLICIT NONE + TYPE(txios(time)), INTENT(IN):: timestep + + CALL cxios_set_timestep(timestep%year, timestep%month , timestep%day, & + timestep%hour, timestep%minute, timestep%second) + + END SUBROUTINE xios(set_timestep) + + + + SUBROUTINE xios(update_calendar)(step) + IMPLICIT NONE + INTEGER, INTENT(IN):: step + + IF (step < 0) THEN + PRINT *, "L'argument 'step' ne peut être négatif" + STOP + END IF + CALL cxios_update_calendar(step) + + END SUBROUTINE xios(update_calendar) + + +END MODULE IDATE diff --git a/src/interface/fortran/idomain.F90 b/src/interface/fortran/idomain.F90 new file mode 100644 index 0000000000000000000000000000000000000000..429f111e117e5306debaa14d1684faa2e0c1f615 --- /dev/null +++ b/src/interface/fortran/idomain.F90 @@ -0,0 +1,55 @@ +#include "xios_fortran_prefix.hpp" + +MODULE IDOMAIN + USE, INTRINSIC :: ISO_C_BINDING + USE DOMAIN_INTERFACE + USE DOMAINGROUP_INTERFACE +! USE IDOMAIN_ATTR +! USE IDOMAINGROUP_ATTR + + TYPE txios(domain) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(domain) + + TYPE txios(domaingroup) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(domaingroup) + + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + SUBROUTINE xios(get_domain_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + TYPE(txios(domain)), INTENT(OUT):: ret + + CALL cxios_domain_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_domain_handle) + + SUBROUTINE xios(get_domaingroup_handle)(idt, ret) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + TYPE(txios(domaingroup)), INTENT(OUT):: ret + + CALL cxios_domaingroup_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_domaingroup_handle) + + LOGICAL FUNCTION xios(is_valid_domain)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + CALL cxios_domain_valid_id(val, idt, len(idt)); + xios(is_valid_domain) = val + END FUNCTION xios(is_valid_domain) + + LOGICAL FUNCTION xios(is_valid_domaingroup)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + CALL cxios_domaingroup_valid_id(val, idt, len(idt)); + xios(is_valid_domaingroup) = val + END FUNCTION xios(is_valid_domaingroup) + +END MODULE IDOMAIN diff --git a/src/interface/fortran/ifield.F90 b/src/interface/fortran/ifield.F90 new file mode 100644 index 0000000000000000000000000000000000000000..4a7f4542845ca70b5df69d25f7beeb5309fab8b3 --- /dev/null +++ b/src/interface/fortran/ifield.F90 @@ -0,0 +1,79 @@ +#include "xios_fortran_prefix.hpp" + +MODULE IFIELD + USE, INTRINSIC :: ISO_C_BINDING + USE FIELD_INTERFACE + USE FIELDGROUP_INTERFACE +! USE IFIELD_ATTR +! USE IFIELDGROUP_ATTR + + TYPE txios(field) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(field) + + TYPE txios(fieldgroup) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(fieldgroup) + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + SUBROUTINE xios(get_field_handle)(idt, ret) + IMPLICIT NONE + CHARACTER(len = *), INTENT(IN) :: idt + TYPE(txios(field)), INTENT(OUT) :: ret + CALL cxios_field_handle_create(ret%daddr, idt, len(idt)) + END SUBROUTINE xios(get_field_handle) + + SUBROUTINE xios(get_fieldgroup_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + TYPE(txios(fieldgroup)), INTENT(OUT):: ret + + CALL cxios_fieldgroup_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_fieldgroup_handle) + + + LOGICAL FUNCTION xios(is_valid_field)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_field_valid_id(val, idt, len(idt)); + xios(is_valid_field) = val + + END FUNCTION xios(is_valid_field) + + LOGICAL FUNCTION xios(is_valid_fieldgroup)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + CALL cxios_fieldgroup_valid_id(val, idt, len(idt)); + xios(is_valid_fieldgroup) = val + + END FUNCTION xios(is_valid_fieldgroup) + + LOGICAL FUNCTION xios(field_is_active_id(field_id)) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: field_id + LOGICAL (kind = 1) :: val + TYPE(txios(field)) :: field_hdl + + CALL xios(get_field_handle)(field_id,field_hdl) + xios(field_is_active_id)=xios(field_is_active_hdl(field_hdl)) + + END FUNCTION xios(field_is_active_id) + + + LOGICAL FUNCTION xios(field_is_active_hdl(field_hdl)) + IMPLICIT NONE + TYPE(txios(field)),INTENT(IN) :: field_hdl + LOGICAL (kind = 1) :: ret + + CALL cxios_field_is_active(field_hdl%daddr, ret); + xios(field_is_active_hdl) = ret + + END FUNCTION xios(field_is_active_hdl) + + +END MODULE IFIELD diff --git a/src/interface/fortran/ifile.F90 b/src/interface/fortran/ifile.F90 new file mode 100644 index 0000000000000000000000000000000000000000..727a82dc9ba5843e2f6172ade786ad3a79dcc93b --- /dev/null +++ b/src/interface/fortran/ifile.F90 @@ -0,0 +1,59 @@ +#include "xios_fortran_prefix.hpp" + +MODULE IFILE + USE, INTRINSIC :: ISO_C_BINDING + USE FILE_INTERFACE + USE FILEGROUP_INTERFACE +! USE IFILE_ATTR +! USE IFILEGROUP_ATTR + + TYPE txios(file) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(file) + + TYPE txios(filegroup) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(filegroup) + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + SUBROUTINE xios(get_file_handle)( idt, ret) + IMPLICIT NONE + CHARACTER(len = *), INTENT(IN) :: idt + TYPE(txios(file)) , INTENT(OUT):: ret + + CALL cxios_file_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_file_handle) + + SUBROUTINE xios(get_filegroup_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + TYPE(txios(filegroup)), INTENT(OUT):: ret + + CALL cxios_filegroup_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_filegroup_handle) + + LOGICAL FUNCTION xios(is_valid_file)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_file_valid_id(val, idt, len(idt)); + xios(is_valid_file) = val + + END FUNCTION xios(is_valid_file) + + LOGICAL FUNCTION xios(is_valid_filegroup)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_filegroup_valid_id(val, idt, len(idt)); + xios(is_valid_filegroup) = val + + END FUNCTION xios(is_valid_filegroup) + + +END MODULE IFILE diff --git a/src/interface/fortran/igrid.F90 b/src/interface/fortran/igrid.F90 new file mode 100644 index 0000000000000000000000000000000000000000..a21970ee3bb4bc00d51b4d61b0cad7d94704d76c --- /dev/null +++ b/src/interface/fortran/igrid.F90 @@ -0,0 +1,60 @@ +#include "xios_fortran_prefix.hpp" + +MODULE IGRID + USE, INTRINSIC :: ISO_C_BINDING + USE GRID_INTERFACE + USE GRIDGROUP_INTERFACE +! USE IGRID_ATTR +! USE IGRIDGROUP_ATTR + + TYPE txios(grid) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(grid) + + TYPE txios(gridgroup) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(gridgroup) + + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + SUBROUTINE xios(get_grid_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *), INTENT(IN) :: idt + TYPE(txios(grid)), INTENT(OUT):: ret + + CALL cxios_grid_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_grid_handle) + + SUBROUTINE xios(get_gridgroup_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + TYPE(txios(gridgroup)) , INTENT(OUT):: ret + + CALL cxios_gridgroup_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_gridgroup_handle) + + LOGICAL FUNCTION xios(is_valid_grid)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_grid_valid_id(val, idt, len(idt)); + xios(is_valid_grid) = val + + END FUNCTION xios(is_valid_grid) + + LOGICAL FUNCTION xios(is_valid_gridgroup)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_gridgroup_valid_id(val, idt, len(idt)); + xios(is_valid_gridgroup) = val + + END FUNCTION xios(is_valid_gridgroup) + + +END MODULE IGRID diff --git a/src/interface/fortran/ivariable.F90 b/src/interface/fortran/ivariable.F90 new file mode 100644 index 0000000000000000000000000000000000000000..bc529f3f88e9a6ef38544d0881c8bc5965ab1be5 --- /dev/null +++ b/src/interface/fortran/ivariable.F90 @@ -0,0 +1,56 @@ +#include "xios_fortran_prefix.hpp" + +MODULE IVARIABLE + USE, INTRINSIC :: ISO_C_BINDING + USE VARIABLE_INTERFACE + USE VARIABLEGROUP_INTERFACE + + TYPE txios(variable) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(variable) + + TYPE txios(variablegroup) + INTEGER(kind = C_INTPTR_T) :: daddr + END TYPE txios(variablegroup) + + + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + SUBROUTINE xios(get_variable_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *), INTENT(IN) :: idt + TYPE(txios(variable)) , INTENT(OUT):: ret + CALL cxios_variable_handle_create(ret%daddr, idt, len(idt)) + END SUBROUTINE xios(get_variable_handle) + + SUBROUTINE xios(get_variablegroup_handle)(idt,ret) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + TYPE(txios(variablegroup)), INTENT(OUT):: ret + + CALL cxios_variablegroup_handle_create(ret%daddr, idt, len(idt)) + + END SUBROUTINE xios(get_variablegroup_handle) + + LOGICAL FUNCTION xios(is_valid_variable)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_variable_valid_id(val, idt, len(idt)) + xios(is_valid_variable) = val + + END FUNCTION xios(is_valid_variable) + + LOGICAL FUNCTION xios(is_valid_variablegroup)(idt) + IMPLICIT NONE + CHARACTER(len = *) , INTENT(IN) :: idt + LOGICAL (kind = 1) :: val + + CALL cxios_variablegroup_valid_id(val, idt, len(idt)) + xios(is_valid_variablegroup) = val + + END FUNCTION xios(is_valid_variablegroup) + +END MODULE IVARIABLE diff --git a/src/interface/fortran/ixios.F90 b/src/interface/fortran/ixios.F90 new file mode 100644 index 0000000000000000000000000000000000000000..f5105e0bd708a5e21c2f340c230b7983740f30f9 --- /dev/null +++ b/src/interface/fortran/ixios.F90 @@ -0,0 +1,194 @@ +#include "xios_fortran_prefix.hpp" + +MODULE XIOS + + +USE icontext, ONLY : txios(context), xios(get_context_handle), xios(set_current_context), & + xios(is_valid_context) + +USE icontext_attr, ONLY : xios(set_context_attr), xios(set_context_attr_hdl), & + xios(get_context_attr), xios(get_context_attr_hdl), & + xios(is_defined_context_attr), xios(is_defined_context_attr_hdl) + +USE idata, ONLY : xios(initialize),xios(init_server), xios(finalize), xios(context_initialize), & + xios(context_is_initialized), xios(close_context_definition),xios(solve_inheritance), & + xios(context_finalize), xios(send_field_r8_1d), xios(send_field_r8_2d), & + xios(send_field_r8_3d), xios(send_field_r4_1d), xios(send_field_r4_2d), & + xios(send_field_r4_3d), xios(getVar_k8), xios(getVar_k4), xios(getVar_int), & + xios(getVar_logic), xios(getVar_char), xios(setVar_k8), xios(setVar_k4), xios(setVar_int), & + xios(setVar_logic), xios(setVar_char) + +USE idate, ONLY : txios(date),txios(time), xios(set_timestep),xios(update_calendar) + +USE idomain, ONLY : txios(domain), txios(domaingroup), xios(get_domain_handle), & + xios(get_domaingroup_handle),xios(is_valid_domain), & + xios(is_valid_domaingroup) + +USE idomain_attr, ONLY : xios(set_domain_attr), xios(set_domain_attr_hdl), & + xios(get_domain_attr), xios(get_domain_attr_hdl), & + xios(is_defined_domain_attr), xios(is_defined_domain_attr_hdl) + +USE idomaingroup_attr, ONLY : xios(set_domaingroup_attr), xios(set_domaingroup_attr_hdl), & + xios(get_domaingroup_attr), xios(get_domaingroup_attr_hdl), & + xios(is_defined_domaingroup_attr), xios(is_defined_domaingroup_attr_hdl) + +USE ifield, ONLY : txios(field), txios(fieldgroup), xios(get_field_handle), & + xios(get_fieldgroup_handle), xios(is_valid_field), & + xios(is_valid_fieldgroup),xios(field_is_active_id),xios(field_is_active_hdl) + +USE ifield_attr, ONLY : xios(set_field_attr),xios(set_field_attr_hdl), & + xios(get_field_attr),xios(get_field_attr_hdl), & + xios(is_defined_field_attr),xios(is_defined_field_attr_hdl) + +USE ifieldgroup_attr, ONLY : xios(set_fieldgroup_attr), xios(set_fieldgroup_attr_hdl), & + xios(get_fieldgroup_attr), xios(get_fieldgroup_attr_hdl), & + xios(is_defined_fieldgroup_attr), xios(is_defined_fieldgroup_attr_hdl) + +USE ivariable, ONLY : txios(variable), txios(variablegroup), xios(get_variable_handle), & + xios(get_variablegroup_handle), xios(is_valid_variable), & + xios(is_valid_variablegroup) + +USE ivariable_attr, ONLY : xios(set_variable_attr),xios(set_variable_attr_hdl), & + xios(get_variable_attr),xios(get_variable_attr_hdl), & + xios(is_defined_variable_attr),xios(is_defined_variable_attr_hdl) + +USE ivariablegroup_attr, ONLY : xios(set_variablegroup_attr), xios(set_variablegroup_attr_hdl), & + xios(get_variablegroup_attr), xios(get_variablegroup_attr_hdl), & + xios(is_defined_variablegroup_attr), xios(is_defined_variablegroup_attr_hdl) + +USE ifile, ONLY : txios(file), txios(filegroup), xios(get_file_handle), & + xios(get_filegroup_handle), xios(is_valid_file), xios(is_valid_filegroup) + +USE ifile_attr, ONLY : xios(set_file_attr),xios(set_file_attr_hdl), & + xios(get_file_attr),xios(get_file_attr_hdl), & + xios(is_defined_file_attr),xios(is_defined_file_attr_hdl) + +USE ifilegroup_attr, ONLY : xios(set_filegroup_attr), xios(set_filegroup_attr_hdl), & + xios(get_filegroup_attr), xios(get_filegroup_attr_hdl), & + xios(is_defined_filegroup_attr), xios(is_defined_filegroup_attr_hdl) + +USE igrid, ONLY : txios(grid), txios(gridgroup), xios(get_grid_handle), & + xios(get_gridgroup_handle), xios(is_valid_grid), xios(is_valid_gridgroup) + +USE igrid_attr, ONLY : xios(set_grid_attr_hdl), xios(set_grid_attr), & + xios(get_grid_attr_hdl), xios(get_grid_attr), & + xios(is_defined_grid_attr_hdl), xios(is_defined_grid_attr) + +USE igridgroup_attr, ONLY : xios(set_gridgroup_attr), xios(set_gridgroup_attr_hdl), & + xios(get_gridgroup_attr), xios(get_gridgroup_attr_hdl), & + xios(is_defined_gridgroup_attr), xios(is_defined_gridgroup_attr_hdl) + +USE iaxis, ONLY : txios(axis), txios(axisgroup), xios(get_axis_handle), & + xios(get_axisgroup_handle), xios(is_valid_axis), xios(is_valid_axisgroup) + +USE iaxis_attr, ONLY : xios(set_axis_attr), xios(set_axis_attr_hdl), & + xios(get_axis_attr), xios(get_axis_attr_hdl), & + xios(is_defined_axis_attr), xios(is_defined_axis_attr_hdl) + +USE iaxisgroup_attr, ONLY : xios(set_axisgroup_attr), xios(set_axisgroup_attr_hdl), & + xios(get_axisgroup_attr), xios(get_axisgroup_attr_hdl), & + xios(is_defined_axisgroup_attr), xios(is_defined_axisgroup_attr_hdl) + +USE ixml_tree, ONLY : xios(add_axis), xios(add_file), xios(add_grid), xios(add_field), xios(add_domain), & + xios(add_fieldtofile), xios(add_variabletofile), xios(add_variabletofield), & + xios(add_axisgroup), xios(add_filegroup), xios(add_gridgroup), xios(add_fieldgroup), & + xios(add_domaingroup), xios(add_fieldgrouptofile), xios(add_variablegrouptofile), & + xios(add_variablegrouptofield) + +PRIVATE + + +INTERFACE xios(set_attr) + MODULE PROCEDURE xios(set_domaingroup_attr_hdl), xios(set_domain_attr_hdl), xios(set_fieldgroup_attr_hdl), & + xios(set_field_attr_hdl),xios(set_variable_attr_hdl), xios(set_variablegroup_attr_hdl), & + xios(set_file_attr_hdl), xios(set_filegroup_attr_hdl), & + xios(set_grid_attr_hdl), xios(set_gridgroup_attr_hdl), xios(set_axis_attr_hdl) , & + xios(set_axisgroup_attr_hdl), xios(set_context_attr_hdl) +END INTERFACE xios(set_attr) + +INTERFACE xios(get_attr) + MODULE PROCEDURE xios(get_domaingroup_attr_hdl), xios(get_domain_attr_hdl), xios(get_fieldgroup_attr_hdl), & + xios(get_field_attr_hdl), xios(get_variable_attr_hdl), xios(get_variablegroup_attr_hdl), & + xios(get_file_attr_hdl), xios(get_filegroup_attr_hdl), & + xios(get_grid_attr_hdl), xios(get_gridgroup_attr_hdl), xios(get_axis_attr_hdl) , & + xios(get_axisgroup_attr_hdl), xios(get_context_attr_hdl) +END INTERFACE xios(get_attr) + +INTERFACE xios(is_defined_attr) + MODULE PROCEDURE xios(is_defined_domaingroup_attr_hdl), xios(is_defined_domain_attr_hdl), xios(is_defined_fieldgroup_attr_hdl), & + xios(is_defined_field_attr_hdl), xios(is_defined_variable_attr_hdl), xios(is_defined_variablegroup_attr_hdl), & + xios(is_defined_file_attr_hdl), xios(is_defined_filegroup_attr_hdl), & + xios(is_defined_grid_attr_hdl), xios(is_defined_gridgroup_attr_hdl), xios(is_defined_axis_attr_hdl) , & + xios(is_defined_axisgroup_attr_hdl), xios(is_defined_context_attr_hdl) +END INTERFACE xios(is_defined_attr) + +INTERFACE xios(get_handle) + MODULE PROCEDURE xios(get_context_handle), xios(get_domain_handle), xios(get_domaingroup_handle), & + xios(get_file_handle), xios(get_filegroup_handle), xios(get_grid_handle), & + xios(get_gridgroup_handle), xios(get_axis_handle), xios(get_axisgroup_handle), & + xios(get_field_handle), xios(get_fieldgroup_handle),xios(get_variable_handle), & + xios(get_variablegroup_handle) +END INTERFACE xios(get_handle) + +INTERFACE xios(add_child) + MODULE PROCEDURE xios(add_axis), xios(add_file), xios(add_grid), xios(add_field), xios(add_domain), & + xios(add_fieldtofile), xios(add_variabletofile), xios(add_variabletofield), xios(add_axisgroup), & + xios(add_filegroup), xios(add_gridgroup), xios(add_fieldgroup), xios(add_domaingroup), & + xios(add_fieldgrouptofile), xios(add_variablegrouptofile),xios(add_variablegrouptofield) +END INTERFACE xios(add_child) + + +INTERFACE xios(send_field) + MODULE PROCEDURE xios(send_field_r8_1d), xios(send_field_r8_2d), xios(send_field_r8_3d), & + xios(send_field_r4_1d), xios(send_field_r4_2d), xios(send_field_r4_3d) +END INTERFACE xios(send_field) + +INTERFACE xios(field_is_active) + MODULE PROCEDURE xios(field_is_active_id),xios(field_is_active_hdl) +END INTERFACE + +INTERFACE xios(getVar) + MODULE PROCEDURE xios(getVar_k8), xios(getVar_k4), xios(getVar_int), xios(getVar_logic), xios(getVar_char) +END INTERFACE xios(getVar) + +INTERFACE xios(setVar) + MODULE PROCEDURE xios(setVar_k8), xios(setVar_k4), xios(setVar_int), xios(setVar_logic), xios(setVar_char) +END INTERFACE xios(setVar) + + PUBLIC :: txios(domain), txios(domaingroup),txios(field), txios(fieldgroup),txios(file), txios(filegroup), & + txios(grid), txios(gridgroup), txios(axis), txios(axisgroup),txios(context), txios(date), & + txios(time), txios(variable) + + PUBLIC :: xios(set_attr), xios(set_domain_attr), xios(set_domaingroup_attr), xios(set_fieldgroup_attr), & + xios(set_field_attr), xios(set_file_attr), xios(set_filegroup_attr), & + xios(set_grid_attr), xios(set_gridgroup_attr), xios(set_axis_attr) , & + xios(set_axisgroup_attr), xios(set_context_attr) + + PUBLIC :: xios(get_attr), xios(get_domain_attr), xios(get_domaingroup_attr), xios(get_fieldgroup_attr), & + xios(get_field_attr), xios(get_file_attr), xios(get_filegroup_attr), & + xios(get_grid_attr), xios(get_gridgroup_attr), xios(get_axis_attr) , & + xios(get_axisgroup_attr), xios(get_context_attr) + +PUBLIC :: xios(is_defined_attr), xios(is_defined_domain_attr), xios(is_defined_domaingroup_attr), xios(is_defined_fieldgroup_attr), & + xios(is_defined_field_attr), xios(is_defined_file_attr), xios(is_defined_filegroup_attr), & + xios(is_defined_grid_attr), xios(is_defined_gridgroup_attr), xios(is_defined_axis_attr) , & + xios(is_defined_axisgroup_attr), xios(is_defined_context_attr) + + PUBLIC :: xios(get_handle) + PUBLIC :: xios(add_child) + + PUBLIC :: xios(is_valid_context),xios(is_valid_domain), xios(is_valid_domaingroup),xios(is_valid_field), & + xios(is_valid_fieldgroup), xios(is_valid_file), xios(is_valid_filegroup), xios(is_valid_grid), & + xios(is_valid_gridgroup), xios(is_valid_axis), xios(is_valid_axisgroup), xios(is_valid_variable), & + xios(is_valid_variablegroup) + + PUBLIC :: xios(set_current_context) + PUBLIC :: xios(set_timestep),xios(update_calendar) + PUBLIC :: xios(initialize), xios(init_server), xios(finalize), xios(context_initialize),xios(context_is_initialized), & + xios(solve_inheritance), xios(close_context_definition), xios(context_finalize), xios(send_field), & + xios(field_is_active) + + PUBLIC :: xios(getVar) + PUBLIC :: xios(setVar) + +END MODULE XIOS diff --git a/src/interface/fortran/ixml_tree.F90 b/src/interface/fortran/ixml_tree.F90 new file mode 100644 index 0000000000000000000000000000000000000000..93728a27eec9ff946be91a4907227ee5979f0b64 --- /dev/null +++ b/src/interface/fortran/ixml_tree.F90 @@ -0,0 +1,378 @@ +#include "xios_fortran_prefix.hpp" + +MODULE IXML_TREE + USE, INTRINSIC :: ISO_C_BINDING + USE IAXIS + USE IFILE + USE IFIELD + USE IGRID + USE IDOMAIN + USE IVARIABLE + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_xml_tree_add_field(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_field + + SUBROUTINE cxios_xml_tree_add_grid(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_grid + + SUBROUTINE cxios_xml_tree_add_file(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_file + + SUBROUTINE cxios_xml_tree_add_axis(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_axis + + SUBROUTINE cxios_xml_tree_add_domain(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_domain + + SUBROUTINE cxios_xml_tree_add_fieldtofile(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_fieldtofile + + SUBROUTINE cxios_xml_tree_add_variabletofile(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_variabletofile + + + SUBROUTINE cxios_xml_tree_add_variabletofield(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_variabletofield + + + SUBROUTINE cxios_xml_tree_add_fieldgroup(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_fieldgroup + + SUBROUTINE cxios_xml_tree_add_gridgroup(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_gridgroup + + SUBROUTINE cxios_xml_tree_add_filegroup(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_filegroup + + SUBROUTINE cxios_xml_tree_add_axisgroup(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_axisgroup + + SUBROUTINE cxios_xml_tree_add_domaingroup(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_domaingroup + + SUBROUTINE cxios_xml_tree_add_fieldgrouptofile(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_fieldgrouptofile + + SUBROUTINE cxios_xml_tree_add_variablegrouptofile(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_variablegrouptofile + + SUBROUTINE cxios_xml_tree_add_variablegrouptofield(parent_, child_, child_id, child_id_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: parent_ + INTEGER (kind = C_INTPTR_T) :: child_ + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: child_id + INTEGER (kind = C_INT) , VALUE :: child_id_size + END SUBROUTINE cxios_xml_tree_add_variablegrouptofield + + SUBROUTINE cxios_xml_tree_show(filename, filename_size) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR), DIMENSION(*) :: filename + INTEGER (kind = C_INT) , VALUE :: filename_size + END SUBROUTINE cxios_xml_tree_show + + SUBROUTINE cxios_xml_parse_file(filename, filename_size) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR), DIMENSION(*) :: filename + INTEGER (kind = C_INT) , VALUE :: filename_size + END SUBROUTINE cxios_xml_parse_file + + SUBROUTINE cxios_xml_parse_string(xmlcontent, xmlcontent_size) BIND(C) + USE ISO_C_BINDING + CHARACTER(kind = C_CHAR), DIMENSION(*) :: xmlcontent + INTEGER (kind = C_INT) , VALUE :: xmlcontent_size + END SUBROUTINE cxios_xml_parse_string + + END INTERFACE + + + CONTAINS ! Fonctions disponibles pour les utilisateurs. + + + SUBROUTINE xios(add_axis)(parent_hdl, child_hdl, child_id) + TYPE(txios(axisgroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(axis)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL, INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_axis(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_axis(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_axis) + + SUBROUTINE xios(add_file)(parent_hdl, child_hdl, child_id) + TYPE(txios(filegroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(file)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL, INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_file(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_file(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_file) + + SUBROUTINE xios(add_grid)(parent_hdl, child_hdl, child_id) + TYPE(txios(gridgroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(grid)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL, INTENT(IN) :: child_id + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_grid(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_grid(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_grid) + + + SUBROUTINE xios(add_field)(parent_hdl, child_hdl, child_id) + TYPE(txios(fieldgroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(field)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL, INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_field(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_field(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_field) + + + SUBROUTINE xios(add_domain)(parent_hdl, child_hdl, child_id) + TYPE(txios(domaingroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(domain)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL , INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_domain(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_domain(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_domain) + + SUBROUTINE xios(add_fieldtofile)(parent_hdl, child_hdl, child_id) + TYPE(txios(file)) , INTENT(IN) :: parent_hdl + TYPE(txios(field)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL , INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_fieldtofile(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_fieldtofile(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_fieldtofile) + + SUBROUTINE xios(add_variabletofile)(parent_hdl, child_hdl, child_id) + TYPE(txios(file)) , INTENT(IN) :: parent_hdl + TYPE(txios(variable)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL , INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_variabletofile(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_variabletofile(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_variabletofile) + + SUBROUTINE xios(add_variabletofield)(parent_hdl, child_hdl, child_id) + TYPE(txios(field)) , INTENT(IN) :: parent_hdl + TYPE(txios(variable)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL , INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_variabletofield(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_variabletofield(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_variabletofield) + + + SUBROUTINE xios(add_axisgroup)(parent_hdl, child_hdl, child_id) + TYPE(txios(axisgroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(axisgroup)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL, INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_axisgroup(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_axisgroup(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_axisgroup) + + + SUBROUTINE xios(add_filegroup)(parent_hdl, child_hdl, child_id) + TYPE(txios(filegroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(filegroup)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL, INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_filegroup(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_filegroup(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_filegroup) + + SUBROUTINE xios(add_gridgroup)(parent_hdl, child_hdl, child_id) + TYPE(txios(gridgroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(gridgroup)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL, INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_gridgroup(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_gridgroup(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_gridgroup) + + + SUBROUTINE xios(add_fieldgroup)(parent_hdl, child_hdl, child_id) + TYPE(txios(fieldgroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(fieldgroup)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL, INTENT(IN) :: child_id + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_fieldgroup(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_fieldgroup(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + END SUBROUTINE xios(add_fieldgroup) + + SUBROUTINE xios(add_domaingroup)(parent_hdl, child_hdl, child_id) + TYPE(txios(domaingroup)) , INTENT(IN) :: parent_hdl + TYPE(txios(domaingroup)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL , INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_domaingroup(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_domaingroup(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_domaingroup) + + SUBROUTINE xios(add_fieldgrouptofile)(parent_hdl, child_hdl, child_id) + TYPE(txios(file)) , INTENT(IN) :: parent_hdl + TYPE(txios(fieldgroup)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL , INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_fieldgrouptofile(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_fieldgrouptofile(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_fieldgrouptofile) + + SUBROUTINE xios(add_variablegrouptofile)(parent_hdl, child_hdl, child_id) + TYPE(txios(file)) , INTENT(IN) :: parent_hdl + TYPE(txios(variablegroup)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL , INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_variablegrouptofile(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_variablegrouptofile(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_variablegrouptofile) + + SUBROUTINE xios(add_variablegrouptofield)(parent_hdl, child_hdl, child_id) + TYPE(txios(field)) , INTENT(IN) :: parent_hdl + TYPE(txios(variablegroup)) , INTENT(OUT):: child_hdl + CHARACTER(len = *), OPTIONAL , INTENT(IN) :: child_id + + IF (PRESENT(child_id)) THEN + CALL cxios_xml_tree_add_variablegrouptofield(parent_hdl%daddr, child_hdl%daddr, child_id, len(child_id)) + ELSE + CALL cxios_xml_tree_add_variablegrouptofield(parent_hdl%daddr, child_hdl%daddr, "NONE", -1) + END IF + + END SUBROUTINE xios(add_variablegrouptofield) + +END MODULE IXML_TREE diff --git a/src/interface/fortran/oasis_interface.F90 b/src/interface/fortran/oasis_interface.F90 new file mode 100644 index 0000000000000000000000000000000000000000..313a973ad841f2bd98db6fe1f28de522ccf64d2c --- /dev/null +++ b/src/interface/fortran/oasis_interface.F90 @@ -0,0 +1,141 @@ +SUBROUTINE fxios_oasis_init(server_id,str_len) BIND(C,NAME="fxios_oasis_init") + USE, INTRINSIC :: ISO_C_BINDING +#ifdef USE_OASIS + USE mod_prism_proto +#endif +#ifdef USE_OMCT + USE mod_prism +#endif + CHARACTER(kind = C_CHAR),DIMENSION(*) :: server_id + INTEGER(kind = C_INT),VALUE :: str_len + + INTEGER :: comp_id + CHARACTER(len=str_len) :: oasis_server_id + INTEGER :: ierr + INTEGER :: i + + DO i=1,str_len + oasis_server_id(i:i)=server_id(i) + ENDDO + +#if defined USE_OASIS || defined USE_OMCT + CALL prism_init_comp_proto (comp_id, oasis_server_id, ierr) +#endif + PRINT *,"---> prism_init",oasis_server_id,ierr + +END SUBROUTINE fxios_oasis_init + +SUBROUTINE fxios_oasis_enddef() BIND(C,NAME="fxios_oasis_enddef") + USE, INTRINSIC :: ISO_C_BINDING +#ifdef USE_OMCT + USE mod_prism +#endif + IMPLICIT NONE + INTEGER :: ierr +#ifdef USE_OMCT + CALL prism_enddef_proto(ierr) +#endif + +END SUBROUTINE fxios_oasis_enddef + +SUBROUTINE fxios_oasis_finalize() BIND(C,NAME="fxios_oasis_finalize") + USE, INTRINSIC :: ISO_C_BINDING +#ifdef USE_OASIS + USE mod_prism_proto +#endif +#ifdef USE_OMCT + USE mod_prism +#endif + IMPLICIT NONE + INTEGER :: ierr + +#if defined USE_OASIS || defined USE_OMCT + CALL prism_terminate_proto(ierr) +#endif + +END SUBROUTINE fxios_oasis_finalize + + +SUBROUTINE fxios_oasis_get_localcomm(f_comm) BIND(C,NAME="fxios_oasis_get_localcomm") + USE, INTRINSIC :: ISO_C_BINDING +#ifdef USE_OASIS + USE mod_prism_get_localcomm_proto +#endif +#ifdef USE_OMCT + USE mod_prism +#endif + IMPLICIT NONE + INTEGER(kind=C_INT) :: f_comm + + INTEGER :: comm + INTEGER :: ierr + +#if defined USE_OASIS || defined USE_OMCT + CALL prism_get_localcomm_proto(comm,ierr) +#endif + f_comm=comm + +END SUBROUTINE fxios_oasis_get_localcomm + + + + +SUBROUTINE fxios_oasis_get_intracomm(f_comm_client_server,client_id,str_len) BIND(C,NAME="fxios_oasis_get_intracomm") + USE, INTRINSIC :: ISO_C_BINDING +#ifdef USE_OASIS + USE mod_prism_get_comm +#endif +#ifdef USE_OMCT + USE mod_prism +#endif + IMPLICIT NONE + INTEGER(kind=C_INT) :: f_comm_client_server + CHARACTER,DIMENSION(*) :: client_id + INTEGER,VALUE :: str_len + + INTEGER :: comm_client_server + CHARACTER(len=str_len) :: oasis_client_id + INTEGER :: ierr + INTEGER :: i + + DO i=1,str_len + oasis_client_id(i:i)=client_id(i) + ENDDO + +#if defined USE_OASIS || defined USE_OMCT + CALL prism_get_intracomm(comm_client_server,oasis_client_id,ierr) +#endif + + f_comm_client_server=comm_client_server + +END SUBROUTINE fxios_oasis_get_intracomm + +SUBROUTINE fxios_oasis_get_intercomm(f_comm_client_server,client_id,str_len) BIND(C,NAME="fxios_oasis_get_intercomm") + USE, INTRINSIC :: ISO_C_BINDING +#ifdef USE_OASIS + USE mod_prism_get_comm +#endif +#ifdef USE_OMCT + USE mod_prism +#endif + IMPLICIT NONE + INTEGER(kind=C_INT) :: f_comm_client_server + CHARACTER,DIMENSION(*) :: client_id + INTEGER,VALUE :: str_len + + INTEGER :: comm_client_server + CHARACTER(len=str_len) :: oasis_client_id + INTEGER :: ierr + INTEGER :: i + + DO i=1,str_len + oasis_client_id(i:i)=client_id(i) + ENDDO + +#if defined USE_OASIS || defined USE_OMCT + CALL prism_get_intercomm(comm_client_server,oasis_client_id,ierr) +#endif + + f_comm_client_server=comm_client_server + +END SUBROUTINE fxios_oasis_get_intercomm diff --git a/src/interface/fortran/variable_interface.f90 b/src/interface/fortran/variable_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..531d3d85054c3492d90ee6f5cd78d4aaff2dabd3 --- /dev/null +++ b/src/interface/fortran/variable_interface.f90 @@ -0,0 +1,22 @@ +MODULE VARIABLE_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + SUBROUTINE cxios_variable_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_variable_handle_create + + SUBROUTINE cxios_variable_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_variable_valid_id + + END INTERFACE + +END MODULE VARIABLE_INTERFACE diff --git a/src/interface/fortran/variablegroup_interface.f90 b/src/interface/fortran/variablegroup_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..241d66042a4da40fd6625b6d540c38e2776673f8 --- /dev/null +++ b/src/interface/fortran/variablegroup_interface.f90 @@ -0,0 +1,23 @@ +MODULE VARIABLEGROUP_INTERFACE + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Ne pas appeler directement/Interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_variablegroup_handle_create(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_variablegroup_handle_create + + SUBROUTINE cxios_variablegroup_valid_id(ret, idt, idt_size) BIND(C) + USE ISO_C_BINDING + LOGICAL (kind = C_BOOL) :: ret + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: idt + INTEGER (kind = C_INT) , VALUE :: idt_size + END SUBROUTINE cxios_variablegroup_valid_id + + END INTERFACE + +END MODULE VARIABLEGROUP_INTERFACE diff --git a/src/interface/fortran/xios_fortran_prefix.hpp b/src/interface/fortran/xios_fortran_prefix.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b8c75b4594bea6fc5e99ca9e44aec00089a7897b --- /dev/null +++ b/src/interface/fortran/xios_fortran_prefix.hpp @@ -0,0 +1,7 @@ +#ifndef __XIOS_SUFFIX__ +#define __XIOS_SUFFIX__ + +#define xios(arg) xios_##arg +#define txios(arg) xios_##arg + +#endif diff --git a/src/interface/fortran_attr/axis_interface_attr.f90 b/src/interface/fortran_attr/axis_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..c4b51abd7eb721d27b58ed9ebea480c22e27cc5d --- /dev/null +++ b/src/interface/fortran_attr/axis_interface_attr.f90 @@ -0,0 +1,215 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE axis_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_axis_long_name(axis_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_set_axis_long_name + + SUBROUTINE cxios_get_axis_long_name(axis_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_get_axis_long_name + + FUNCTION cxios_is_defined_axis_long_name(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_long_name + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_long_name + + + SUBROUTINE cxios_set_axis_name(axis_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_axis_name + + SUBROUTINE cxios_get_axis_name(axis_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_axis_name + + FUNCTION cxios_is_defined_axis_name(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_name + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_name + + + SUBROUTINE cxios_set_axis_positive(axis_hdl, positive, positive_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: positive + INTEGER (kind = C_INT) , VALUE :: positive_size + END SUBROUTINE cxios_set_axis_positive + + SUBROUTINE cxios_get_axis_positive(axis_hdl, positive, positive_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: positive + INTEGER (kind = C_INT) , VALUE :: positive_size + END SUBROUTINE cxios_get_axis_positive + + FUNCTION cxios_is_defined_axis_positive(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_positive + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_positive + + + SUBROUTINE cxios_set_axis_size(axis_hdl, size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + INTEGER (KIND=C_INT) , VALUE :: size + END SUBROUTINE cxios_set_axis_size + + SUBROUTINE cxios_get_axis_size(axis_hdl, size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + INTEGER (KIND=C_INT) :: size + END SUBROUTINE cxios_get_axis_size + + FUNCTION cxios_is_defined_axis_size(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_size + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_size + + + SUBROUTINE cxios_set_axis_standard_name(axis_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_set_axis_standard_name + + SUBROUTINE cxios_get_axis_standard_name(axis_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_get_axis_standard_name + + FUNCTION cxios_is_defined_axis_standard_name(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_standard_name + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_standard_name + + + SUBROUTINE cxios_set_axis_unit(axis_hdl, unit, unit_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: unit + INTEGER (kind = C_INT) , VALUE :: unit_size + END SUBROUTINE cxios_set_axis_unit + + SUBROUTINE cxios_get_axis_unit(axis_hdl, unit, unit_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: unit + INTEGER (kind = C_INT) , VALUE :: unit_size + END SUBROUTINE cxios_get_axis_unit + + FUNCTION cxios_is_defined_axis_unit(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_unit + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_unit + + + SUBROUTINE cxios_set_axis_value(axis_hdl, value, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: value + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_axis_value + + SUBROUTINE cxios_get_axis_value(axis_hdl, value, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: value + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_axis_value + + FUNCTION cxios_is_defined_axis_value(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_value + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_value + + + SUBROUTINE cxios_set_axis_zoom_begin(axis_hdl, zoom_begin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_begin + END SUBROUTINE cxios_set_axis_zoom_begin + + SUBROUTINE cxios_get_axis_zoom_begin(axis_hdl, zoom_begin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + INTEGER (KIND=C_INT) :: zoom_begin + END SUBROUTINE cxios_get_axis_zoom_begin + + FUNCTION cxios_is_defined_axis_zoom_begin(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_zoom_begin + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_zoom_begin + + + SUBROUTINE cxios_set_axis_zoom_end(axis_hdl, zoom_end) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_end + END SUBROUTINE cxios_set_axis_zoom_end + + SUBROUTINE cxios_get_axis_zoom_end(axis_hdl, zoom_end) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + INTEGER (KIND=C_INT) :: zoom_end + END SUBROUTINE cxios_get_axis_zoom_end + + FUNCTION cxios_is_defined_axis_zoom_end(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_zoom_end + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_zoom_end + + + SUBROUTINE cxios_set_axis_zoom_size(axis_hdl, zoom_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_size + END SUBROUTINE cxios_set_axis_zoom_size + + SUBROUTINE cxios_get_axis_zoom_size(axis_hdl, zoom_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + INTEGER (KIND=C_INT) :: zoom_size + END SUBROUTINE cxios_get_axis_zoom_size + + FUNCTION cxios_is_defined_axis_zoom_size(axis_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axis_zoom_size + INTEGER (kind = C_INTPTR_T), VALUE :: axis_hdl + END FUNCTION cxios_is_defined_axis_zoom_size + + + END INTERFACE + +END MODULE axis_interface_attr diff --git a/src/interface/fortran_attr/axisgroup_interface_attr.f90 b/src/interface/fortran_attr/axisgroup_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..e2c4468621ffc1b51e1c315568a0df61dc55e85c --- /dev/null +++ b/src/interface/fortran_attr/axisgroup_interface_attr.f90 @@ -0,0 +1,236 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE axisgroup_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_axisgroup_group_ref(axisgroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_set_axisgroup_group_ref + + SUBROUTINE cxios_get_axisgroup_group_ref(axisgroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_get_axisgroup_group_ref + + FUNCTION cxios_is_defined_axisgroup_group_ref(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_group_ref + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_group_ref + + + SUBROUTINE cxios_set_axisgroup_long_name(axisgroup_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_set_axisgroup_long_name + + SUBROUTINE cxios_get_axisgroup_long_name(axisgroup_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_get_axisgroup_long_name + + FUNCTION cxios_is_defined_axisgroup_long_name(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_long_name + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_long_name + + + SUBROUTINE cxios_set_axisgroup_name(axisgroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_axisgroup_name + + SUBROUTINE cxios_get_axisgroup_name(axisgroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_axisgroup_name + + FUNCTION cxios_is_defined_axisgroup_name(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_name + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_name + + + SUBROUTINE cxios_set_axisgroup_positive(axisgroup_hdl, positive, positive_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: positive + INTEGER (kind = C_INT) , VALUE :: positive_size + END SUBROUTINE cxios_set_axisgroup_positive + + SUBROUTINE cxios_get_axisgroup_positive(axisgroup_hdl, positive, positive_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: positive + INTEGER (kind = C_INT) , VALUE :: positive_size + END SUBROUTINE cxios_get_axisgroup_positive + + FUNCTION cxios_is_defined_axisgroup_positive(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_positive + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_positive + + + SUBROUTINE cxios_set_axisgroup_size(axisgroup_hdl, size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + INTEGER (KIND=C_INT) , VALUE :: size + END SUBROUTINE cxios_set_axisgroup_size + + SUBROUTINE cxios_get_axisgroup_size(axisgroup_hdl, size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + INTEGER (KIND=C_INT) :: size + END SUBROUTINE cxios_get_axisgroup_size + + FUNCTION cxios_is_defined_axisgroup_size(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_size + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_size + + + SUBROUTINE cxios_set_axisgroup_standard_name(axisgroup_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_set_axisgroup_standard_name + + SUBROUTINE cxios_get_axisgroup_standard_name(axisgroup_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_get_axisgroup_standard_name + + FUNCTION cxios_is_defined_axisgroup_standard_name(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_standard_name + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_standard_name + + + SUBROUTINE cxios_set_axisgroup_unit(axisgroup_hdl, unit, unit_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: unit + INTEGER (kind = C_INT) , VALUE :: unit_size + END SUBROUTINE cxios_set_axisgroup_unit + + SUBROUTINE cxios_get_axisgroup_unit(axisgroup_hdl, unit, unit_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: unit + INTEGER (kind = C_INT) , VALUE :: unit_size + END SUBROUTINE cxios_get_axisgroup_unit + + FUNCTION cxios_is_defined_axisgroup_unit(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_unit + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_unit + + + SUBROUTINE cxios_set_axisgroup_value(axisgroup_hdl, value, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: value + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_axisgroup_value + + SUBROUTINE cxios_get_axisgroup_value(axisgroup_hdl, value, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: value + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_axisgroup_value + + FUNCTION cxios_is_defined_axisgroup_value(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_value + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_value + + + SUBROUTINE cxios_set_axisgroup_zoom_begin(axisgroup_hdl, zoom_begin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_begin + END SUBROUTINE cxios_set_axisgroup_zoom_begin + + SUBROUTINE cxios_get_axisgroup_zoom_begin(axisgroup_hdl, zoom_begin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + INTEGER (KIND=C_INT) :: zoom_begin + END SUBROUTINE cxios_get_axisgroup_zoom_begin + + FUNCTION cxios_is_defined_axisgroup_zoom_begin(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_zoom_begin + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_zoom_begin + + + SUBROUTINE cxios_set_axisgroup_zoom_end(axisgroup_hdl, zoom_end) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_end + END SUBROUTINE cxios_set_axisgroup_zoom_end + + SUBROUTINE cxios_get_axisgroup_zoom_end(axisgroup_hdl, zoom_end) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + INTEGER (KIND=C_INT) :: zoom_end + END SUBROUTINE cxios_get_axisgroup_zoom_end + + FUNCTION cxios_is_defined_axisgroup_zoom_end(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_zoom_end + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_zoom_end + + + SUBROUTINE cxios_set_axisgroup_zoom_size(axisgroup_hdl, zoom_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_size + END SUBROUTINE cxios_set_axisgroup_zoom_size + + SUBROUTINE cxios_get_axisgroup_zoom_size(axisgroup_hdl, zoom_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + INTEGER (KIND=C_INT) :: zoom_size + END SUBROUTINE cxios_get_axisgroup_zoom_size + + FUNCTION cxios_is_defined_axisgroup_zoom_size(axisgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_axisgroup_zoom_size + INTEGER (kind = C_INTPTR_T), VALUE :: axisgroup_hdl + END FUNCTION cxios_is_defined_axisgroup_zoom_size + + + END INTERFACE + +END MODULE axisgroup_interface_attr diff --git a/src/interface/fortran_attr/context_interface_attr.f90 b/src/interface/fortran_attr/context_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..5a0c585ec3bec3a67be7e52c20b6888bae8e972a --- /dev/null +++ b/src/interface/fortran_attr/context_interface_attr.f90 @@ -0,0 +1,118 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE context_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_context_calendar_type(context_hdl, calendar_type, calendar_type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: calendar_type + INTEGER (kind = C_INT) , VALUE :: calendar_type_size + END SUBROUTINE cxios_set_context_calendar_type + + SUBROUTINE cxios_get_context_calendar_type(context_hdl, calendar_type, calendar_type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: calendar_type + INTEGER (kind = C_INT) , VALUE :: calendar_type_size + END SUBROUTINE cxios_get_context_calendar_type + + FUNCTION cxios_is_defined_context_calendar_type(context_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_context_calendar_type + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + END FUNCTION cxios_is_defined_context_calendar_type + + + SUBROUTINE cxios_set_context_output_dir(context_hdl, output_dir, output_dir_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: output_dir + INTEGER (kind = C_INT) , VALUE :: output_dir_size + END SUBROUTINE cxios_set_context_output_dir + + SUBROUTINE cxios_get_context_output_dir(context_hdl, output_dir, output_dir_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: output_dir + INTEGER (kind = C_INT) , VALUE :: output_dir_size + END SUBROUTINE cxios_get_context_output_dir + + FUNCTION cxios_is_defined_context_output_dir(context_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_context_output_dir + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + END FUNCTION cxios_is_defined_context_output_dir + + + SUBROUTINE cxios_set_context_start_date(context_hdl, start_date, start_date_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: start_date + INTEGER (kind = C_INT) , VALUE :: start_date_size + END SUBROUTINE cxios_set_context_start_date + + SUBROUTINE cxios_get_context_start_date(context_hdl, start_date, start_date_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: start_date + INTEGER (kind = C_INT) , VALUE :: start_date_size + END SUBROUTINE cxios_get_context_start_date + + FUNCTION cxios_is_defined_context_start_date(context_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_context_start_date + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + END FUNCTION cxios_is_defined_context_start_date + + + SUBROUTINE cxios_set_context_time_origin(context_hdl, time_origin, time_origin_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: time_origin + INTEGER (kind = C_INT) , VALUE :: time_origin_size + END SUBROUTINE cxios_set_context_time_origin + + SUBROUTINE cxios_get_context_time_origin(context_hdl, time_origin, time_origin_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: time_origin + INTEGER (kind = C_INT) , VALUE :: time_origin_size + END SUBROUTINE cxios_get_context_time_origin + + FUNCTION cxios_is_defined_context_time_origin(context_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_context_time_origin + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + END FUNCTION cxios_is_defined_context_time_origin + + + SUBROUTINE cxios_set_context_timestep(context_hdl, timestep, timestep_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: timestep + INTEGER (kind = C_INT) , VALUE :: timestep_size + END SUBROUTINE cxios_set_context_timestep + + SUBROUTINE cxios_get_context_timestep(context_hdl, timestep, timestep_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: timestep + INTEGER (kind = C_INT) , VALUE :: timestep_size + END SUBROUTINE cxios_get_context_timestep + + FUNCTION cxios_is_defined_context_timestep(context_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_context_timestep + INTEGER (kind = C_INTPTR_T), VALUE :: context_hdl + END FUNCTION cxios_is_defined_context_timestep + + + END INTERFACE + +END MODULE context_interface_attr diff --git a/src/interface/fortran_attr/domain_interface_attr.f90 b/src/interface/fortran_attr/domain_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..f11f53309b2fcc0b1e0838d3326329bab5eec3c7 --- /dev/null +++ b/src/interface/fortran_attr/domain_interface_attr.f90 @@ -0,0 +1,754 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE domain_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_domain_bounds_lat(domain_hdl, bounds_lat, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: bounds_lat + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domain_bounds_lat + + SUBROUTINE cxios_get_domain_bounds_lat(domain_hdl, bounds_lat, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: bounds_lat + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domain_bounds_lat + + FUNCTION cxios_is_defined_domain_bounds_lat(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_bounds_lat + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_bounds_lat + + + SUBROUTINE cxios_set_domain_bounds_lon(domain_hdl, bounds_lon, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: bounds_lon + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domain_bounds_lon + + SUBROUTINE cxios_get_domain_bounds_lon(domain_hdl, bounds_lon, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: bounds_lon + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domain_bounds_lon + + FUNCTION cxios_is_defined_domain_bounds_lon(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_bounds_lon + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_bounds_lon + + + SUBROUTINE cxios_set_domain_data_dim(domain_hdl, data_dim) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: data_dim + END SUBROUTINE cxios_set_domain_data_dim + + SUBROUTINE cxios_get_domain_data_dim(domain_hdl, data_dim) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: data_dim + END SUBROUTINE cxios_get_domain_data_dim + + FUNCTION cxios_is_defined_domain_data_dim(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_data_dim + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_data_dim + + + SUBROUTINE cxios_set_domain_data_i_index(domain_hdl, data_i_index, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: data_i_index + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_domain_data_i_index + + SUBROUTINE cxios_get_domain_data_i_index(domain_hdl, data_i_index, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: data_i_index + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_domain_data_i_index + + FUNCTION cxios_is_defined_domain_data_i_index(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_data_i_index + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_data_i_index + + + SUBROUTINE cxios_set_domain_data_ibegin(domain_hdl, data_ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: data_ibegin + END SUBROUTINE cxios_set_domain_data_ibegin + + SUBROUTINE cxios_get_domain_data_ibegin(domain_hdl, data_ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: data_ibegin + END SUBROUTINE cxios_get_domain_data_ibegin + + FUNCTION cxios_is_defined_domain_data_ibegin(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_data_ibegin + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_data_ibegin + + + SUBROUTINE cxios_set_domain_data_j_index(domain_hdl, data_j_index, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: data_j_index + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_domain_data_j_index + + SUBROUTINE cxios_get_domain_data_j_index(domain_hdl, data_j_index, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: data_j_index + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_domain_data_j_index + + FUNCTION cxios_is_defined_domain_data_j_index(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_data_j_index + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_data_j_index + + + SUBROUTINE cxios_set_domain_data_jbegin(domain_hdl, data_jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: data_jbegin + END SUBROUTINE cxios_set_domain_data_jbegin + + SUBROUTINE cxios_get_domain_data_jbegin(domain_hdl, data_jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: data_jbegin + END SUBROUTINE cxios_get_domain_data_jbegin + + FUNCTION cxios_is_defined_domain_data_jbegin(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_data_jbegin + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_data_jbegin + + + SUBROUTINE cxios_set_domain_data_n_index(domain_hdl, data_n_index) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: data_n_index + END SUBROUTINE cxios_set_domain_data_n_index + + SUBROUTINE cxios_get_domain_data_n_index(domain_hdl, data_n_index) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: data_n_index + END SUBROUTINE cxios_get_domain_data_n_index + + FUNCTION cxios_is_defined_domain_data_n_index(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_data_n_index + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_data_n_index + + + SUBROUTINE cxios_set_domain_data_ni(domain_hdl, data_ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: data_ni + END SUBROUTINE cxios_set_domain_data_ni + + SUBROUTINE cxios_get_domain_data_ni(domain_hdl, data_ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: data_ni + END SUBROUTINE cxios_get_domain_data_ni + + FUNCTION cxios_is_defined_domain_data_ni(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_data_ni + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_data_ni + + + SUBROUTINE cxios_set_domain_data_nj(domain_hdl, data_nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: data_nj + END SUBROUTINE cxios_set_domain_data_nj + + SUBROUTINE cxios_get_domain_data_nj(domain_hdl, data_nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: data_nj + END SUBROUTINE cxios_get_domain_data_nj + + FUNCTION cxios_is_defined_domain_data_nj(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_data_nj + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_data_nj + + + SUBROUTINE cxios_set_domain_domain_group_ref(domain_hdl, domain_group_ref, domain_group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_group_ref + INTEGER (kind = C_INT) , VALUE :: domain_group_ref_size + END SUBROUTINE cxios_set_domain_domain_group_ref + + SUBROUTINE cxios_get_domain_domain_group_ref(domain_hdl, domain_group_ref, domain_group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_group_ref + INTEGER (kind = C_INT) , VALUE :: domain_group_ref_size + END SUBROUTINE cxios_get_domain_domain_group_ref + + FUNCTION cxios_is_defined_domain_domain_group_ref(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_domain_group_ref + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_domain_group_ref + + + SUBROUTINE cxios_set_domain_i_index(domain_hdl, i_index, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: i_index + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domain_i_index + + SUBROUTINE cxios_get_domain_i_index(domain_hdl, i_index, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: i_index + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domain_i_index + + FUNCTION cxios_is_defined_domain_i_index(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_i_index + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_i_index + + + SUBROUTINE cxios_set_domain_ibegin(domain_hdl, ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: ibegin + END SUBROUTINE cxios_set_domain_ibegin + + SUBROUTINE cxios_get_domain_ibegin(domain_hdl, ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: ibegin + END SUBROUTINE cxios_get_domain_ibegin + + FUNCTION cxios_is_defined_domain_ibegin(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_ibegin + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_ibegin + + + SUBROUTINE cxios_set_domain_iend(domain_hdl, iend) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: iend + END SUBROUTINE cxios_set_domain_iend + + SUBROUTINE cxios_get_domain_iend(domain_hdl, iend) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: iend + END SUBROUTINE cxios_get_domain_iend + + FUNCTION cxios_is_defined_domain_iend(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_iend + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_iend + + + SUBROUTINE cxios_set_domain_j_index(domain_hdl, j_index, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: j_index + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domain_j_index + + SUBROUTINE cxios_get_domain_j_index(domain_hdl, j_index, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: j_index + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domain_j_index + + FUNCTION cxios_is_defined_domain_j_index(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_j_index + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_j_index + + + SUBROUTINE cxios_set_domain_jbegin(domain_hdl, jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: jbegin + END SUBROUTINE cxios_set_domain_jbegin + + SUBROUTINE cxios_get_domain_jbegin(domain_hdl, jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: jbegin + END SUBROUTINE cxios_get_domain_jbegin + + FUNCTION cxios_is_defined_domain_jbegin(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_jbegin + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_jbegin + + + SUBROUTINE cxios_set_domain_jend(domain_hdl, jend) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: jend + END SUBROUTINE cxios_set_domain_jend + + SUBROUTINE cxios_get_domain_jend(domain_hdl, jend) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: jend + END SUBROUTINE cxios_get_domain_jend + + FUNCTION cxios_is_defined_domain_jend(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_jend + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_jend + + + SUBROUTINE cxios_set_domain_latvalue(domain_hdl, latvalue, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: latvalue + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_domain_latvalue + + SUBROUTINE cxios_get_domain_latvalue(domain_hdl, latvalue, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: latvalue + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_domain_latvalue + + FUNCTION cxios_is_defined_domain_latvalue(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_latvalue + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_latvalue + + + SUBROUTINE cxios_set_domain_long_name(domain_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_set_domain_long_name + + SUBROUTINE cxios_get_domain_long_name(domain_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_get_domain_long_name + + FUNCTION cxios_is_defined_domain_long_name(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_long_name + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_long_name + + + SUBROUTINE cxios_set_domain_lonvalue(domain_hdl, lonvalue, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: lonvalue + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_domain_lonvalue + + SUBROUTINE cxios_get_domain_lonvalue(domain_hdl, lonvalue, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: lonvalue + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_domain_lonvalue + + FUNCTION cxios_is_defined_domain_lonvalue(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_lonvalue + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_lonvalue + + + SUBROUTINE cxios_set_domain_mask(domain_hdl, mask, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + LOGICAL (KIND=C_BOOL) , DIMENSION(*) :: mask + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domain_mask + + SUBROUTINE cxios_get_domain_mask(domain_hdl, mask, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + LOGICAL (KIND=C_BOOL) , DIMENSION(*) :: mask + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domain_mask + + FUNCTION cxios_is_defined_domain_mask(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_mask + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_mask + + + SUBROUTINE cxios_set_domain_name(domain_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_domain_name + + SUBROUTINE cxios_get_domain_name(domain_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_domain_name + + FUNCTION cxios_is_defined_domain_name(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_name + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_name + + + SUBROUTINE cxios_set_domain_ni(domain_hdl, ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: ni + END SUBROUTINE cxios_set_domain_ni + + SUBROUTINE cxios_get_domain_ni(domain_hdl, ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: ni + END SUBROUTINE cxios_get_domain_ni + + FUNCTION cxios_is_defined_domain_ni(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_ni + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_ni + + + SUBROUTINE cxios_set_domain_ni_glo(domain_hdl, ni_glo) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: ni_glo + END SUBROUTINE cxios_set_domain_ni_glo + + SUBROUTINE cxios_get_domain_ni_glo(domain_hdl, ni_glo) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: ni_glo + END SUBROUTINE cxios_get_domain_ni_glo + + FUNCTION cxios_is_defined_domain_ni_glo(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_ni_glo + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_ni_glo + + + SUBROUTINE cxios_set_domain_nj(domain_hdl, nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: nj + END SUBROUTINE cxios_set_domain_nj + + SUBROUTINE cxios_get_domain_nj(domain_hdl, nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: nj + END SUBROUTINE cxios_get_domain_nj + + FUNCTION cxios_is_defined_domain_nj(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_nj + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_nj + + + SUBROUTINE cxios_set_domain_nj_glo(domain_hdl, nj_glo) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: nj_glo + END SUBROUTINE cxios_set_domain_nj_glo + + SUBROUTINE cxios_get_domain_nj_glo(domain_hdl, nj_glo) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: nj_glo + END SUBROUTINE cxios_get_domain_nj_glo + + FUNCTION cxios_is_defined_domain_nj_glo(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_nj_glo + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_nj_glo + + + SUBROUTINE cxios_set_domain_nvertex(domain_hdl, nvertex) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: nvertex + END SUBROUTINE cxios_set_domain_nvertex + + SUBROUTINE cxios_get_domain_nvertex(domain_hdl, nvertex) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: nvertex + END SUBROUTINE cxios_get_domain_nvertex + + FUNCTION cxios_is_defined_domain_nvertex(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_nvertex + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_nvertex + + + SUBROUTINE cxios_set_domain_standard_name(domain_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_set_domain_standard_name + + SUBROUTINE cxios_get_domain_standard_name(domain_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_get_domain_standard_name + + FUNCTION cxios_is_defined_domain_standard_name(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_standard_name + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_standard_name + + + SUBROUTINE cxios_set_domain_type(domain_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_set_domain_type + + SUBROUTINE cxios_get_domain_type(domain_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_get_domain_type + + FUNCTION cxios_is_defined_domain_type(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_type + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_type + + + SUBROUTINE cxios_set_domain_zoom_ibegin(domain_hdl, zoom_ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_ibegin + END SUBROUTINE cxios_set_domain_zoom_ibegin + + SUBROUTINE cxios_get_domain_zoom_ibegin(domain_hdl, zoom_ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: zoom_ibegin + END SUBROUTINE cxios_get_domain_zoom_ibegin + + FUNCTION cxios_is_defined_domain_zoom_ibegin(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_zoom_ibegin + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_zoom_ibegin + + + SUBROUTINE cxios_set_domain_zoom_ibegin_loc(domain_hdl, zoom_ibegin_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_ibegin_loc + END SUBROUTINE cxios_set_domain_zoom_ibegin_loc + + SUBROUTINE cxios_get_domain_zoom_ibegin_loc(domain_hdl, zoom_ibegin_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: zoom_ibegin_loc + END SUBROUTINE cxios_get_domain_zoom_ibegin_loc + + FUNCTION cxios_is_defined_domain_zoom_ibegin_loc(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_zoom_ibegin_loc + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_zoom_ibegin_loc + + + SUBROUTINE cxios_set_domain_zoom_jbegin(domain_hdl, zoom_jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_jbegin + END SUBROUTINE cxios_set_domain_zoom_jbegin + + SUBROUTINE cxios_get_domain_zoom_jbegin(domain_hdl, zoom_jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: zoom_jbegin + END SUBROUTINE cxios_get_domain_zoom_jbegin + + FUNCTION cxios_is_defined_domain_zoom_jbegin(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_zoom_jbegin + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_zoom_jbegin + + + SUBROUTINE cxios_set_domain_zoom_jbegin_loc(domain_hdl, zoom_jbegin_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_jbegin_loc + END SUBROUTINE cxios_set_domain_zoom_jbegin_loc + + SUBROUTINE cxios_get_domain_zoom_jbegin_loc(domain_hdl, zoom_jbegin_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: zoom_jbegin_loc + END SUBROUTINE cxios_get_domain_zoom_jbegin_loc + + FUNCTION cxios_is_defined_domain_zoom_jbegin_loc(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_zoom_jbegin_loc + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_zoom_jbegin_loc + + + SUBROUTINE cxios_set_domain_zoom_ni(domain_hdl, zoom_ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_ni + END SUBROUTINE cxios_set_domain_zoom_ni + + SUBROUTINE cxios_get_domain_zoom_ni(domain_hdl, zoom_ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: zoom_ni + END SUBROUTINE cxios_get_domain_zoom_ni + + FUNCTION cxios_is_defined_domain_zoom_ni(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_zoom_ni + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_zoom_ni + + + SUBROUTINE cxios_set_domain_zoom_ni_loc(domain_hdl, zoom_ni_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_ni_loc + END SUBROUTINE cxios_set_domain_zoom_ni_loc + + SUBROUTINE cxios_get_domain_zoom_ni_loc(domain_hdl, zoom_ni_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: zoom_ni_loc + END SUBROUTINE cxios_get_domain_zoom_ni_loc + + FUNCTION cxios_is_defined_domain_zoom_ni_loc(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_zoom_ni_loc + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_zoom_ni_loc + + + SUBROUTINE cxios_set_domain_zoom_nj(domain_hdl, zoom_nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_nj + END SUBROUTINE cxios_set_domain_zoom_nj + + SUBROUTINE cxios_get_domain_zoom_nj(domain_hdl, zoom_nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: zoom_nj + END SUBROUTINE cxios_get_domain_zoom_nj + + FUNCTION cxios_is_defined_domain_zoom_nj(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_zoom_nj + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_zoom_nj + + + SUBROUTINE cxios_set_domain_zoom_nj_loc(domain_hdl, zoom_nj_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_nj_loc + END SUBROUTINE cxios_set_domain_zoom_nj_loc + + SUBROUTINE cxios_get_domain_zoom_nj_loc(domain_hdl, zoom_nj_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + INTEGER (KIND=C_INT) :: zoom_nj_loc + END SUBROUTINE cxios_get_domain_zoom_nj_loc + + FUNCTION cxios_is_defined_domain_zoom_nj_loc(domain_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domain_zoom_nj_loc + INTEGER (kind = C_INTPTR_T), VALUE :: domain_hdl + END FUNCTION cxios_is_defined_domain_zoom_nj_loc + + + END INTERFACE + +END MODULE domain_interface_attr diff --git a/src/interface/fortran_attr/domaingroup_interface_attr.f90 b/src/interface/fortran_attr/domaingroup_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..dc292c6b1b1e1da2507768151a6a9b4bb85443f8 --- /dev/null +++ b/src/interface/fortran_attr/domaingroup_interface_attr.f90 @@ -0,0 +1,775 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE domaingroup_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_domaingroup_bounds_lat(domaingroup_hdl, bounds_lat, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: bounds_lat + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domaingroup_bounds_lat + + SUBROUTINE cxios_get_domaingroup_bounds_lat(domaingroup_hdl, bounds_lat, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: bounds_lat + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domaingroup_bounds_lat + + FUNCTION cxios_is_defined_domaingroup_bounds_lat(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_bounds_lat + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_bounds_lat + + + SUBROUTINE cxios_set_domaingroup_bounds_lon(domaingroup_hdl, bounds_lon, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: bounds_lon + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domaingroup_bounds_lon + + SUBROUTINE cxios_get_domaingroup_bounds_lon(domaingroup_hdl, bounds_lon, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: bounds_lon + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domaingroup_bounds_lon + + FUNCTION cxios_is_defined_domaingroup_bounds_lon(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_bounds_lon + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_bounds_lon + + + SUBROUTINE cxios_set_domaingroup_data_dim(domaingroup_hdl, data_dim) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: data_dim + END SUBROUTINE cxios_set_domaingroup_data_dim + + SUBROUTINE cxios_get_domaingroup_data_dim(domaingroup_hdl, data_dim) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: data_dim + END SUBROUTINE cxios_get_domaingroup_data_dim + + FUNCTION cxios_is_defined_domaingroup_data_dim(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_data_dim + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_data_dim + + + SUBROUTINE cxios_set_domaingroup_data_i_index(domaingroup_hdl, data_i_index, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: data_i_index + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_domaingroup_data_i_index + + SUBROUTINE cxios_get_domaingroup_data_i_index(domaingroup_hdl, data_i_index, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: data_i_index + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_domaingroup_data_i_index + + FUNCTION cxios_is_defined_domaingroup_data_i_index(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_data_i_index + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_data_i_index + + + SUBROUTINE cxios_set_domaingroup_data_ibegin(domaingroup_hdl, data_ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: data_ibegin + END SUBROUTINE cxios_set_domaingroup_data_ibegin + + SUBROUTINE cxios_get_domaingroup_data_ibegin(domaingroup_hdl, data_ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: data_ibegin + END SUBROUTINE cxios_get_domaingroup_data_ibegin + + FUNCTION cxios_is_defined_domaingroup_data_ibegin(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_data_ibegin + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_data_ibegin + + + SUBROUTINE cxios_set_domaingroup_data_j_index(domaingroup_hdl, data_j_index, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: data_j_index + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_domaingroup_data_j_index + + SUBROUTINE cxios_get_domaingroup_data_j_index(domaingroup_hdl, data_j_index, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: data_j_index + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_domaingroup_data_j_index + + FUNCTION cxios_is_defined_domaingroup_data_j_index(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_data_j_index + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_data_j_index + + + SUBROUTINE cxios_set_domaingroup_data_jbegin(domaingroup_hdl, data_jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: data_jbegin + END SUBROUTINE cxios_set_domaingroup_data_jbegin + + SUBROUTINE cxios_get_domaingroup_data_jbegin(domaingroup_hdl, data_jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: data_jbegin + END SUBROUTINE cxios_get_domaingroup_data_jbegin + + FUNCTION cxios_is_defined_domaingroup_data_jbegin(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_data_jbegin + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_data_jbegin + + + SUBROUTINE cxios_set_domaingroup_data_n_index(domaingroup_hdl, data_n_index) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: data_n_index + END SUBROUTINE cxios_set_domaingroup_data_n_index + + SUBROUTINE cxios_get_domaingroup_data_n_index(domaingroup_hdl, data_n_index) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: data_n_index + END SUBROUTINE cxios_get_domaingroup_data_n_index + + FUNCTION cxios_is_defined_domaingroup_data_n_index(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_data_n_index + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_data_n_index + + + SUBROUTINE cxios_set_domaingroup_data_ni(domaingroup_hdl, data_ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: data_ni + END SUBROUTINE cxios_set_domaingroup_data_ni + + SUBROUTINE cxios_get_domaingroup_data_ni(domaingroup_hdl, data_ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: data_ni + END SUBROUTINE cxios_get_domaingroup_data_ni + + FUNCTION cxios_is_defined_domaingroup_data_ni(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_data_ni + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_data_ni + + + SUBROUTINE cxios_set_domaingroup_data_nj(domaingroup_hdl, data_nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: data_nj + END SUBROUTINE cxios_set_domaingroup_data_nj + + SUBROUTINE cxios_get_domaingroup_data_nj(domaingroup_hdl, data_nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: data_nj + END SUBROUTINE cxios_get_domaingroup_data_nj + + FUNCTION cxios_is_defined_domaingroup_data_nj(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_data_nj + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_data_nj + + + SUBROUTINE cxios_set_domaingroup_domain_group_ref(domaingroup_hdl, domain_group_ref, domain_group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_group_ref + INTEGER (kind = C_INT) , VALUE :: domain_group_ref_size + END SUBROUTINE cxios_set_domaingroup_domain_group_ref + + SUBROUTINE cxios_get_domaingroup_domain_group_ref(domaingroup_hdl, domain_group_ref, domain_group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_group_ref + INTEGER (kind = C_INT) , VALUE :: domain_group_ref_size + END SUBROUTINE cxios_get_domaingroup_domain_group_ref + + FUNCTION cxios_is_defined_domaingroup_domain_group_ref(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_domain_group_ref + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_domain_group_ref + + + SUBROUTINE cxios_set_domaingroup_group_ref(domaingroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_set_domaingroup_group_ref + + SUBROUTINE cxios_get_domaingroup_group_ref(domaingroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_get_domaingroup_group_ref + + FUNCTION cxios_is_defined_domaingroup_group_ref(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_group_ref + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_group_ref + + + SUBROUTINE cxios_set_domaingroup_i_index(domaingroup_hdl, i_index, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: i_index + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domaingroup_i_index + + SUBROUTINE cxios_get_domaingroup_i_index(domaingroup_hdl, i_index, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: i_index + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domaingroup_i_index + + FUNCTION cxios_is_defined_domaingroup_i_index(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_i_index + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_i_index + + + SUBROUTINE cxios_set_domaingroup_ibegin(domaingroup_hdl, ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: ibegin + END SUBROUTINE cxios_set_domaingroup_ibegin + + SUBROUTINE cxios_get_domaingroup_ibegin(domaingroup_hdl, ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: ibegin + END SUBROUTINE cxios_get_domaingroup_ibegin + + FUNCTION cxios_is_defined_domaingroup_ibegin(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_ibegin + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_ibegin + + + SUBROUTINE cxios_set_domaingroup_iend(domaingroup_hdl, iend) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: iend + END SUBROUTINE cxios_set_domaingroup_iend + + SUBROUTINE cxios_get_domaingroup_iend(domaingroup_hdl, iend) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: iend + END SUBROUTINE cxios_get_domaingroup_iend + + FUNCTION cxios_is_defined_domaingroup_iend(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_iend + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_iend + + + SUBROUTINE cxios_set_domaingroup_j_index(domaingroup_hdl, j_index, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: j_index + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domaingroup_j_index + + SUBROUTINE cxios_get_domaingroup_j_index(domaingroup_hdl, j_index, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , DIMENSION(*) :: j_index + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domaingroup_j_index + + FUNCTION cxios_is_defined_domaingroup_j_index(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_j_index + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_j_index + + + SUBROUTINE cxios_set_domaingroup_jbegin(domaingroup_hdl, jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: jbegin + END SUBROUTINE cxios_set_domaingroup_jbegin + + SUBROUTINE cxios_get_domaingroup_jbegin(domaingroup_hdl, jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: jbegin + END SUBROUTINE cxios_get_domaingroup_jbegin + + FUNCTION cxios_is_defined_domaingroup_jbegin(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_jbegin + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_jbegin + + + SUBROUTINE cxios_set_domaingroup_jend(domaingroup_hdl, jend) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: jend + END SUBROUTINE cxios_set_domaingroup_jend + + SUBROUTINE cxios_get_domaingroup_jend(domaingroup_hdl, jend) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: jend + END SUBROUTINE cxios_get_domaingroup_jend + + FUNCTION cxios_is_defined_domaingroup_jend(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_jend + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_jend + + + SUBROUTINE cxios_set_domaingroup_latvalue(domaingroup_hdl, latvalue, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: latvalue + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_domaingroup_latvalue + + SUBROUTINE cxios_get_domaingroup_latvalue(domaingroup_hdl, latvalue, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: latvalue + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_domaingroup_latvalue + + FUNCTION cxios_is_defined_domaingroup_latvalue(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_latvalue + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_latvalue + + + SUBROUTINE cxios_set_domaingroup_long_name(domaingroup_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_set_domaingroup_long_name + + SUBROUTINE cxios_get_domaingroup_long_name(domaingroup_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_get_domaingroup_long_name + + FUNCTION cxios_is_defined_domaingroup_long_name(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_long_name + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_long_name + + + SUBROUTINE cxios_set_domaingroup_lonvalue(domaingroup_hdl, lonvalue, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: lonvalue + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_set_domaingroup_lonvalue + + SUBROUTINE cxios_get_domaingroup_lonvalue(domaingroup_hdl, lonvalue, extent1) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + REAL (KIND=C_DOUBLE) , DIMENSION(*) :: lonvalue + INTEGER (kind = C_INT), VALUE :: extent1 + END SUBROUTINE cxios_get_domaingroup_lonvalue + + FUNCTION cxios_is_defined_domaingroup_lonvalue(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_lonvalue + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_lonvalue + + + SUBROUTINE cxios_set_domaingroup_mask(domaingroup_hdl, mask, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + LOGICAL (KIND=C_BOOL) , DIMENSION(*) :: mask + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_set_domaingroup_mask + + SUBROUTINE cxios_get_domaingroup_mask(domaingroup_hdl, mask, extent1, extent2) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + LOGICAL (KIND=C_BOOL) , DIMENSION(*) :: mask + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + END SUBROUTINE cxios_get_domaingroup_mask + + FUNCTION cxios_is_defined_domaingroup_mask(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_mask + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_mask + + + SUBROUTINE cxios_set_domaingroup_name(domaingroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_domaingroup_name + + SUBROUTINE cxios_get_domaingroup_name(domaingroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_domaingroup_name + + FUNCTION cxios_is_defined_domaingroup_name(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_name + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_name + + + SUBROUTINE cxios_set_domaingroup_ni(domaingroup_hdl, ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: ni + END SUBROUTINE cxios_set_domaingroup_ni + + SUBROUTINE cxios_get_domaingroup_ni(domaingroup_hdl, ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: ni + END SUBROUTINE cxios_get_domaingroup_ni + + FUNCTION cxios_is_defined_domaingroup_ni(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_ni + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_ni + + + SUBROUTINE cxios_set_domaingroup_ni_glo(domaingroup_hdl, ni_glo) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: ni_glo + END SUBROUTINE cxios_set_domaingroup_ni_glo + + SUBROUTINE cxios_get_domaingroup_ni_glo(domaingroup_hdl, ni_glo) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: ni_glo + END SUBROUTINE cxios_get_domaingroup_ni_glo + + FUNCTION cxios_is_defined_domaingroup_ni_glo(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_ni_glo + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_ni_glo + + + SUBROUTINE cxios_set_domaingroup_nj(domaingroup_hdl, nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: nj + END SUBROUTINE cxios_set_domaingroup_nj + + SUBROUTINE cxios_get_domaingroup_nj(domaingroup_hdl, nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: nj + END SUBROUTINE cxios_get_domaingroup_nj + + FUNCTION cxios_is_defined_domaingroup_nj(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_nj + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_nj + + + SUBROUTINE cxios_set_domaingroup_nj_glo(domaingroup_hdl, nj_glo) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: nj_glo + END SUBROUTINE cxios_set_domaingroup_nj_glo + + SUBROUTINE cxios_get_domaingroup_nj_glo(domaingroup_hdl, nj_glo) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: nj_glo + END SUBROUTINE cxios_get_domaingroup_nj_glo + + FUNCTION cxios_is_defined_domaingroup_nj_glo(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_nj_glo + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_nj_glo + + + SUBROUTINE cxios_set_domaingroup_nvertex(domaingroup_hdl, nvertex) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: nvertex + END SUBROUTINE cxios_set_domaingroup_nvertex + + SUBROUTINE cxios_get_domaingroup_nvertex(domaingroup_hdl, nvertex) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: nvertex + END SUBROUTINE cxios_get_domaingroup_nvertex + + FUNCTION cxios_is_defined_domaingroup_nvertex(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_nvertex + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_nvertex + + + SUBROUTINE cxios_set_domaingroup_standard_name(domaingroup_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_set_domaingroup_standard_name + + SUBROUTINE cxios_get_domaingroup_standard_name(domaingroup_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_get_domaingroup_standard_name + + FUNCTION cxios_is_defined_domaingroup_standard_name(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_standard_name + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_standard_name + + + SUBROUTINE cxios_set_domaingroup_type(domaingroup_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_set_domaingroup_type + + SUBROUTINE cxios_get_domaingroup_type(domaingroup_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_get_domaingroup_type + + FUNCTION cxios_is_defined_domaingroup_type(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_type + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_type + + + SUBROUTINE cxios_set_domaingroup_zoom_ibegin(domaingroup_hdl, zoom_ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_ibegin + END SUBROUTINE cxios_set_domaingroup_zoom_ibegin + + SUBROUTINE cxios_get_domaingroup_zoom_ibegin(domaingroup_hdl, zoom_ibegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: zoom_ibegin + END SUBROUTINE cxios_get_domaingroup_zoom_ibegin + + FUNCTION cxios_is_defined_domaingroup_zoom_ibegin(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_zoom_ibegin + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_zoom_ibegin + + + SUBROUTINE cxios_set_domaingroup_zoom_ibegin_loc(domaingroup_hdl, zoom_ibegin_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_ibegin_loc + END SUBROUTINE cxios_set_domaingroup_zoom_ibegin_loc + + SUBROUTINE cxios_get_domaingroup_zoom_ibegin_loc(domaingroup_hdl, zoom_ibegin_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: zoom_ibegin_loc + END SUBROUTINE cxios_get_domaingroup_zoom_ibegin_loc + + FUNCTION cxios_is_defined_domaingroup_zoom_ibegin_loc(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_zoom_ibegin_loc + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_zoom_ibegin_loc + + + SUBROUTINE cxios_set_domaingroup_zoom_jbegin(domaingroup_hdl, zoom_jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_jbegin + END SUBROUTINE cxios_set_domaingroup_zoom_jbegin + + SUBROUTINE cxios_get_domaingroup_zoom_jbegin(domaingroup_hdl, zoom_jbegin) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: zoom_jbegin + END SUBROUTINE cxios_get_domaingroup_zoom_jbegin + + FUNCTION cxios_is_defined_domaingroup_zoom_jbegin(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_zoom_jbegin + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_zoom_jbegin + + + SUBROUTINE cxios_set_domaingroup_zoom_jbegin_loc(domaingroup_hdl, zoom_jbegin_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_jbegin_loc + END SUBROUTINE cxios_set_domaingroup_zoom_jbegin_loc + + SUBROUTINE cxios_get_domaingroup_zoom_jbegin_loc(domaingroup_hdl, zoom_jbegin_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: zoom_jbegin_loc + END SUBROUTINE cxios_get_domaingroup_zoom_jbegin_loc + + FUNCTION cxios_is_defined_domaingroup_zoom_jbegin_loc(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_zoom_jbegin_loc + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_zoom_jbegin_loc + + + SUBROUTINE cxios_set_domaingroup_zoom_ni(domaingroup_hdl, zoom_ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_ni + END SUBROUTINE cxios_set_domaingroup_zoom_ni + + SUBROUTINE cxios_get_domaingroup_zoom_ni(domaingroup_hdl, zoom_ni) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: zoom_ni + END SUBROUTINE cxios_get_domaingroup_zoom_ni + + FUNCTION cxios_is_defined_domaingroup_zoom_ni(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_zoom_ni + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_zoom_ni + + + SUBROUTINE cxios_set_domaingroup_zoom_ni_loc(domaingroup_hdl, zoom_ni_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_ni_loc + END SUBROUTINE cxios_set_domaingroup_zoom_ni_loc + + SUBROUTINE cxios_get_domaingroup_zoom_ni_loc(domaingroup_hdl, zoom_ni_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: zoom_ni_loc + END SUBROUTINE cxios_get_domaingroup_zoom_ni_loc + + FUNCTION cxios_is_defined_domaingroup_zoom_ni_loc(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_zoom_ni_loc + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_zoom_ni_loc + + + SUBROUTINE cxios_set_domaingroup_zoom_nj(domaingroup_hdl, zoom_nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_nj + END SUBROUTINE cxios_set_domaingroup_zoom_nj + + SUBROUTINE cxios_get_domaingroup_zoom_nj(domaingroup_hdl, zoom_nj) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: zoom_nj + END SUBROUTINE cxios_get_domaingroup_zoom_nj + + FUNCTION cxios_is_defined_domaingroup_zoom_nj(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_zoom_nj + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_zoom_nj + + + SUBROUTINE cxios_set_domaingroup_zoom_nj_loc(domaingroup_hdl, zoom_nj_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) , VALUE :: zoom_nj_loc + END SUBROUTINE cxios_set_domaingroup_zoom_nj_loc + + SUBROUTINE cxios_get_domaingroup_zoom_nj_loc(domaingroup_hdl, zoom_nj_loc) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + INTEGER (KIND=C_INT) :: zoom_nj_loc + END SUBROUTINE cxios_get_domaingroup_zoom_nj_loc + + FUNCTION cxios_is_defined_domaingroup_zoom_nj_loc(domaingroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_domaingroup_zoom_nj_loc + INTEGER (kind = C_INTPTR_T), VALUE :: domaingroup_hdl + END FUNCTION cxios_is_defined_domaingroup_zoom_nj_loc + + + END INTERFACE + +END MODULE domaingroup_interface_attr diff --git a/src/interface/fortran_attr/field_interface_attr.f90 b/src/interface/fortran_attr/field_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..981f880b3550144deef564ed3dbd9c4491fd9cd1 --- /dev/null +++ b/src/interface/fortran_attr/field_interface_attr.f90 @@ -0,0 +1,415 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE field_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_field_add_offset(field_hdl, add_offset) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) , VALUE :: add_offset + END SUBROUTINE cxios_set_field_add_offset + + SUBROUTINE cxios_get_field_add_offset(field_hdl, add_offset) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) :: add_offset + END SUBROUTINE cxios_get_field_add_offset + + FUNCTION cxios_is_defined_field_add_offset(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_add_offset + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_add_offset + + + SUBROUTINE cxios_set_field_axis_ref(field_hdl, axis_ref, axis_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: axis_ref + INTEGER (kind = C_INT) , VALUE :: axis_ref_size + END SUBROUTINE cxios_set_field_axis_ref + + SUBROUTINE cxios_get_field_axis_ref(field_hdl, axis_ref, axis_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: axis_ref + INTEGER (kind = C_INT) , VALUE :: axis_ref_size + END SUBROUTINE cxios_get_field_axis_ref + + FUNCTION cxios_is_defined_field_axis_ref(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_axis_ref + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_axis_ref + + + SUBROUTINE cxios_set_field_default_value(field_hdl, default_value) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) , VALUE :: default_value + END SUBROUTINE cxios_set_field_default_value + + SUBROUTINE cxios_get_field_default_value(field_hdl, default_value) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) :: default_value + END SUBROUTINE cxios_get_field_default_value + + FUNCTION cxios_is_defined_field_default_value(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_default_value + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_default_value + + + SUBROUTINE cxios_set_field_detect_missing_value(field_hdl, detect_missing_value) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + LOGICAL (KIND=C_BOOL) , VALUE :: detect_missing_value + END SUBROUTINE cxios_set_field_detect_missing_value + + SUBROUTINE cxios_get_field_detect_missing_value(field_hdl, detect_missing_value) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + LOGICAL (KIND=C_BOOL) :: detect_missing_value + END SUBROUTINE cxios_get_field_detect_missing_value + + FUNCTION cxios_is_defined_field_detect_missing_value(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_detect_missing_value + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_detect_missing_value + + + SUBROUTINE cxios_set_field_domain_ref(field_hdl, domain_ref, domain_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_ref + INTEGER (kind = C_INT) , VALUE :: domain_ref_size + END SUBROUTINE cxios_set_field_domain_ref + + SUBROUTINE cxios_get_field_domain_ref(field_hdl, domain_ref, domain_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_ref + INTEGER (kind = C_INT) , VALUE :: domain_ref_size + END SUBROUTINE cxios_get_field_domain_ref + + FUNCTION cxios_is_defined_field_domain_ref(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_domain_ref + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_domain_ref + + + SUBROUTINE cxios_set_field_enabled(field_hdl, enabled) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + LOGICAL (KIND=C_BOOL) , VALUE :: enabled + END SUBROUTINE cxios_set_field_enabled + + SUBROUTINE cxios_get_field_enabled(field_hdl, enabled) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + LOGICAL (KIND=C_BOOL) :: enabled + END SUBROUTINE cxios_get_field_enabled + + FUNCTION cxios_is_defined_field_enabled(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_enabled + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_enabled + + + SUBROUTINE cxios_set_field_field_ref(field_hdl, field_ref, field_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: field_ref + INTEGER (kind = C_INT) , VALUE :: field_ref_size + END SUBROUTINE cxios_set_field_field_ref + + SUBROUTINE cxios_get_field_field_ref(field_hdl, field_ref, field_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: field_ref + INTEGER (kind = C_INT) , VALUE :: field_ref_size + END SUBROUTINE cxios_get_field_field_ref + + FUNCTION cxios_is_defined_field_field_ref(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_field_ref + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_field_ref + + + SUBROUTINE cxios_set_field_freq_offset(field_hdl, freq_offset, freq_offset_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: freq_offset + INTEGER (kind = C_INT) , VALUE :: freq_offset_size + END SUBROUTINE cxios_set_field_freq_offset + + SUBROUTINE cxios_get_field_freq_offset(field_hdl, freq_offset, freq_offset_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: freq_offset + INTEGER (kind = C_INT) , VALUE :: freq_offset_size + END SUBROUTINE cxios_get_field_freq_offset + + FUNCTION cxios_is_defined_field_freq_offset(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_freq_offset + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_freq_offset + + + SUBROUTINE cxios_set_field_freq_op(field_hdl, freq_op, freq_op_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: freq_op + INTEGER (kind = C_INT) , VALUE :: freq_op_size + END SUBROUTINE cxios_set_field_freq_op + + SUBROUTINE cxios_get_field_freq_op(field_hdl, freq_op, freq_op_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: freq_op + INTEGER (kind = C_INT) , VALUE :: freq_op_size + END SUBROUTINE cxios_get_field_freq_op + + FUNCTION cxios_is_defined_field_freq_op(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_freq_op + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_freq_op + + + SUBROUTINE cxios_set_field_grid_ref(field_hdl, grid_ref, grid_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: grid_ref + INTEGER (kind = C_INT) , VALUE :: grid_ref_size + END SUBROUTINE cxios_set_field_grid_ref + + SUBROUTINE cxios_get_field_grid_ref(field_hdl, grid_ref, grid_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: grid_ref + INTEGER (kind = C_INT) , VALUE :: grid_ref_size + END SUBROUTINE cxios_get_field_grid_ref + + FUNCTION cxios_is_defined_field_grid_ref(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_grid_ref + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_grid_ref + + + SUBROUTINE cxios_set_field_level(field_hdl, level) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + INTEGER (KIND=C_INT) , VALUE :: level + END SUBROUTINE cxios_set_field_level + + SUBROUTINE cxios_get_field_level(field_hdl, level) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + INTEGER (KIND=C_INT) :: level + END SUBROUTINE cxios_get_field_level + + FUNCTION cxios_is_defined_field_level(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_level + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_level + + + SUBROUTINE cxios_set_field_long_name(field_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_set_field_long_name + + SUBROUTINE cxios_get_field_long_name(field_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_get_field_long_name + + FUNCTION cxios_is_defined_field_long_name(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_long_name + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_long_name + + + SUBROUTINE cxios_set_field_name(field_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_field_name + + SUBROUTINE cxios_get_field_name(field_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_field_name + + FUNCTION cxios_is_defined_field_name(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_name + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_name + + + SUBROUTINE cxios_set_field_operation(field_hdl, operation, operation_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: operation + INTEGER (kind = C_INT) , VALUE :: operation_size + END SUBROUTINE cxios_set_field_operation + + SUBROUTINE cxios_get_field_operation(field_hdl, operation, operation_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: operation + INTEGER (kind = C_INT) , VALUE :: operation_size + END SUBROUTINE cxios_get_field_operation + + FUNCTION cxios_is_defined_field_operation(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_operation + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_operation + + + SUBROUTINE cxios_set_field_prec(field_hdl, prec) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + INTEGER (KIND=C_INT) , VALUE :: prec + END SUBROUTINE cxios_set_field_prec + + SUBROUTINE cxios_get_field_prec(field_hdl, prec) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + INTEGER (KIND=C_INT) :: prec + END SUBROUTINE cxios_get_field_prec + + FUNCTION cxios_is_defined_field_prec(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_prec + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_prec + + + SUBROUTINE cxios_set_field_scale_factor(field_hdl, scale_factor) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) , VALUE :: scale_factor + END SUBROUTINE cxios_set_field_scale_factor + + SUBROUTINE cxios_get_field_scale_factor(field_hdl, scale_factor) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) :: scale_factor + END SUBROUTINE cxios_get_field_scale_factor + + FUNCTION cxios_is_defined_field_scale_factor(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_scale_factor + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_scale_factor + + + SUBROUTINE cxios_set_field_standard_name(field_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_set_field_standard_name + + SUBROUTINE cxios_get_field_standard_name(field_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_get_field_standard_name + + FUNCTION cxios_is_defined_field_standard_name(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_standard_name + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_standard_name + + + SUBROUTINE cxios_set_field_unit(field_hdl, unit, unit_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: unit + INTEGER (kind = C_INT) , VALUE :: unit_size + END SUBROUTINE cxios_set_field_unit + + SUBROUTINE cxios_get_field_unit(field_hdl, unit, unit_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: unit + INTEGER (kind = C_INT) , VALUE :: unit_size + END SUBROUTINE cxios_get_field_unit + + FUNCTION cxios_is_defined_field_unit(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_unit + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_unit + + + SUBROUTINE cxios_set_field_valid_max(field_hdl, valid_max) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) , VALUE :: valid_max + END SUBROUTINE cxios_set_field_valid_max + + SUBROUTINE cxios_get_field_valid_max(field_hdl, valid_max) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) :: valid_max + END SUBROUTINE cxios_get_field_valid_max + + FUNCTION cxios_is_defined_field_valid_max(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_valid_max + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_valid_max + + + SUBROUTINE cxios_set_field_valid_min(field_hdl, valid_min) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) , VALUE :: valid_min + END SUBROUTINE cxios_set_field_valid_min + + SUBROUTINE cxios_get_field_valid_min(field_hdl, valid_min) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + REAL (KIND=C_DOUBLE) :: valid_min + END SUBROUTINE cxios_get_field_valid_min + + FUNCTION cxios_is_defined_field_valid_min(field_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_field_valid_min + INTEGER (kind = C_INTPTR_T), VALUE :: field_hdl + END FUNCTION cxios_is_defined_field_valid_min + + + END INTERFACE + +END MODULE field_interface_attr diff --git a/src/interface/fortran_attr/fieldgroup_interface_attr.f90 b/src/interface/fortran_attr/fieldgroup_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..d6eeaff63039df2d0d74dd62683aa4cd340eef20 --- /dev/null +++ b/src/interface/fortran_attr/fieldgroup_interface_attr.f90 @@ -0,0 +1,436 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE fieldgroup_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_fieldgroup_add_offset(fieldgroup_hdl, add_offset) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) , VALUE :: add_offset + END SUBROUTINE cxios_set_fieldgroup_add_offset + + SUBROUTINE cxios_get_fieldgroup_add_offset(fieldgroup_hdl, add_offset) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) :: add_offset + END SUBROUTINE cxios_get_fieldgroup_add_offset + + FUNCTION cxios_is_defined_fieldgroup_add_offset(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_add_offset + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_add_offset + + + SUBROUTINE cxios_set_fieldgroup_axis_ref(fieldgroup_hdl, axis_ref, axis_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: axis_ref + INTEGER (kind = C_INT) , VALUE :: axis_ref_size + END SUBROUTINE cxios_set_fieldgroup_axis_ref + + SUBROUTINE cxios_get_fieldgroup_axis_ref(fieldgroup_hdl, axis_ref, axis_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: axis_ref + INTEGER (kind = C_INT) , VALUE :: axis_ref_size + END SUBROUTINE cxios_get_fieldgroup_axis_ref + + FUNCTION cxios_is_defined_fieldgroup_axis_ref(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_axis_ref + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_axis_ref + + + SUBROUTINE cxios_set_fieldgroup_default_value(fieldgroup_hdl, default_value) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) , VALUE :: default_value + END SUBROUTINE cxios_set_fieldgroup_default_value + + SUBROUTINE cxios_get_fieldgroup_default_value(fieldgroup_hdl, default_value) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) :: default_value + END SUBROUTINE cxios_get_fieldgroup_default_value + + FUNCTION cxios_is_defined_fieldgroup_default_value(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_default_value + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_default_value + + + SUBROUTINE cxios_set_fieldgroup_detect_missing_value(fieldgroup_hdl, detect_missing_value) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + LOGICAL (KIND=C_BOOL) , VALUE :: detect_missing_value + END SUBROUTINE cxios_set_fieldgroup_detect_missing_value + + SUBROUTINE cxios_get_fieldgroup_detect_missing_value(fieldgroup_hdl, detect_missing_value) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + LOGICAL (KIND=C_BOOL) :: detect_missing_value + END SUBROUTINE cxios_get_fieldgroup_detect_missing_value + + FUNCTION cxios_is_defined_fieldgroup_detect_missing_value(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_detect_missing_value + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_detect_missing_value + + + SUBROUTINE cxios_set_fieldgroup_domain_ref(fieldgroup_hdl, domain_ref, domain_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_ref + INTEGER (kind = C_INT) , VALUE :: domain_ref_size + END SUBROUTINE cxios_set_fieldgroup_domain_ref + + SUBROUTINE cxios_get_fieldgroup_domain_ref(fieldgroup_hdl, domain_ref, domain_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_ref + INTEGER (kind = C_INT) , VALUE :: domain_ref_size + END SUBROUTINE cxios_get_fieldgroup_domain_ref + + FUNCTION cxios_is_defined_fieldgroup_domain_ref(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_domain_ref + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_domain_ref + + + SUBROUTINE cxios_set_fieldgroup_enabled(fieldgroup_hdl, enabled) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + LOGICAL (KIND=C_BOOL) , VALUE :: enabled + END SUBROUTINE cxios_set_fieldgroup_enabled + + SUBROUTINE cxios_get_fieldgroup_enabled(fieldgroup_hdl, enabled) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + LOGICAL (KIND=C_BOOL) :: enabled + END SUBROUTINE cxios_get_fieldgroup_enabled + + FUNCTION cxios_is_defined_fieldgroup_enabled(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_enabled + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_enabled + + + SUBROUTINE cxios_set_fieldgroup_field_ref(fieldgroup_hdl, field_ref, field_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: field_ref + INTEGER (kind = C_INT) , VALUE :: field_ref_size + END SUBROUTINE cxios_set_fieldgroup_field_ref + + SUBROUTINE cxios_get_fieldgroup_field_ref(fieldgroup_hdl, field_ref, field_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: field_ref + INTEGER (kind = C_INT) , VALUE :: field_ref_size + END SUBROUTINE cxios_get_fieldgroup_field_ref + + FUNCTION cxios_is_defined_fieldgroup_field_ref(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_field_ref + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_field_ref + + + SUBROUTINE cxios_set_fieldgroup_freq_offset(fieldgroup_hdl, freq_offset, freq_offset_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: freq_offset + INTEGER (kind = C_INT) , VALUE :: freq_offset_size + END SUBROUTINE cxios_set_fieldgroup_freq_offset + + SUBROUTINE cxios_get_fieldgroup_freq_offset(fieldgroup_hdl, freq_offset, freq_offset_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: freq_offset + INTEGER (kind = C_INT) , VALUE :: freq_offset_size + END SUBROUTINE cxios_get_fieldgroup_freq_offset + + FUNCTION cxios_is_defined_fieldgroup_freq_offset(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_freq_offset + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_freq_offset + + + SUBROUTINE cxios_set_fieldgroup_freq_op(fieldgroup_hdl, freq_op, freq_op_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: freq_op + INTEGER (kind = C_INT) , VALUE :: freq_op_size + END SUBROUTINE cxios_set_fieldgroup_freq_op + + SUBROUTINE cxios_get_fieldgroup_freq_op(fieldgroup_hdl, freq_op, freq_op_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: freq_op + INTEGER (kind = C_INT) , VALUE :: freq_op_size + END SUBROUTINE cxios_get_fieldgroup_freq_op + + FUNCTION cxios_is_defined_fieldgroup_freq_op(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_freq_op + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_freq_op + + + SUBROUTINE cxios_set_fieldgroup_grid_ref(fieldgroup_hdl, grid_ref, grid_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: grid_ref + INTEGER (kind = C_INT) , VALUE :: grid_ref_size + END SUBROUTINE cxios_set_fieldgroup_grid_ref + + SUBROUTINE cxios_get_fieldgroup_grid_ref(fieldgroup_hdl, grid_ref, grid_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: grid_ref + INTEGER (kind = C_INT) , VALUE :: grid_ref_size + END SUBROUTINE cxios_get_fieldgroup_grid_ref + + FUNCTION cxios_is_defined_fieldgroup_grid_ref(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_grid_ref + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_grid_ref + + + SUBROUTINE cxios_set_fieldgroup_group_ref(fieldgroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_set_fieldgroup_group_ref + + SUBROUTINE cxios_get_fieldgroup_group_ref(fieldgroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_get_fieldgroup_group_ref + + FUNCTION cxios_is_defined_fieldgroup_group_ref(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_group_ref + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_group_ref + + + SUBROUTINE cxios_set_fieldgroup_level(fieldgroup_hdl, level) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + INTEGER (KIND=C_INT) , VALUE :: level + END SUBROUTINE cxios_set_fieldgroup_level + + SUBROUTINE cxios_get_fieldgroup_level(fieldgroup_hdl, level) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + INTEGER (KIND=C_INT) :: level + END SUBROUTINE cxios_get_fieldgroup_level + + FUNCTION cxios_is_defined_fieldgroup_level(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_level + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_level + + + SUBROUTINE cxios_set_fieldgroup_long_name(fieldgroup_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_set_fieldgroup_long_name + + SUBROUTINE cxios_get_fieldgroup_long_name(fieldgroup_hdl, long_name, long_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: long_name + INTEGER (kind = C_INT) , VALUE :: long_name_size + END SUBROUTINE cxios_get_fieldgroup_long_name + + FUNCTION cxios_is_defined_fieldgroup_long_name(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_long_name + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_long_name + + + SUBROUTINE cxios_set_fieldgroup_name(fieldgroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_fieldgroup_name + + SUBROUTINE cxios_get_fieldgroup_name(fieldgroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_fieldgroup_name + + FUNCTION cxios_is_defined_fieldgroup_name(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_name + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_name + + + SUBROUTINE cxios_set_fieldgroup_operation(fieldgroup_hdl, operation, operation_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: operation + INTEGER (kind = C_INT) , VALUE :: operation_size + END SUBROUTINE cxios_set_fieldgroup_operation + + SUBROUTINE cxios_get_fieldgroup_operation(fieldgroup_hdl, operation, operation_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: operation + INTEGER (kind = C_INT) , VALUE :: operation_size + END SUBROUTINE cxios_get_fieldgroup_operation + + FUNCTION cxios_is_defined_fieldgroup_operation(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_operation + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_operation + + + SUBROUTINE cxios_set_fieldgroup_prec(fieldgroup_hdl, prec) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + INTEGER (KIND=C_INT) , VALUE :: prec + END SUBROUTINE cxios_set_fieldgroup_prec + + SUBROUTINE cxios_get_fieldgroup_prec(fieldgroup_hdl, prec) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + INTEGER (KIND=C_INT) :: prec + END SUBROUTINE cxios_get_fieldgroup_prec + + FUNCTION cxios_is_defined_fieldgroup_prec(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_prec + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_prec + + + SUBROUTINE cxios_set_fieldgroup_scale_factor(fieldgroup_hdl, scale_factor) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) , VALUE :: scale_factor + END SUBROUTINE cxios_set_fieldgroup_scale_factor + + SUBROUTINE cxios_get_fieldgroup_scale_factor(fieldgroup_hdl, scale_factor) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) :: scale_factor + END SUBROUTINE cxios_get_fieldgroup_scale_factor + + FUNCTION cxios_is_defined_fieldgroup_scale_factor(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_scale_factor + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_scale_factor + + + SUBROUTINE cxios_set_fieldgroup_standard_name(fieldgroup_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_set_fieldgroup_standard_name + + SUBROUTINE cxios_get_fieldgroup_standard_name(fieldgroup_hdl, standard_name, standard_name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: standard_name + INTEGER (kind = C_INT) , VALUE :: standard_name_size + END SUBROUTINE cxios_get_fieldgroup_standard_name + + FUNCTION cxios_is_defined_fieldgroup_standard_name(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_standard_name + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_standard_name + + + SUBROUTINE cxios_set_fieldgroup_unit(fieldgroup_hdl, unit, unit_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: unit + INTEGER (kind = C_INT) , VALUE :: unit_size + END SUBROUTINE cxios_set_fieldgroup_unit + + SUBROUTINE cxios_get_fieldgroup_unit(fieldgroup_hdl, unit, unit_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: unit + INTEGER (kind = C_INT) , VALUE :: unit_size + END SUBROUTINE cxios_get_fieldgroup_unit + + FUNCTION cxios_is_defined_fieldgroup_unit(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_unit + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_unit + + + SUBROUTINE cxios_set_fieldgroup_valid_max(fieldgroup_hdl, valid_max) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) , VALUE :: valid_max + END SUBROUTINE cxios_set_fieldgroup_valid_max + + SUBROUTINE cxios_get_fieldgroup_valid_max(fieldgroup_hdl, valid_max) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) :: valid_max + END SUBROUTINE cxios_get_fieldgroup_valid_max + + FUNCTION cxios_is_defined_fieldgroup_valid_max(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_valid_max + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_valid_max + + + SUBROUTINE cxios_set_fieldgroup_valid_min(fieldgroup_hdl, valid_min) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) , VALUE :: valid_min + END SUBROUTINE cxios_set_fieldgroup_valid_min + + SUBROUTINE cxios_get_fieldgroup_valid_min(fieldgroup_hdl, valid_min) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + REAL (KIND=C_DOUBLE) :: valid_min + END SUBROUTINE cxios_get_fieldgroup_valid_min + + FUNCTION cxios_is_defined_fieldgroup_valid_min(fieldgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_fieldgroup_valid_min + INTEGER (kind = C_INTPTR_T), VALUE :: fieldgroup_hdl + END FUNCTION cxios_is_defined_fieldgroup_valid_min + + + END INTERFACE + +END MODULE fieldgroup_interface_attr diff --git a/src/interface/fortran_attr/file_interface_attr.f90 b/src/interface/fortran_attr/file_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..e98b71cfdf04602143ba2447fa2fe537d8363546 --- /dev/null +++ b/src/interface/fortran_attr/file_interface_attr.f90 @@ -0,0 +1,259 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE file_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_file_description(file_hdl, description, description_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: description + INTEGER (kind = C_INT) , VALUE :: description_size + END SUBROUTINE cxios_set_file_description + + SUBROUTINE cxios_get_file_description(file_hdl, description, description_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: description + INTEGER (kind = C_INT) , VALUE :: description_size + END SUBROUTINE cxios_get_file_description + + FUNCTION cxios_is_defined_file_description(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_description + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_description + + + SUBROUTINE cxios_set_file_enabled(file_hdl, enabled) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + LOGICAL (KIND=C_BOOL) , VALUE :: enabled + END SUBROUTINE cxios_set_file_enabled + + SUBROUTINE cxios_get_file_enabled(file_hdl, enabled) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + LOGICAL (KIND=C_BOOL) :: enabled + END SUBROUTINE cxios_get_file_enabled + + FUNCTION cxios_is_defined_file_enabled(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_enabled + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_enabled + + + SUBROUTINE cxios_set_file_min_digits(file_hdl, min_digits) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + INTEGER (KIND=C_INT) , VALUE :: min_digits + END SUBROUTINE cxios_set_file_min_digits + + SUBROUTINE cxios_get_file_min_digits(file_hdl, min_digits) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + INTEGER (KIND=C_INT) :: min_digits + END SUBROUTINE cxios_get_file_min_digits + + FUNCTION cxios_is_defined_file_min_digits(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_min_digits + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_min_digits + + + SUBROUTINE cxios_set_file_name(file_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_file_name + + SUBROUTINE cxios_get_file_name(file_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_file_name + + FUNCTION cxios_is_defined_file_name(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_name + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_name + + + SUBROUTINE cxios_set_file_name_suffix(file_hdl, name_suffix, name_suffix_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name_suffix + INTEGER (kind = C_INT) , VALUE :: name_suffix_size + END SUBROUTINE cxios_set_file_name_suffix + + SUBROUTINE cxios_get_file_name_suffix(file_hdl, name_suffix, name_suffix_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name_suffix + INTEGER (kind = C_INT) , VALUE :: name_suffix_size + END SUBROUTINE cxios_get_file_name_suffix + + FUNCTION cxios_is_defined_file_name_suffix(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_name_suffix + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_name_suffix + + + SUBROUTINE cxios_set_file_output_freq(file_hdl, output_freq, output_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: output_freq + INTEGER (kind = C_INT) , VALUE :: output_freq_size + END SUBROUTINE cxios_set_file_output_freq + + SUBROUTINE cxios_get_file_output_freq(file_hdl, output_freq, output_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: output_freq + INTEGER (kind = C_INT) , VALUE :: output_freq_size + END SUBROUTINE cxios_get_file_output_freq + + FUNCTION cxios_is_defined_file_output_freq(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_output_freq + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_output_freq + + + SUBROUTINE cxios_set_file_output_level(file_hdl, output_level) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + INTEGER (KIND=C_INT) , VALUE :: output_level + END SUBROUTINE cxios_set_file_output_level + + SUBROUTINE cxios_get_file_output_level(file_hdl, output_level) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + INTEGER (KIND=C_INT) :: output_level + END SUBROUTINE cxios_get_file_output_level + + FUNCTION cxios_is_defined_file_output_level(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_output_level + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_output_level + + + SUBROUTINE cxios_set_file_par_access(file_hdl, par_access, par_access_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: par_access + INTEGER (kind = C_INT) , VALUE :: par_access_size + END SUBROUTINE cxios_set_file_par_access + + SUBROUTINE cxios_get_file_par_access(file_hdl, par_access, par_access_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: par_access + INTEGER (kind = C_INT) , VALUE :: par_access_size + END SUBROUTINE cxios_get_file_par_access + + FUNCTION cxios_is_defined_file_par_access(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_par_access + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_par_access + + + SUBROUTINE cxios_set_file_split_freq(file_hdl, split_freq, split_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: split_freq + INTEGER (kind = C_INT) , VALUE :: split_freq_size + END SUBROUTINE cxios_set_file_split_freq + + SUBROUTINE cxios_get_file_split_freq(file_hdl, split_freq, split_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: split_freq + INTEGER (kind = C_INT) , VALUE :: split_freq_size + END SUBROUTINE cxios_get_file_split_freq + + FUNCTION cxios_is_defined_file_split_freq(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_split_freq + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_split_freq + + + SUBROUTINE cxios_set_file_split_freq_format(file_hdl, split_freq_format, split_freq_format_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: split_freq_format + INTEGER (kind = C_INT) , VALUE :: split_freq_format_size + END SUBROUTINE cxios_set_file_split_freq_format + + SUBROUTINE cxios_get_file_split_freq_format(file_hdl, split_freq_format, split_freq_format_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: split_freq_format + INTEGER (kind = C_INT) , VALUE :: split_freq_format_size + END SUBROUTINE cxios_get_file_split_freq_format + + FUNCTION cxios_is_defined_file_split_freq_format(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_split_freq_format + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_split_freq_format + + + SUBROUTINE cxios_set_file_sync_freq(file_hdl, sync_freq, sync_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: sync_freq + INTEGER (kind = C_INT) , VALUE :: sync_freq_size + END SUBROUTINE cxios_set_file_sync_freq + + SUBROUTINE cxios_get_file_sync_freq(file_hdl, sync_freq, sync_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: sync_freq + INTEGER (kind = C_INT) , VALUE :: sync_freq_size + END SUBROUTINE cxios_get_file_sync_freq + + FUNCTION cxios_is_defined_file_sync_freq(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_sync_freq + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_sync_freq + + + SUBROUTINE cxios_set_file_type(file_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_set_file_type + + SUBROUTINE cxios_get_file_type(file_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_get_file_type + + FUNCTION cxios_is_defined_file_type(file_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_file_type + INTEGER (kind = C_INTPTR_T), VALUE :: file_hdl + END FUNCTION cxios_is_defined_file_type + + + END INTERFACE + +END MODULE file_interface_attr diff --git a/src/interface/fortran_attr/filegroup_interface_attr.f90 b/src/interface/fortran_attr/filegroup_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..b0aeadaffa438dbedfb851ca72661e828486e9aa --- /dev/null +++ b/src/interface/fortran_attr/filegroup_interface_attr.f90 @@ -0,0 +1,280 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE filegroup_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_filegroup_description(filegroup_hdl, description, description_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: description + INTEGER (kind = C_INT) , VALUE :: description_size + END SUBROUTINE cxios_set_filegroup_description + + SUBROUTINE cxios_get_filegroup_description(filegroup_hdl, description, description_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: description + INTEGER (kind = C_INT) , VALUE :: description_size + END SUBROUTINE cxios_get_filegroup_description + + FUNCTION cxios_is_defined_filegroup_description(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_description + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_description + + + SUBROUTINE cxios_set_filegroup_enabled(filegroup_hdl, enabled) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + LOGICAL (KIND=C_BOOL) , VALUE :: enabled + END SUBROUTINE cxios_set_filegroup_enabled + + SUBROUTINE cxios_get_filegroup_enabled(filegroup_hdl, enabled) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + LOGICAL (KIND=C_BOOL) :: enabled + END SUBROUTINE cxios_get_filegroup_enabled + + FUNCTION cxios_is_defined_filegroup_enabled(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_enabled + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_enabled + + + SUBROUTINE cxios_set_filegroup_group_ref(filegroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_set_filegroup_group_ref + + SUBROUTINE cxios_get_filegroup_group_ref(filegroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_get_filegroup_group_ref + + FUNCTION cxios_is_defined_filegroup_group_ref(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_group_ref + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_group_ref + + + SUBROUTINE cxios_set_filegroup_min_digits(filegroup_hdl, min_digits) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + INTEGER (KIND=C_INT) , VALUE :: min_digits + END SUBROUTINE cxios_set_filegroup_min_digits + + SUBROUTINE cxios_get_filegroup_min_digits(filegroup_hdl, min_digits) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + INTEGER (KIND=C_INT) :: min_digits + END SUBROUTINE cxios_get_filegroup_min_digits + + FUNCTION cxios_is_defined_filegroup_min_digits(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_min_digits + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_min_digits + + + SUBROUTINE cxios_set_filegroup_name(filegroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_filegroup_name + + SUBROUTINE cxios_get_filegroup_name(filegroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_filegroup_name + + FUNCTION cxios_is_defined_filegroup_name(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_name + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_name + + + SUBROUTINE cxios_set_filegroup_name_suffix(filegroup_hdl, name_suffix, name_suffix_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name_suffix + INTEGER (kind = C_INT) , VALUE :: name_suffix_size + END SUBROUTINE cxios_set_filegroup_name_suffix + + SUBROUTINE cxios_get_filegroup_name_suffix(filegroup_hdl, name_suffix, name_suffix_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name_suffix + INTEGER (kind = C_INT) , VALUE :: name_suffix_size + END SUBROUTINE cxios_get_filegroup_name_suffix + + FUNCTION cxios_is_defined_filegroup_name_suffix(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_name_suffix + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_name_suffix + + + SUBROUTINE cxios_set_filegroup_output_freq(filegroup_hdl, output_freq, output_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: output_freq + INTEGER (kind = C_INT) , VALUE :: output_freq_size + END SUBROUTINE cxios_set_filegroup_output_freq + + SUBROUTINE cxios_get_filegroup_output_freq(filegroup_hdl, output_freq, output_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: output_freq + INTEGER (kind = C_INT) , VALUE :: output_freq_size + END SUBROUTINE cxios_get_filegroup_output_freq + + FUNCTION cxios_is_defined_filegroup_output_freq(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_output_freq + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_output_freq + + + SUBROUTINE cxios_set_filegroup_output_level(filegroup_hdl, output_level) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + INTEGER (KIND=C_INT) , VALUE :: output_level + END SUBROUTINE cxios_set_filegroup_output_level + + SUBROUTINE cxios_get_filegroup_output_level(filegroup_hdl, output_level) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + INTEGER (KIND=C_INT) :: output_level + END SUBROUTINE cxios_get_filegroup_output_level + + FUNCTION cxios_is_defined_filegroup_output_level(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_output_level + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_output_level + + + SUBROUTINE cxios_set_filegroup_par_access(filegroup_hdl, par_access, par_access_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: par_access + INTEGER (kind = C_INT) , VALUE :: par_access_size + END SUBROUTINE cxios_set_filegroup_par_access + + SUBROUTINE cxios_get_filegroup_par_access(filegroup_hdl, par_access, par_access_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: par_access + INTEGER (kind = C_INT) , VALUE :: par_access_size + END SUBROUTINE cxios_get_filegroup_par_access + + FUNCTION cxios_is_defined_filegroup_par_access(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_par_access + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_par_access + + + SUBROUTINE cxios_set_filegroup_split_freq(filegroup_hdl, split_freq, split_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: split_freq + INTEGER (kind = C_INT) , VALUE :: split_freq_size + END SUBROUTINE cxios_set_filegroup_split_freq + + SUBROUTINE cxios_get_filegroup_split_freq(filegroup_hdl, split_freq, split_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: split_freq + INTEGER (kind = C_INT) , VALUE :: split_freq_size + END SUBROUTINE cxios_get_filegroup_split_freq + + FUNCTION cxios_is_defined_filegroup_split_freq(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_split_freq + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_split_freq + + + SUBROUTINE cxios_set_filegroup_split_freq_format(filegroup_hdl, split_freq_format, split_freq_format_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: split_freq_format + INTEGER (kind = C_INT) , VALUE :: split_freq_format_size + END SUBROUTINE cxios_set_filegroup_split_freq_format + + SUBROUTINE cxios_get_filegroup_split_freq_format(filegroup_hdl, split_freq_format, split_freq_format_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: split_freq_format + INTEGER (kind = C_INT) , VALUE :: split_freq_format_size + END SUBROUTINE cxios_get_filegroup_split_freq_format + + FUNCTION cxios_is_defined_filegroup_split_freq_format(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_split_freq_format + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_split_freq_format + + + SUBROUTINE cxios_set_filegroup_sync_freq(filegroup_hdl, sync_freq, sync_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: sync_freq + INTEGER (kind = C_INT) , VALUE :: sync_freq_size + END SUBROUTINE cxios_set_filegroup_sync_freq + + SUBROUTINE cxios_get_filegroup_sync_freq(filegroup_hdl, sync_freq, sync_freq_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: sync_freq + INTEGER (kind = C_INT) , VALUE :: sync_freq_size + END SUBROUTINE cxios_get_filegroup_sync_freq + + FUNCTION cxios_is_defined_filegroup_sync_freq(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_sync_freq + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_sync_freq + + + SUBROUTINE cxios_set_filegroup_type(filegroup_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_set_filegroup_type + + SUBROUTINE cxios_get_filegroup_type(filegroup_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_get_filegroup_type + + FUNCTION cxios_is_defined_filegroup_type(filegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_filegroup_type + INTEGER (kind = C_INTPTR_T), VALUE :: filegroup_hdl + END FUNCTION cxios_is_defined_filegroup_type + + + END INTERFACE + +END MODULE filegroup_interface_attr diff --git a/src/interface/fortran_attr/grid_interface_attr.f90 b/src/interface/fortran_attr/grid_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..81891858991ffd40800863c3b36821310d780c18 --- /dev/null +++ b/src/interface/fortran_attr/grid_interface_attr.f90 @@ -0,0 +1,122 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE grid_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_grid_axis_ref(grid_hdl, axis_ref, axis_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: axis_ref + INTEGER (kind = C_INT) , VALUE :: axis_ref_size + END SUBROUTINE cxios_set_grid_axis_ref + + SUBROUTINE cxios_get_grid_axis_ref(grid_hdl, axis_ref, axis_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: axis_ref + INTEGER (kind = C_INT) , VALUE :: axis_ref_size + END SUBROUTINE cxios_get_grid_axis_ref + + FUNCTION cxios_is_defined_grid_axis_ref(grid_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_grid_axis_ref + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + END FUNCTION cxios_is_defined_grid_axis_ref + + + SUBROUTINE cxios_set_grid_description(grid_hdl, description, description_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: description + INTEGER (kind = C_INT) , VALUE :: description_size + END SUBROUTINE cxios_set_grid_description + + SUBROUTINE cxios_get_grid_description(grid_hdl, description, description_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: description + INTEGER (kind = C_INT) , VALUE :: description_size + END SUBROUTINE cxios_get_grid_description + + FUNCTION cxios_is_defined_grid_description(grid_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_grid_description + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + END FUNCTION cxios_is_defined_grid_description + + + SUBROUTINE cxios_set_grid_domain_ref(grid_hdl, domain_ref, domain_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_ref + INTEGER (kind = C_INT) , VALUE :: domain_ref_size + END SUBROUTINE cxios_set_grid_domain_ref + + SUBROUTINE cxios_get_grid_domain_ref(grid_hdl, domain_ref, domain_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_ref + INTEGER (kind = C_INT) , VALUE :: domain_ref_size + END SUBROUTINE cxios_get_grid_domain_ref + + FUNCTION cxios_is_defined_grid_domain_ref(grid_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_grid_domain_ref + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + END FUNCTION cxios_is_defined_grid_domain_ref + + + SUBROUTINE cxios_set_grid_mask(grid_hdl, mask, extent1, extent2, extent3) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + LOGICAL (KIND=C_BOOL) , DIMENSION(*) :: mask + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + INTEGER (kind = C_INT), VALUE :: extent3 + END SUBROUTINE cxios_set_grid_mask + + SUBROUTINE cxios_get_grid_mask(grid_hdl, mask, extent1, extent2, extent3) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + LOGICAL (KIND=C_BOOL) , DIMENSION(*) :: mask + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + INTEGER (kind = C_INT), VALUE :: extent3 + END SUBROUTINE cxios_get_grid_mask + + FUNCTION cxios_is_defined_grid_mask(grid_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_grid_mask + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + END FUNCTION cxios_is_defined_grid_mask + + + SUBROUTINE cxios_set_grid_name(grid_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_grid_name + + SUBROUTINE cxios_get_grid_name(grid_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_grid_name + + FUNCTION cxios_is_defined_grid_name(grid_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_grid_name + INTEGER (kind = C_INTPTR_T), VALUE :: grid_hdl + END FUNCTION cxios_is_defined_grid_name + + + END INTERFACE + +END MODULE grid_interface_attr diff --git a/src/interface/fortran_attr/gridgroup_interface_attr.f90 b/src/interface/fortran_attr/gridgroup_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..d914f6b0e412f7640d03e93a6f123bdae940a214 --- /dev/null +++ b/src/interface/fortran_attr/gridgroup_interface_attr.f90 @@ -0,0 +1,143 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE gridgroup_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_gridgroup_axis_ref(gridgroup_hdl, axis_ref, axis_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: axis_ref + INTEGER (kind = C_INT) , VALUE :: axis_ref_size + END SUBROUTINE cxios_set_gridgroup_axis_ref + + SUBROUTINE cxios_get_gridgroup_axis_ref(gridgroup_hdl, axis_ref, axis_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: axis_ref + INTEGER (kind = C_INT) , VALUE :: axis_ref_size + END SUBROUTINE cxios_get_gridgroup_axis_ref + + FUNCTION cxios_is_defined_gridgroup_axis_ref(gridgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_gridgroup_axis_ref + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + END FUNCTION cxios_is_defined_gridgroup_axis_ref + + + SUBROUTINE cxios_set_gridgroup_description(gridgroup_hdl, description, description_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: description + INTEGER (kind = C_INT) , VALUE :: description_size + END SUBROUTINE cxios_set_gridgroup_description + + SUBROUTINE cxios_get_gridgroup_description(gridgroup_hdl, description, description_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: description + INTEGER (kind = C_INT) , VALUE :: description_size + END SUBROUTINE cxios_get_gridgroup_description + + FUNCTION cxios_is_defined_gridgroup_description(gridgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_gridgroup_description + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + END FUNCTION cxios_is_defined_gridgroup_description + + + SUBROUTINE cxios_set_gridgroup_domain_ref(gridgroup_hdl, domain_ref, domain_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_ref + INTEGER (kind = C_INT) , VALUE :: domain_ref_size + END SUBROUTINE cxios_set_gridgroup_domain_ref + + SUBROUTINE cxios_get_gridgroup_domain_ref(gridgroup_hdl, domain_ref, domain_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: domain_ref + INTEGER (kind = C_INT) , VALUE :: domain_ref_size + END SUBROUTINE cxios_get_gridgroup_domain_ref + + FUNCTION cxios_is_defined_gridgroup_domain_ref(gridgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_gridgroup_domain_ref + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + END FUNCTION cxios_is_defined_gridgroup_domain_ref + + + SUBROUTINE cxios_set_gridgroup_group_ref(gridgroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_set_gridgroup_group_ref + + SUBROUTINE cxios_get_gridgroup_group_ref(gridgroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_get_gridgroup_group_ref + + FUNCTION cxios_is_defined_gridgroup_group_ref(gridgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_gridgroup_group_ref + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + END FUNCTION cxios_is_defined_gridgroup_group_ref + + + SUBROUTINE cxios_set_gridgroup_mask(gridgroup_hdl, mask, extent1, extent2, extent3) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + LOGICAL (KIND=C_BOOL) , DIMENSION(*) :: mask + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + INTEGER (kind = C_INT), VALUE :: extent3 + END SUBROUTINE cxios_set_gridgroup_mask + + SUBROUTINE cxios_get_gridgroup_mask(gridgroup_hdl, mask, extent1, extent2, extent3) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + LOGICAL (KIND=C_BOOL) , DIMENSION(*) :: mask + INTEGER (kind = C_INT), VALUE :: extent1 + INTEGER (kind = C_INT), VALUE :: extent2 + INTEGER (kind = C_INT), VALUE :: extent3 + END SUBROUTINE cxios_get_gridgroup_mask + + FUNCTION cxios_is_defined_gridgroup_mask(gridgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_gridgroup_mask + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + END FUNCTION cxios_is_defined_gridgroup_mask + + + SUBROUTINE cxios_set_gridgroup_name(gridgroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_gridgroup_name + + SUBROUTINE cxios_get_gridgroup_name(gridgroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_gridgroup_name + + FUNCTION cxios_is_defined_gridgroup_name(gridgroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_gridgroup_name + INTEGER (kind = C_INTPTR_T), VALUE :: gridgroup_hdl + END FUNCTION cxios_is_defined_gridgroup_name + + + END INTERFACE + +END MODULE gridgroup_interface_attr diff --git a/src/interface/fortran_attr/iaxis_attr.F90 b/src/interface/fortran_attr/iaxis_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..4264e9a7007fc4b7cf9494bb24bf3a0312bd3b9d --- /dev/null +++ b/src/interface/fortran_attr/iaxis_attr.F90 @@ -0,0 +1,380 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE iaxis_attr + USE, INTRINSIC :: ISO_C_BINDING + USE iaxis + USE axis_interface_attr + +CONTAINS + + SUBROUTINE xios(set_axis_attr) & + ( axis_id, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + IMPLICIT NONE + TYPE(txios(axis)) :: axis_hdl + CHARACTER(LEN=*), INTENT(IN) ::axis_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: positive + INTEGER , OPTIONAL, INTENT(IN) :: size + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: value(:) + INTEGER , OPTIONAL, INTENT(IN) :: zoom_begin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_end + INTEGER , OPTIONAL, INTENT(IN) :: zoom_size + + CALL xios(get_axis_handle)(axis_id,axis_hdl) + CALL xios(set_axis_attr_hdl_) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + END SUBROUTINE xios(set_axis_attr) + + SUBROUTINE xios(set_axis_attr_hdl) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + IMPLICIT NONE + TYPE(txios(axis)) , INTENT(IN) :: axis_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: positive + INTEGER , OPTIONAL, INTENT(IN) :: size + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: value(:) + INTEGER , OPTIONAL, INTENT(IN) :: zoom_begin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_end + INTEGER , OPTIONAL, INTENT(IN) :: zoom_size + + CALL xios(set_axis_attr_hdl_) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + END SUBROUTINE xios(set_axis_attr_hdl) + + SUBROUTINE xios(set_axis_attr_hdl_) & + ( axis_hdl, long_name_, name_, positive_, size_, standard_name_, unit_, value_, zoom_begin_ & + , zoom_end_, zoom_size_ ) + + IMPLICIT NONE + TYPE(txios(axis)) , INTENT(IN) :: axis_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: positive_ + INTEGER , OPTIONAL, INTENT(IN) :: size_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: value_(:) + INTEGER , OPTIONAL, INTENT(IN) :: zoom_begin_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_end_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_size_ + + IF (PRESENT(long_name_)) THEN + CALL cxios_set_axis_long_name(axis_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_axis_name(axis_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(positive_)) THEN + CALL cxios_set_axis_positive(axis_hdl%daddr, positive_, len(positive_)) + ENDIF + + IF (PRESENT(size_)) THEN + CALL cxios_set_axis_size(axis_hdl%daddr, size_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_set_axis_standard_name(axis_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(unit_)) THEN + CALL cxios_set_axis_unit(axis_hdl%daddr, unit_, len(unit_)) + ENDIF + + IF (PRESENT(value_)) THEN + CALL cxios_set_axis_value(axis_hdl%daddr, value_,size(value_,1)) + ENDIF + + IF (PRESENT(zoom_begin_)) THEN + CALL cxios_set_axis_zoom_begin(axis_hdl%daddr, zoom_begin_) + ENDIF + + IF (PRESENT(zoom_end_)) THEN + CALL cxios_set_axis_zoom_end(axis_hdl%daddr, zoom_end_) + ENDIF + + IF (PRESENT(zoom_size_)) THEN + CALL cxios_set_axis_zoom_size(axis_hdl%daddr, zoom_size_) + ENDIF + + + + END SUBROUTINE xios(set_axis_attr_hdl_) + + SUBROUTINE xios(get_axis_attr) & + ( axis_id, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + IMPLICIT NONE + TYPE(txios(axis)) :: axis_hdl + CHARACTER(LEN=*), INTENT(IN) ::axis_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: positive + INTEGER , OPTIONAL, INTENT(OUT) :: size + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: value(:) + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_begin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_end + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_size + + CALL xios(get_axis_handle)(axis_id,axis_hdl) + CALL xios(get_axis_attr_hdl_) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + END SUBROUTINE xios(get_axis_attr) + + SUBROUTINE xios(get_axis_attr_hdl) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + IMPLICIT NONE + TYPE(txios(axis)) , INTENT(IN) :: axis_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: positive + INTEGER , OPTIONAL, INTENT(OUT) :: size + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: value(:) + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_begin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_end + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_size + + CALL xios(get_axis_attr_hdl_) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + END SUBROUTINE xios(get_axis_attr_hdl) + + SUBROUTINE xios(get_axis_attr_hdl_) & + ( axis_hdl, long_name_, name_, positive_, size_, standard_name_, unit_, value_, zoom_begin_ & + , zoom_end_, zoom_size_ ) + + IMPLICIT NONE + TYPE(txios(axis)) , INTENT(IN) :: axis_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: positive_ + INTEGER , OPTIONAL, INTENT(OUT) :: size_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: value_(:) + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_begin_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_end_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_size_ + + IF (PRESENT(long_name_)) THEN + CALL cxios_get_axis_long_name(axis_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_axis_name(axis_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(positive_)) THEN + CALL cxios_get_axis_positive(axis_hdl%daddr, positive_, len(positive_)) + ENDIF + + IF (PRESENT(size_)) THEN + CALL cxios_get_axis_size(axis_hdl%daddr, size_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_get_axis_standard_name(axis_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(unit_)) THEN + CALL cxios_get_axis_unit(axis_hdl%daddr, unit_, len(unit_)) + ENDIF + + IF (PRESENT(value_)) THEN + CALL cxios_get_axis_value(axis_hdl%daddr, value_,size(value_,1)) + ENDIF + + IF (PRESENT(zoom_begin_)) THEN + CALL cxios_get_axis_zoom_begin(axis_hdl%daddr, zoom_begin_) + ENDIF + + IF (PRESENT(zoom_end_)) THEN + CALL cxios_get_axis_zoom_end(axis_hdl%daddr, zoom_end_) + ENDIF + + IF (PRESENT(zoom_size_)) THEN + CALL cxios_get_axis_zoom_size(axis_hdl%daddr, zoom_size_) + ENDIF + + + + END SUBROUTINE xios(get_axis_attr_hdl_) + + SUBROUTINE xios(is_defined_axis_attr) & + ( axis_id, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + IMPLICIT NONE + TYPE(txios(axis)) :: axis_hdl + CHARACTER(LEN=*), INTENT(IN) ::axis_id + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: positive + LOGICAL(KIND=C_BOOL) :: positive_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: size + LOGICAL(KIND=C_BOOL) :: size_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit + LOGICAL(KIND=C_BOOL) :: unit_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: value + LOGICAL(KIND=C_BOOL) :: value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_begin + LOGICAL(KIND=C_BOOL) :: zoom_begin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_end + LOGICAL(KIND=C_BOOL) :: zoom_end_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_size + LOGICAL(KIND=C_BOOL) :: zoom_size_tmp + + CALL xios(get_axis_handle)(axis_id,axis_hdl) + CALL xios(is_defined_axis_attr_hdl_) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + END SUBROUTINE xios(is_defined_axis_attr) + + SUBROUTINE xios(is_defined_axis_attr_hdl) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + IMPLICIT NONE + TYPE(txios(axis)) , INTENT(IN) :: axis_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: positive + LOGICAL(KIND=C_BOOL) :: positive_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: size + LOGICAL(KIND=C_BOOL) :: size_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit + LOGICAL(KIND=C_BOOL) :: unit_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: value + LOGICAL(KIND=C_BOOL) :: value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_begin + LOGICAL(KIND=C_BOOL) :: zoom_begin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_end + LOGICAL(KIND=C_BOOL) :: zoom_end_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_size + LOGICAL(KIND=C_BOOL) :: zoom_size_tmp + + CALL xios(is_defined_axis_attr_hdl_) & + ( axis_hdl, long_name, name, positive, size, standard_name, unit, value, zoom_begin, zoom_end & + , zoom_size ) + + END SUBROUTINE xios(is_defined_axis_attr_hdl) + + SUBROUTINE xios(is_defined_axis_attr_hdl_) & + ( axis_hdl, long_name_, name_, positive_, size_, standard_name_, unit_, value_, zoom_begin_ & + , zoom_end_, zoom_size_ ) + + IMPLICIT NONE + TYPE(txios(axis)) , INTENT(IN) :: axis_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name_ + LOGICAL(KIND=C_BOOL) :: long_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: positive_ + LOGICAL(KIND=C_BOOL) :: positive__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: size_ + LOGICAL(KIND=C_BOOL) :: size__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name_ + LOGICAL(KIND=C_BOOL) :: standard_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit_ + LOGICAL(KIND=C_BOOL) :: unit__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: value_ + LOGICAL(KIND=C_BOOL) :: value__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_begin_ + LOGICAL(KIND=C_BOOL) :: zoom_begin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_end_ + LOGICAL(KIND=C_BOOL) :: zoom_end__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_size_ + LOGICAL(KIND=C_BOOL) :: zoom_size__tmp + + IF (PRESENT(long_name_)) THEN + long_name__tmp=cxios_is_defined_axis_long_name(axis_hdl%daddr) + long_name_=long_name__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_axis_name(axis_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(positive_)) THEN + positive__tmp=cxios_is_defined_axis_positive(axis_hdl%daddr) + positive_=positive__tmp + ENDIF + + IF (PRESENT(size_)) THEN + size__tmp=cxios_is_defined_axis_size(axis_hdl%daddr) + size_=size__tmp + ENDIF + + IF (PRESENT(standard_name_)) THEN + standard_name__tmp=cxios_is_defined_axis_standard_name(axis_hdl%daddr) + standard_name_=standard_name__tmp + ENDIF + + IF (PRESENT(unit_)) THEN + unit__tmp=cxios_is_defined_axis_unit(axis_hdl%daddr) + unit_=unit__tmp + ENDIF + + IF (PRESENT(value_)) THEN + value__tmp=cxios_is_defined_axis_value(axis_hdl%daddr) + value_=value__tmp + ENDIF + + IF (PRESENT(zoom_begin_)) THEN + zoom_begin__tmp=cxios_is_defined_axis_zoom_begin(axis_hdl%daddr) + zoom_begin_=zoom_begin__tmp + ENDIF + + IF (PRESENT(zoom_end_)) THEN + zoom_end__tmp=cxios_is_defined_axis_zoom_end(axis_hdl%daddr) + zoom_end_=zoom_end__tmp + ENDIF + + IF (PRESENT(zoom_size_)) THEN + zoom_size__tmp=cxios_is_defined_axis_zoom_size(axis_hdl%daddr) + zoom_size_=zoom_size__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_axis_attr_hdl_) + +END MODULE iaxis_attr diff --git a/src/interface/fortran_attr/iaxisgroup_attr.F90 b/src/interface/fortran_attr/iaxisgroup_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..9366078d72bca49e7a05029660c5414b8a81d80e --- /dev/null +++ b/src/interface/fortran_attr/iaxisgroup_attr.F90 @@ -0,0 +1,405 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE iaxisgroup_attr + USE, INTRINSIC :: ISO_C_BINDING + USE iaxis + USE axisgroup_interface_attr + +CONTAINS + + SUBROUTINE xios(set_axisgroup_attr) & + ( axisgroup_id, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) :: axisgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::axisgroup_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: positive + INTEGER , OPTIONAL, INTENT(IN) :: size + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: value(:) + INTEGER , OPTIONAL, INTENT(IN) :: zoom_begin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_end + INTEGER , OPTIONAL, INTENT(IN) :: zoom_size + + CALL xios(get_axisgroup_handle)(axisgroup_id,axisgroup_hdl) + CALL xios(set_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + END SUBROUTINE xios(set_axisgroup_attr) + + SUBROUTINE xios(set_axisgroup_attr_hdl) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) , INTENT(IN) :: axisgroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: positive + INTEGER , OPTIONAL, INTENT(IN) :: size + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: value(:) + INTEGER , OPTIONAL, INTENT(IN) :: zoom_begin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_end + INTEGER , OPTIONAL, INTENT(IN) :: zoom_size + + CALL xios(set_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + END SUBROUTINE xios(set_axisgroup_attr_hdl) + + SUBROUTINE xios(set_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref_, long_name_, name_, positive_, size_, standard_name_, unit_, value_ & + , zoom_begin_, zoom_end_, zoom_size_ ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) , INTENT(IN) :: axisgroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: positive_ + INTEGER , OPTIONAL, INTENT(IN) :: size_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: value_(:) + INTEGER , OPTIONAL, INTENT(IN) :: zoom_begin_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_end_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_size_ + + IF (PRESENT(group_ref_)) THEN + CALL cxios_set_axisgroup_group_ref(axisgroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_set_axisgroup_long_name(axisgroup_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_axisgroup_name(axisgroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(positive_)) THEN + CALL cxios_set_axisgroup_positive(axisgroup_hdl%daddr, positive_, len(positive_)) + ENDIF + + IF (PRESENT(size_)) THEN + CALL cxios_set_axisgroup_size(axisgroup_hdl%daddr, size_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_set_axisgroup_standard_name(axisgroup_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(unit_)) THEN + CALL cxios_set_axisgroup_unit(axisgroup_hdl%daddr, unit_, len(unit_)) + ENDIF + + IF (PRESENT(value_)) THEN + CALL cxios_set_axisgroup_value(axisgroup_hdl%daddr, value_,size(value_,1)) + ENDIF + + IF (PRESENT(zoom_begin_)) THEN + CALL cxios_set_axisgroup_zoom_begin(axisgroup_hdl%daddr, zoom_begin_) + ENDIF + + IF (PRESENT(zoom_end_)) THEN + CALL cxios_set_axisgroup_zoom_end(axisgroup_hdl%daddr, zoom_end_) + ENDIF + + IF (PRESENT(zoom_size_)) THEN + CALL cxios_set_axisgroup_zoom_size(axisgroup_hdl%daddr, zoom_size_) + ENDIF + + + + END SUBROUTINE xios(set_axisgroup_attr_hdl_) + + SUBROUTINE xios(get_axisgroup_attr) & + ( axisgroup_id, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) :: axisgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::axisgroup_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: positive + INTEGER , OPTIONAL, INTENT(OUT) :: size + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: value(:) + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_begin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_end + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_size + + CALL xios(get_axisgroup_handle)(axisgroup_id,axisgroup_hdl) + CALL xios(get_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + END SUBROUTINE xios(get_axisgroup_attr) + + SUBROUTINE xios(get_axisgroup_attr_hdl) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) , INTENT(IN) :: axisgroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: positive + INTEGER , OPTIONAL, INTENT(OUT) :: size + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: value(:) + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_begin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_end + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_size + + CALL xios(get_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + END SUBROUTINE xios(get_axisgroup_attr_hdl) + + SUBROUTINE xios(get_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref_, long_name_, name_, positive_, size_, standard_name_, unit_, value_ & + , zoom_begin_, zoom_end_, zoom_size_ ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) , INTENT(IN) :: axisgroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: positive_ + INTEGER , OPTIONAL, INTENT(OUT) :: size_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: value_(:) + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_begin_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_end_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_size_ + + IF (PRESENT(group_ref_)) THEN + CALL cxios_get_axisgroup_group_ref(axisgroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_get_axisgroup_long_name(axisgroup_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_axisgroup_name(axisgroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(positive_)) THEN + CALL cxios_get_axisgroup_positive(axisgroup_hdl%daddr, positive_, len(positive_)) + ENDIF + + IF (PRESENT(size_)) THEN + CALL cxios_get_axisgroup_size(axisgroup_hdl%daddr, size_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_get_axisgroup_standard_name(axisgroup_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(unit_)) THEN + CALL cxios_get_axisgroup_unit(axisgroup_hdl%daddr, unit_, len(unit_)) + ENDIF + + IF (PRESENT(value_)) THEN + CALL cxios_get_axisgroup_value(axisgroup_hdl%daddr, value_,size(value_,1)) + ENDIF + + IF (PRESENT(zoom_begin_)) THEN + CALL cxios_get_axisgroup_zoom_begin(axisgroup_hdl%daddr, zoom_begin_) + ENDIF + + IF (PRESENT(zoom_end_)) THEN + CALL cxios_get_axisgroup_zoom_end(axisgroup_hdl%daddr, zoom_end_) + ENDIF + + IF (PRESENT(zoom_size_)) THEN + CALL cxios_get_axisgroup_zoom_size(axisgroup_hdl%daddr, zoom_size_) + ENDIF + + + + END SUBROUTINE xios(get_axisgroup_attr_hdl_) + + SUBROUTINE xios(is_defined_axisgroup_attr) & + ( axisgroup_id, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) :: axisgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::axisgroup_id + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: positive + LOGICAL(KIND=C_BOOL) :: positive_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: size + LOGICAL(KIND=C_BOOL) :: size_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit + LOGICAL(KIND=C_BOOL) :: unit_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: value + LOGICAL(KIND=C_BOOL) :: value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_begin + LOGICAL(KIND=C_BOOL) :: zoom_begin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_end + LOGICAL(KIND=C_BOOL) :: zoom_end_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_size + LOGICAL(KIND=C_BOOL) :: zoom_size_tmp + + CALL xios(get_axisgroup_handle)(axisgroup_id,axisgroup_hdl) + CALL xios(is_defined_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + END SUBROUTINE xios(is_defined_axisgroup_attr) + + SUBROUTINE xios(is_defined_axisgroup_attr_hdl) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) , INTENT(IN) :: axisgroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: positive + LOGICAL(KIND=C_BOOL) :: positive_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: size + LOGICAL(KIND=C_BOOL) :: size_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit + LOGICAL(KIND=C_BOOL) :: unit_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: value + LOGICAL(KIND=C_BOOL) :: value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_begin + LOGICAL(KIND=C_BOOL) :: zoom_begin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_end + LOGICAL(KIND=C_BOOL) :: zoom_end_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_size + LOGICAL(KIND=C_BOOL) :: zoom_size_tmp + + CALL xios(is_defined_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref, long_name, name, positive, size, standard_name, unit, value, zoom_begin & + , zoom_end, zoom_size ) + + END SUBROUTINE xios(is_defined_axisgroup_attr_hdl) + + SUBROUTINE xios(is_defined_axisgroup_attr_hdl_) & + ( axisgroup_hdl, group_ref_, long_name_, name_, positive_, size_, standard_name_, unit_, value_ & + , zoom_begin_, zoom_end_, zoom_size_ ) + + IMPLICIT NONE + TYPE(txios(axisgroup)) , INTENT(IN) :: axisgroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref_ + LOGICAL(KIND=C_BOOL) :: group_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name_ + LOGICAL(KIND=C_BOOL) :: long_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: positive_ + LOGICAL(KIND=C_BOOL) :: positive__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: size_ + LOGICAL(KIND=C_BOOL) :: size__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name_ + LOGICAL(KIND=C_BOOL) :: standard_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit_ + LOGICAL(KIND=C_BOOL) :: unit__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: value_ + LOGICAL(KIND=C_BOOL) :: value__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_begin_ + LOGICAL(KIND=C_BOOL) :: zoom_begin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_end_ + LOGICAL(KIND=C_BOOL) :: zoom_end__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_size_ + LOGICAL(KIND=C_BOOL) :: zoom_size__tmp + + IF (PRESENT(group_ref_)) THEN + group_ref__tmp=cxios_is_defined_axisgroup_group_ref(axisgroup_hdl%daddr) + group_ref_=group_ref__tmp + ENDIF + + IF (PRESENT(long_name_)) THEN + long_name__tmp=cxios_is_defined_axisgroup_long_name(axisgroup_hdl%daddr) + long_name_=long_name__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_axisgroup_name(axisgroup_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(positive_)) THEN + positive__tmp=cxios_is_defined_axisgroup_positive(axisgroup_hdl%daddr) + positive_=positive__tmp + ENDIF + + IF (PRESENT(size_)) THEN + size__tmp=cxios_is_defined_axisgroup_size(axisgroup_hdl%daddr) + size_=size__tmp + ENDIF + + IF (PRESENT(standard_name_)) THEN + standard_name__tmp=cxios_is_defined_axisgroup_standard_name(axisgroup_hdl%daddr) + standard_name_=standard_name__tmp + ENDIF + + IF (PRESENT(unit_)) THEN + unit__tmp=cxios_is_defined_axisgroup_unit(axisgroup_hdl%daddr) + unit_=unit__tmp + ENDIF + + IF (PRESENT(value_)) THEN + value__tmp=cxios_is_defined_axisgroup_value(axisgroup_hdl%daddr) + value_=value__tmp + ENDIF + + IF (PRESENT(zoom_begin_)) THEN + zoom_begin__tmp=cxios_is_defined_axisgroup_zoom_begin(axisgroup_hdl%daddr) + zoom_begin_=zoom_begin__tmp + ENDIF + + IF (PRESENT(zoom_end_)) THEN + zoom_end__tmp=cxios_is_defined_axisgroup_zoom_end(axisgroup_hdl%daddr) + zoom_end_=zoom_end__tmp + ENDIF + + IF (PRESENT(zoom_size_)) THEN + zoom_size__tmp=cxios_is_defined_axisgroup_zoom_size(axisgroup_hdl%daddr) + zoom_size_=zoom_size__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_axisgroup_attr_hdl_) + +END MODULE iaxisgroup_attr diff --git a/src/interface/fortran_attr/icontext_attr.F90 b/src/interface/fortran_attr/icontext_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..6d6d4f029d6ab76fa686b939c4711aff6b09deb0 --- /dev/null +++ b/src/interface/fortran_attr/icontext_attr.F90 @@ -0,0 +1,240 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE icontext_attr + USE, INTRINSIC :: ISO_C_BINDING + USE icontext + USE context_interface_attr + +CONTAINS + + SUBROUTINE xios(set_context_attr) & + ( context_id, calendar_type, output_dir, start_date, time_origin, timestep ) + + IMPLICIT NONE + TYPE(txios(context)) :: context_hdl + CHARACTER(LEN=*), INTENT(IN) ::context_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: calendar_type + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_dir + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: timestep + + CALL xios(get_context_handle)(context_id,context_hdl) + CALL xios(set_context_attr_hdl_) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + END SUBROUTINE xios(set_context_attr) + + SUBROUTINE xios(set_context_attr_hdl) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + IMPLICIT NONE + TYPE(txios(context)) , INTENT(IN) :: context_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: calendar_type + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_dir + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: timestep + + CALL xios(set_context_attr_hdl_) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + END SUBROUTINE xios(set_context_attr_hdl) + + SUBROUTINE xios(set_context_attr_hdl_) & + ( context_hdl, calendar_type_, output_dir_, start_date_, time_origin_, timestep_ ) + + IMPLICIT NONE + TYPE(txios(context)) , INTENT(IN) :: context_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: calendar_type_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_dir_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: start_date_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: time_origin_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: timestep_ + + IF (PRESENT(calendar_type_)) THEN + CALL cxios_set_context_calendar_type(context_hdl%daddr, calendar_type_, len(calendar_type_)) + ENDIF + + IF (PRESENT(output_dir_)) THEN + CALL cxios_set_context_output_dir(context_hdl%daddr, output_dir_, len(output_dir_)) + ENDIF + + IF (PRESENT(start_date_)) THEN + CALL cxios_set_context_start_date(context_hdl%daddr, start_date_, len(start_date_)) + ENDIF + + IF (PRESENT(time_origin_)) THEN + CALL cxios_set_context_time_origin(context_hdl%daddr, time_origin_, len(time_origin_)) + ENDIF + + IF (PRESENT(timestep_)) THEN + CALL cxios_set_context_timestep(context_hdl%daddr, timestep_, len(timestep_)) + ENDIF + + + + END SUBROUTINE xios(set_context_attr_hdl_) + + SUBROUTINE xios(get_context_attr) & + ( context_id, calendar_type, output_dir, start_date, time_origin, timestep ) + + IMPLICIT NONE + TYPE(txios(context)) :: context_hdl + CHARACTER(LEN=*), INTENT(IN) ::context_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: calendar_type + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_dir + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: timestep + + CALL xios(get_context_handle)(context_id,context_hdl) + CALL xios(get_context_attr_hdl_) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + END SUBROUTINE xios(get_context_attr) + + SUBROUTINE xios(get_context_attr_hdl) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + IMPLICIT NONE + TYPE(txios(context)) , INTENT(IN) :: context_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: calendar_type + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_dir + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: timestep + + CALL xios(get_context_attr_hdl_) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + END SUBROUTINE xios(get_context_attr_hdl) + + SUBROUTINE xios(get_context_attr_hdl_) & + ( context_hdl, calendar_type_, output_dir_, start_date_, time_origin_, timestep_ ) + + IMPLICIT NONE + TYPE(txios(context)) , INTENT(IN) :: context_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: calendar_type_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_dir_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: start_date_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: time_origin_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: timestep_ + + IF (PRESENT(calendar_type_)) THEN + CALL cxios_get_context_calendar_type(context_hdl%daddr, calendar_type_, len(calendar_type_)) + ENDIF + + IF (PRESENT(output_dir_)) THEN + CALL cxios_get_context_output_dir(context_hdl%daddr, output_dir_, len(output_dir_)) + ENDIF + + IF (PRESENT(start_date_)) THEN + CALL cxios_get_context_start_date(context_hdl%daddr, start_date_, len(start_date_)) + ENDIF + + IF (PRESENT(time_origin_)) THEN + CALL cxios_get_context_time_origin(context_hdl%daddr, time_origin_, len(time_origin_)) + ENDIF + + IF (PRESENT(timestep_)) THEN + CALL cxios_get_context_timestep(context_hdl%daddr, timestep_, len(timestep_)) + ENDIF + + + + END SUBROUTINE xios(get_context_attr_hdl_) + + SUBROUTINE xios(is_defined_context_attr) & + ( context_id, calendar_type, output_dir, start_date, time_origin, timestep ) + + IMPLICIT NONE + TYPE(txios(context)) :: context_hdl + CHARACTER(LEN=*), INTENT(IN) ::context_id + LOGICAL, OPTIONAL, INTENT(OUT) :: calendar_type + LOGICAL(KIND=C_BOOL) :: calendar_type_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_dir + LOGICAL(KIND=C_BOOL) :: output_dir_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: start_date + LOGICAL(KIND=C_BOOL) :: start_date_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: time_origin + LOGICAL(KIND=C_BOOL) :: time_origin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: timestep + LOGICAL(KIND=C_BOOL) :: timestep_tmp + + CALL xios(get_context_handle)(context_id,context_hdl) + CALL xios(is_defined_context_attr_hdl_) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + END SUBROUTINE xios(is_defined_context_attr) + + SUBROUTINE xios(is_defined_context_attr_hdl) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + IMPLICIT NONE + TYPE(txios(context)) , INTENT(IN) :: context_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: calendar_type + LOGICAL(KIND=C_BOOL) :: calendar_type_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_dir + LOGICAL(KIND=C_BOOL) :: output_dir_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: start_date + LOGICAL(KIND=C_BOOL) :: start_date_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: time_origin + LOGICAL(KIND=C_BOOL) :: time_origin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: timestep + LOGICAL(KIND=C_BOOL) :: timestep_tmp + + CALL xios(is_defined_context_attr_hdl_) & + ( context_hdl, calendar_type, output_dir, start_date, time_origin, timestep ) + + END SUBROUTINE xios(is_defined_context_attr_hdl) + + SUBROUTINE xios(is_defined_context_attr_hdl_) & + ( context_hdl, calendar_type_, output_dir_, start_date_, time_origin_, timestep_ ) + + IMPLICIT NONE + TYPE(txios(context)) , INTENT(IN) :: context_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: calendar_type_ + LOGICAL(KIND=C_BOOL) :: calendar_type__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_dir_ + LOGICAL(KIND=C_BOOL) :: output_dir__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: start_date_ + LOGICAL(KIND=C_BOOL) :: start_date__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: time_origin_ + LOGICAL(KIND=C_BOOL) :: time_origin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: timestep_ + LOGICAL(KIND=C_BOOL) :: timestep__tmp + + IF (PRESENT(calendar_type_)) THEN + calendar_type__tmp=cxios_is_defined_context_calendar_type(context_hdl%daddr) + calendar_type_=calendar_type__tmp + ENDIF + + IF (PRESENT(output_dir_)) THEN + output_dir__tmp=cxios_is_defined_context_output_dir(context_hdl%daddr) + output_dir_=output_dir__tmp + ENDIF + + IF (PRESENT(start_date_)) THEN + start_date__tmp=cxios_is_defined_context_start_date(context_hdl%daddr) + start_date_=start_date__tmp + ENDIF + + IF (PRESENT(time_origin_)) THEN + time_origin__tmp=cxios_is_defined_context_time_origin(context_hdl%daddr) + time_origin_=time_origin__tmp + ENDIF + + IF (PRESENT(timestep_)) THEN + timestep__tmp=cxios_is_defined_context_timestep(context_hdl%daddr) + timestep_=timestep__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_context_attr_hdl_) + +END MODULE icontext_attr diff --git a/src/interface/fortran_attr/idomain_attr.F90 b/src/interface/fortran_attr/idomain_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..9a4ca3c66d35ace3635b58e291f3cc39c8826f5d --- /dev/null +++ b/src/interface/fortran_attr/idomain_attr.F90 @@ -0,0 +1,1110 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE idomain_attr + USE, INTRINSIC :: ISO_C_BINDING + USE idomain + USE domain_interface_attr + +CONTAINS + + SUBROUTINE xios(set_domain_attr) & + ( domain_id, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domain)) :: domain_hdl + CHARACTER(LEN=*), INTENT(IN) ::domain_id + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lat(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lon(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: data_dim + INTEGER , OPTIONAL, INTENT(IN) :: data_i_index(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_ibegin + INTEGER , OPTIONAL, INTENT(IN) :: data_j_index(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_jbegin + INTEGER , OPTIONAL, INTENT(IN) :: data_n_index + INTEGER , OPTIONAL, INTENT(IN) :: data_ni + INTEGER , OPTIONAL, INTENT(IN) :: data_nj + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_group_ref + INTEGER , OPTIONAL, INTENT(IN) :: i_index(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: ibegin + INTEGER , OPTIONAL, INTENT(IN) :: iend + INTEGER , OPTIONAL, INTENT(IN) :: j_index(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: jbegin + INTEGER , OPTIONAL, INTENT(IN) :: jend + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: latvalue(:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: lonvalue(:) + LOGICAL , OPTIONAL, INTENT(IN) :: mask(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + INTEGER , OPTIONAL, INTENT(IN) :: ni + INTEGER , OPTIONAL, INTENT(IN) :: ni_glo + INTEGER , OPTIONAL, INTENT(IN) :: nj + INTEGER , OPTIONAL, INTENT(IN) :: nj_glo + INTEGER , OPTIONAL, INTENT(IN) :: nvertex + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj_loc + + CALL xios(get_domain_handle)(domain_id,domain_hdl) + CALL xios(set_domain_attr_hdl_) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + END SUBROUTINE xios(set_domain_attr) + + SUBROUTINE xios(set_domain_attr_hdl) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domain)) , INTENT(IN) :: domain_hdl + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lat(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lon(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: data_dim + INTEGER , OPTIONAL, INTENT(IN) :: data_i_index(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_ibegin + INTEGER , OPTIONAL, INTENT(IN) :: data_j_index(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_jbegin + INTEGER , OPTIONAL, INTENT(IN) :: data_n_index + INTEGER , OPTIONAL, INTENT(IN) :: data_ni + INTEGER , OPTIONAL, INTENT(IN) :: data_nj + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_group_ref + INTEGER , OPTIONAL, INTENT(IN) :: i_index(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: ibegin + INTEGER , OPTIONAL, INTENT(IN) :: iend + INTEGER , OPTIONAL, INTENT(IN) :: j_index(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: jbegin + INTEGER , OPTIONAL, INTENT(IN) :: jend + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: latvalue(:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: lonvalue(:) + LOGICAL , OPTIONAL, INTENT(IN) :: mask(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + INTEGER , OPTIONAL, INTENT(IN) :: ni + INTEGER , OPTIONAL, INTENT(IN) :: ni_glo + INTEGER , OPTIONAL, INTENT(IN) :: nj + INTEGER , OPTIONAL, INTENT(IN) :: nj_glo + INTEGER , OPTIONAL, INTENT(IN) :: nvertex + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj_loc + + CALL xios(set_domain_attr_hdl_) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + END SUBROUTINE xios(set_domain_attr_hdl) + + SUBROUTINE xios(set_domain_attr_hdl_) & + ( domain_hdl, bounds_lat_, bounds_lon_, data_dim_, data_i_index_, data_ibegin_, data_j_index_ & + , data_jbegin_, data_n_index_, data_ni_, data_nj_, domain_group_ref_, i_index_, ibegin_, iend_ & + , j_index_, jbegin_, jend_, latvalue_, long_name_, lonvalue_, mask_, name_, ni_, ni_glo_, nj_ & + , nj_glo_, nvertex_, standard_name_, type_, zoom_ibegin_, zoom_ibegin_loc_, zoom_jbegin_, zoom_jbegin_loc_ & + , zoom_ni_, zoom_ni_loc_, zoom_nj_, zoom_nj_loc_ ) + + IMPLICIT NONE + TYPE(txios(domain)) , INTENT(IN) :: domain_hdl + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lat_(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lon_(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: data_dim_ + INTEGER , OPTIONAL, INTENT(IN) :: data_i_index_(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_ibegin_ + INTEGER , OPTIONAL, INTENT(IN) :: data_j_index_(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_jbegin_ + INTEGER , OPTIONAL, INTENT(IN) :: data_n_index_ + INTEGER , OPTIONAL, INTENT(IN) :: data_ni_ + INTEGER , OPTIONAL, INTENT(IN) :: data_nj_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_group_ref_ + INTEGER , OPTIONAL, INTENT(IN) :: i_index_(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: ibegin_ + INTEGER , OPTIONAL, INTENT(IN) :: iend_ + INTEGER , OPTIONAL, INTENT(IN) :: j_index_(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: jbegin_ + INTEGER , OPTIONAL, INTENT(IN) :: jend_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: latvalue_(:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: lonvalue_(:) + LOGICAL , OPTIONAL, INTENT(IN) :: mask_(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask__tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + INTEGER , OPTIONAL, INTENT(IN) :: ni_ + INTEGER , OPTIONAL, INTENT(IN) :: ni_glo_ + INTEGER , OPTIONAL, INTENT(IN) :: nj_ + INTEGER , OPTIONAL, INTENT(IN) :: nj_glo_ + INTEGER , OPTIONAL, INTENT(IN) :: nvertex_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin_loc_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin_loc_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni_loc_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj_loc_ + + IF (PRESENT(bounds_lat_)) THEN + CALL cxios_set_domain_bounds_lat(domain_hdl%daddr, bounds_lat_,size(bounds_lat_,1),size(bounds_lat_,2)) + ENDIF + + IF (PRESENT(bounds_lon_)) THEN + CALL cxios_set_domain_bounds_lon(domain_hdl%daddr, bounds_lon_,size(bounds_lon_,1),size(bounds_lon_,2)) + ENDIF + + IF (PRESENT(data_dim_)) THEN + CALL cxios_set_domain_data_dim(domain_hdl%daddr, data_dim_) + ENDIF + + IF (PRESENT(data_i_index_)) THEN + CALL cxios_set_domain_data_i_index(domain_hdl%daddr, data_i_index_,size(data_i_index_,1)) + ENDIF + + IF (PRESENT(data_ibegin_)) THEN + CALL cxios_set_domain_data_ibegin(domain_hdl%daddr, data_ibegin_) + ENDIF + + IF (PRESENT(data_j_index_)) THEN + CALL cxios_set_domain_data_j_index(domain_hdl%daddr, data_j_index_,size(data_j_index_,1)) + ENDIF + + IF (PRESENT(data_jbegin_)) THEN + CALL cxios_set_domain_data_jbegin(domain_hdl%daddr, data_jbegin_) + ENDIF + + IF (PRESENT(data_n_index_)) THEN + CALL cxios_set_domain_data_n_index(domain_hdl%daddr, data_n_index_) + ENDIF + + IF (PRESENT(data_ni_)) THEN + CALL cxios_set_domain_data_ni(domain_hdl%daddr, data_ni_) + ENDIF + + IF (PRESENT(data_nj_)) THEN + CALL cxios_set_domain_data_nj(domain_hdl%daddr, data_nj_) + ENDIF + + IF (PRESENT(domain_group_ref_)) THEN + CALL cxios_set_domain_domain_group_ref(domain_hdl%daddr, domain_group_ref_, len(domain_group_ref_)) + ENDIF + + IF (PRESENT(i_index_)) THEN + CALL cxios_set_domain_i_index(domain_hdl%daddr, i_index_,size(i_index_,1),size(i_index_,2)) + ENDIF + + IF (PRESENT(ibegin_)) THEN + CALL cxios_set_domain_ibegin(domain_hdl%daddr, ibegin_) + ENDIF + + IF (PRESENT(iend_)) THEN + CALL cxios_set_domain_iend(domain_hdl%daddr, iend_) + ENDIF + + IF (PRESENT(j_index_)) THEN + CALL cxios_set_domain_j_index(domain_hdl%daddr, j_index_,size(j_index_,1),size(j_index_,2)) + ENDIF + + IF (PRESENT(jbegin_)) THEN + CALL cxios_set_domain_jbegin(domain_hdl%daddr, jbegin_) + ENDIF + + IF (PRESENT(jend_)) THEN + CALL cxios_set_domain_jend(domain_hdl%daddr, jend_) + ENDIF + + IF (PRESENT(latvalue_)) THEN + CALL cxios_set_domain_latvalue(domain_hdl%daddr, latvalue_,size(latvalue_,1)) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_set_domain_long_name(domain_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(lonvalue_)) THEN + CALL cxios_set_domain_lonvalue(domain_hdl%daddr, lonvalue_,size(lonvalue_,1)) + ENDIF + + IF (PRESENT(mask_)) THEN + ALLOCATE(mask__tmp(size(mask_,1),size(mask_,2))) + mask__tmp=mask_ + CALL cxios_set_domain_mask(domain_hdl%daddr, mask__tmp,size(mask_,1),size(mask_,2)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_domain_name(domain_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(ni_)) THEN + CALL cxios_set_domain_ni(domain_hdl%daddr, ni_) + ENDIF + + IF (PRESENT(ni_glo_)) THEN + CALL cxios_set_domain_ni_glo(domain_hdl%daddr, ni_glo_) + ENDIF + + IF (PRESENT(nj_)) THEN + CALL cxios_set_domain_nj(domain_hdl%daddr, nj_) + ENDIF + + IF (PRESENT(nj_glo_)) THEN + CALL cxios_set_domain_nj_glo(domain_hdl%daddr, nj_glo_) + ENDIF + + IF (PRESENT(nvertex_)) THEN + CALL cxios_set_domain_nvertex(domain_hdl%daddr, nvertex_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_set_domain_standard_name(domain_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_set_domain_type(domain_hdl%daddr, type_, len(type_)) + ENDIF + + IF (PRESENT(zoom_ibegin_)) THEN + CALL cxios_set_domain_zoom_ibegin(domain_hdl%daddr, zoom_ibegin_) + ENDIF + + IF (PRESENT(zoom_ibegin_loc_)) THEN + CALL cxios_set_domain_zoom_ibegin_loc(domain_hdl%daddr, zoom_ibegin_loc_) + ENDIF + + IF (PRESENT(zoom_jbegin_)) THEN + CALL cxios_set_domain_zoom_jbegin(domain_hdl%daddr, zoom_jbegin_) + ENDIF + + IF (PRESENT(zoom_jbegin_loc_)) THEN + CALL cxios_set_domain_zoom_jbegin_loc(domain_hdl%daddr, zoom_jbegin_loc_) + ENDIF + + IF (PRESENT(zoom_ni_)) THEN + CALL cxios_set_domain_zoom_ni(domain_hdl%daddr, zoom_ni_) + ENDIF + + IF (PRESENT(zoom_ni_loc_)) THEN + CALL cxios_set_domain_zoom_ni_loc(domain_hdl%daddr, zoom_ni_loc_) + ENDIF + + IF (PRESENT(zoom_nj_)) THEN + CALL cxios_set_domain_zoom_nj(domain_hdl%daddr, zoom_nj_) + ENDIF + + IF (PRESENT(zoom_nj_loc_)) THEN + CALL cxios_set_domain_zoom_nj_loc(domain_hdl%daddr, zoom_nj_loc_) + ENDIF + + + + END SUBROUTINE xios(set_domain_attr_hdl_) + + SUBROUTINE xios(get_domain_attr) & + ( domain_id, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domain)) :: domain_hdl + CHARACTER(LEN=*), INTENT(IN) ::domain_id + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lat(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lon(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_dim + INTEGER , OPTIONAL, INTENT(OUT) :: data_i_index(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: data_j_index(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: data_n_index + INTEGER , OPTIONAL, INTENT(OUT) :: data_ni + INTEGER , OPTIONAL, INTENT(OUT) :: data_nj + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_group_ref + INTEGER , OPTIONAL, INTENT(OUT) :: i_index(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: iend + INTEGER , OPTIONAL, INTENT(OUT) :: j_index(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: jend + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: latvalue(:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: lonvalue(:) + LOGICAL , OPTIONAL, INTENT(OUT) :: mask(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + INTEGER , OPTIONAL, INTENT(OUT) :: ni + INTEGER , OPTIONAL, INTENT(OUT) :: ni_glo + INTEGER , OPTIONAL, INTENT(OUT) :: nj + INTEGER , OPTIONAL, INTENT(OUT) :: nj_glo + INTEGER , OPTIONAL, INTENT(OUT) :: nvertex + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj_loc + + CALL xios(get_domain_handle)(domain_id,domain_hdl) + CALL xios(get_domain_attr_hdl_) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + END SUBROUTINE xios(get_domain_attr) + + SUBROUTINE xios(get_domain_attr_hdl) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domain)) , INTENT(IN) :: domain_hdl + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lat(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lon(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_dim + INTEGER , OPTIONAL, INTENT(OUT) :: data_i_index(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: data_j_index(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: data_n_index + INTEGER , OPTIONAL, INTENT(OUT) :: data_ni + INTEGER , OPTIONAL, INTENT(OUT) :: data_nj + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_group_ref + INTEGER , OPTIONAL, INTENT(OUT) :: i_index(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: iend + INTEGER , OPTIONAL, INTENT(OUT) :: j_index(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: jend + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: latvalue(:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: lonvalue(:) + LOGICAL , OPTIONAL, INTENT(OUT) :: mask(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + INTEGER , OPTIONAL, INTENT(OUT) :: ni + INTEGER , OPTIONAL, INTENT(OUT) :: ni_glo + INTEGER , OPTIONAL, INTENT(OUT) :: nj + INTEGER , OPTIONAL, INTENT(OUT) :: nj_glo + INTEGER , OPTIONAL, INTENT(OUT) :: nvertex + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj_loc + + CALL xios(get_domain_attr_hdl_) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + END SUBROUTINE xios(get_domain_attr_hdl) + + SUBROUTINE xios(get_domain_attr_hdl_) & + ( domain_hdl, bounds_lat_, bounds_lon_, data_dim_, data_i_index_, data_ibegin_, data_j_index_ & + , data_jbegin_, data_n_index_, data_ni_, data_nj_, domain_group_ref_, i_index_, ibegin_, iend_ & + , j_index_, jbegin_, jend_, latvalue_, long_name_, lonvalue_, mask_, name_, ni_, ni_glo_, nj_ & + , nj_glo_, nvertex_, standard_name_, type_, zoom_ibegin_, zoom_ibegin_loc_, zoom_jbegin_, zoom_jbegin_loc_ & + , zoom_ni_, zoom_ni_loc_, zoom_nj_, zoom_nj_loc_ ) + + IMPLICIT NONE + TYPE(txios(domain)) , INTENT(IN) :: domain_hdl + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lat_(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lon_(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_dim_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_i_index_(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_ibegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_j_index_(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_jbegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_n_index_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_ni_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_nj_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_group_ref_ + INTEGER , OPTIONAL, INTENT(OUT) :: i_index_(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: ibegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: iend_ + INTEGER , OPTIONAL, INTENT(OUT) :: j_index_(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: jbegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: jend_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: latvalue_(:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: lonvalue_(:) + LOGICAL , OPTIONAL, INTENT(OUT) :: mask_(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask__tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + INTEGER , OPTIONAL, INTENT(OUT) :: ni_ + INTEGER , OPTIONAL, INTENT(OUT) :: ni_glo_ + INTEGER , OPTIONAL, INTENT(OUT) :: nj_ + INTEGER , OPTIONAL, INTENT(OUT) :: nj_glo_ + INTEGER , OPTIONAL, INTENT(OUT) :: nvertex_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni_loc_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj_loc_ + + IF (PRESENT(bounds_lat_)) THEN + CALL cxios_get_domain_bounds_lat(domain_hdl%daddr, bounds_lat_,size(bounds_lat_,1),size(bounds_lat_,2)) + ENDIF + + IF (PRESENT(bounds_lon_)) THEN + CALL cxios_get_domain_bounds_lon(domain_hdl%daddr, bounds_lon_,size(bounds_lon_,1),size(bounds_lon_,2)) + ENDIF + + IF (PRESENT(data_dim_)) THEN + CALL cxios_get_domain_data_dim(domain_hdl%daddr, data_dim_) + ENDIF + + IF (PRESENT(data_i_index_)) THEN + CALL cxios_get_domain_data_i_index(domain_hdl%daddr, data_i_index_,size(data_i_index_,1)) + ENDIF + + IF (PRESENT(data_ibegin_)) THEN + CALL cxios_get_domain_data_ibegin(domain_hdl%daddr, data_ibegin_) + ENDIF + + IF (PRESENT(data_j_index_)) THEN + CALL cxios_get_domain_data_j_index(domain_hdl%daddr, data_j_index_,size(data_j_index_,1)) + ENDIF + + IF (PRESENT(data_jbegin_)) THEN + CALL cxios_get_domain_data_jbegin(domain_hdl%daddr, data_jbegin_) + ENDIF + + IF (PRESENT(data_n_index_)) THEN + CALL cxios_get_domain_data_n_index(domain_hdl%daddr, data_n_index_) + ENDIF + + IF (PRESENT(data_ni_)) THEN + CALL cxios_get_domain_data_ni(domain_hdl%daddr, data_ni_) + ENDIF + + IF (PRESENT(data_nj_)) THEN + CALL cxios_get_domain_data_nj(domain_hdl%daddr, data_nj_) + ENDIF + + IF (PRESENT(domain_group_ref_)) THEN + CALL cxios_get_domain_domain_group_ref(domain_hdl%daddr, domain_group_ref_, len(domain_group_ref_)) + ENDIF + + IF (PRESENT(i_index_)) THEN + CALL cxios_get_domain_i_index(domain_hdl%daddr, i_index_,size(i_index_,1),size(i_index_,2)) + ENDIF + + IF (PRESENT(ibegin_)) THEN + CALL cxios_get_domain_ibegin(domain_hdl%daddr, ibegin_) + ENDIF + + IF (PRESENT(iend_)) THEN + CALL cxios_get_domain_iend(domain_hdl%daddr, iend_) + ENDIF + + IF (PRESENT(j_index_)) THEN + CALL cxios_get_domain_j_index(domain_hdl%daddr, j_index_,size(j_index_,1),size(j_index_,2)) + ENDIF + + IF (PRESENT(jbegin_)) THEN + CALL cxios_get_domain_jbegin(domain_hdl%daddr, jbegin_) + ENDIF + + IF (PRESENT(jend_)) THEN + CALL cxios_get_domain_jend(domain_hdl%daddr, jend_) + ENDIF + + IF (PRESENT(latvalue_)) THEN + CALL cxios_get_domain_latvalue(domain_hdl%daddr, latvalue_,size(latvalue_,1)) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_get_domain_long_name(domain_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(lonvalue_)) THEN + CALL cxios_get_domain_lonvalue(domain_hdl%daddr, lonvalue_,size(lonvalue_,1)) + ENDIF + + IF (PRESENT(mask_)) THEN + ALLOCATE(mask__tmp(size(mask_,1),size(mask_,2))) + CALL cxios_get_domain_mask(domain_hdl%daddr, mask__tmp,size(mask_,1),size(mask_,2)) + mask_=mask__tmp + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_domain_name(domain_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(ni_)) THEN + CALL cxios_get_domain_ni(domain_hdl%daddr, ni_) + ENDIF + + IF (PRESENT(ni_glo_)) THEN + CALL cxios_get_domain_ni_glo(domain_hdl%daddr, ni_glo_) + ENDIF + + IF (PRESENT(nj_)) THEN + CALL cxios_get_domain_nj(domain_hdl%daddr, nj_) + ENDIF + + IF (PRESENT(nj_glo_)) THEN + CALL cxios_get_domain_nj_glo(domain_hdl%daddr, nj_glo_) + ENDIF + + IF (PRESENT(nvertex_)) THEN + CALL cxios_get_domain_nvertex(domain_hdl%daddr, nvertex_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_get_domain_standard_name(domain_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_get_domain_type(domain_hdl%daddr, type_, len(type_)) + ENDIF + + IF (PRESENT(zoom_ibegin_)) THEN + CALL cxios_get_domain_zoom_ibegin(domain_hdl%daddr, zoom_ibegin_) + ENDIF + + IF (PRESENT(zoom_ibegin_loc_)) THEN + CALL cxios_get_domain_zoom_ibegin_loc(domain_hdl%daddr, zoom_ibegin_loc_) + ENDIF + + IF (PRESENT(zoom_jbegin_)) THEN + CALL cxios_get_domain_zoom_jbegin(domain_hdl%daddr, zoom_jbegin_) + ENDIF + + IF (PRESENT(zoom_jbegin_loc_)) THEN + CALL cxios_get_domain_zoom_jbegin_loc(domain_hdl%daddr, zoom_jbegin_loc_) + ENDIF + + IF (PRESENT(zoom_ni_)) THEN + CALL cxios_get_domain_zoom_ni(domain_hdl%daddr, zoom_ni_) + ENDIF + + IF (PRESENT(zoom_ni_loc_)) THEN + CALL cxios_get_domain_zoom_ni_loc(domain_hdl%daddr, zoom_ni_loc_) + ENDIF + + IF (PRESENT(zoom_nj_)) THEN + CALL cxios_get_domain_zoom_nj(domain_hdl%daddr, zoom_nj_) + ENDIF + + IF (PRESENT(zoom_nj_loc_)) THEN + CALL cxios_get_domain_zoom_nj_loc(domain_hdl%daddr, zoom_nj_loc_) + ENDIF + + + + END SUBROUTINE xios(get_domain_attr_hdl_) + + SUBROUTINE xios(is_defined_domain_attr) & + ( domain_id, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domain)) :: domain_hdl + CHARACTER(LEN=*), INTENT(IN) ::domain_id + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lat + LOGICAL(KIND=C_BOOL) :: bounds_lat_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lon + LOGICAL(KIND=C_BOOL) :: bounds_lon_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_dim + LOGICAL(KIND=C_BOOL) :: data_dim_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_i_index + LOGICAL(KIND=C_BOOL) :: data_i_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ibegin + LOGICAL(KIND=C_BOOL) :: data_ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_j_index + LOGICAL(KIND=C_BOOL) :: data_j_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_jbegin + LOGICAL(KIND=C_BOOL) :: data_jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_n_index + LOGICAL(KIND=C_BOOL) :: data_n_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ni + LOGICAL(KIND=C_BOOL) :: data_ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_nj + LOGICAL(KIND=C_BOOL) :: data_nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_group_ref + LOGICAL(KIND=C_BOOL) :: domain_group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: i_index + LOGICAL(KIND=C_BOOL) :: i_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ibegin + LOGICAL(KIND=C_BOOL) :: ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: iend + LOGICAL(KIND=C_BOOL) :: iend_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: j_index + LOGICAL(KIND=C_BOOL) :: j_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jbegin + LOGICAL(KIND=C_BOOL) :: jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jend + LOGICAL(KIND=C_BOOL) :: jend_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: latvalue + LOGICAL(KIND=C_BOOL) :: latvalue_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: lonvalue + LOGICAL(KIND=C_BOOL) :: lonvalue_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask + LOGICAL(KIND=C_BOOL) :: mask_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni + LOGICAL(KIND=C_BOOL) :: ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni_glo + LOGICAL(KIND=C_BOOL) :: ni_glo_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj + LOGICAL(KIND=C_BOOL) :: nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj_glo + LOGICAL(KIND=C_BOOL) :: nj_glo_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nvertex + LOGICAL(KIND=C_BOOL) :: nvertex_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni + LOGICAL(KIND=C_BOOL) :: zoom_ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni_loc + LOGICAL(KIND=C_BOOL) :: zoom_ni_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj + LOGICAL(KIND=C_BOOL) :: zoom_nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj_loc + LOGICAL(KIND=C_BOOL) :: zoom_nj_loc_tmp + + CALL xios(get_domain_handle)(domain_id,domain_hdl) + CALL xios(is_defined_domain_attr_hdl_) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + END SUBROUTINE xios(is_defined_domain_attr) + + SUBROUTINE xios(is_defined_domain_attr_hdl) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domain)) , INTENT(IN) :: domain_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lat + LOGICAL(KIND=C_BOOL) :: bounds_lat_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lon + LOGICAL(KIND=C_BOOL) :: bounds_lon_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_dim + LOGICAL(KIND=C_BOOL) :: data_dim_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_i_index + LOGICAL(KIND=C_BOOL) :: data_i_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ibegin + LOGICAL(KIND=C_BOOL) :: data_ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_j_index + LOGICAL(KIND=C_BOOL) :: data_j_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_jbegin + LOGICAL(KIND=C_BOOL) :: data_jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_n_index + LOGICAL(KIND=C_BOOL) :: data_n_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ni + LOGICAL(KIND=C_BOOL) :: data_ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_nj + LOGICAL(KIND=C_BOOL) :: data_nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_group_ref + LOGICAL(KIND=C_BOOL) :: domain_group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: i_index + LOGICAL(KIND=C_BOOL) :: i_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ibegin + LOGICAL(KIND=C_BOOL) :: ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: iend + LOGICAL(KIND=C_BOOL) :: iend_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: j_index + LOGICAL(KIND=C_BOOL) :: j_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jbegin + LOGICAL(KIND=C_BOOL) :: jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jend + LOGICAL(KIND=C_BOOL) :: jend_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: latvalue + LOGICAL(KIND=C_BOOL) :: latvalue_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: lonvalue + LOGICAL(KIND=C_BOOL) :: lonvalue_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask + LOGICAL(KIND=C_BOOL) :: mask_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni + LOGICAL(KIND=C_BOOL) :: ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni_glo + LOGICAL(KIND=C_BOOL) :: ni_glo_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj + LOGICAL(KIND=C_BOOL) :: nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj_glo + LOGICAL(KIND=C_BOOL) :: nj_glo_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nvertex + LOGICAL(KIND=C_BOOL) :: nvertex_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni + LOGICAL(KIND=C_BOOL) :: zoom_ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni_loc + LOGICAL(KIND=C_BOOL) :: zoom_ni_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj + LOGICAL(KIND=C_BOOL) :: zoom_nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj_loc + LOGICAL(KIND=C_BOOL) :: zoom_nj_loc_tmp + + CALL xios(is_defined_domain_attr_hdl_) & + ( domain_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index, data_jbegin & + , data_n_index, data_ni, data_nj, domain_group_ref, i_index, ibegin, iend, j_index, jbegin, jend & + , latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo, nvertex, standard_name & + , type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni, zoom_ni_loc, zoom_nj & + , zoom_nj_loc ) + + END SUBROUTINE xios(is_defined_domain_attr_hdl) + + SUBROUTINE xios(is_defined_domain_attr_hdl_) & + ( domain_hdl, bounds_lat_, bounds_lon_, data_dim_, data_i_index_, data_ibegin_, data_j_index_ & + , data_jbegin_, data_n_index_, data_ni_, data_nj_, domain_group_ref_, i_index_, ibegin_, iend_ & + , j_index_, jbegin_, jend_, latvalue_, long_name_, lonvalue_, mask_, name_, ni_, ni_glo_, nj_ & + , nj_glo_, nvertex_, standard_name_, type_, zoom_ibegin_, zoom_ibegin_loc_, zoom_jbegin_, zoom_jbegin_loc_ & + , zoom_ni_, zoom_ni_loc_, zoom_nj_, zoom_nj_loc_ ) + + IMPLICIT NONE + TYPE(txios(domain)) , INTENT(IN) :: domain_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lat_ + LOGICAL(KIND=C_BOOL) :: bounds_lat__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lon_ + LOGICAL(KIND=C_BOOL) :: bounds_lon__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_dim_ + LOGICAL(KIND=C_BOOL) :: data_dim__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_i_index_ + LOGICAL(KIND=C_BOOL) :: data_i_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ibegin_ + LOGICAL(KIND=C_BOOL) :: data_ibegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_j_index_ + LOGICAL(KIND=C_BOOL) :: data_j_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_jbegin_ + LOGICAL(KIND=C_BOOL) :: data_jbegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_n_index_ + LOGICAL(KIND=C_BOOL) :: data_n_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ni_ + LOGICAL(KIND=C_BOOL) :: data_ni__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_nj_ + LOGICAL(KIND=C_BOOL) :: data_nj__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_group_ref_ + LOGICAL(KIND=C_BOOL) :: domain_group_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: i_index_ + LOGICAL(KIND=C_BOOL) :: i_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ibegin_ + LOGICAL(KIND=C_BOOL) :: ibegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: iend_ + LOGICAL(KIND=C_BOOL) :: iend__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: j_index_ + LOGICAL(KIND=C_BOOL) :: j_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jbegin_ + LOGICAL(KIND=C_BOOL) :: jbegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jend_ + LOGICAL(KIND=C_BOOL) :: jend__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: latvalue_ + LOGICAL(KIND=C_BOOL) :: latvalue__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name_ + LOGICAL(KIND=C_BOOL) :: long_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: lonvalue_ + LOGICAL(KIND=C_BOOL) :: lonvalue__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask_ + LOGICAL(KIND=C_BOOL) :: mask__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni_ + LOGICAL(KIND=C_BOOL) :: ni__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni_glo_ + LOGICAL(KIND=C_BOOL) :: ni_glo__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj_ + LOGICAL(KIND=C_BOOL) :: nj__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj_glo_ + LOGICAL(KIND=C_BOOL) :: nj_glo__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nvertex_ + LOGICAL(KIND=C_BOOL) :: nvertex__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name_ + LOGICAL(KIND=C_BOOL) :: standard_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type_ + LOGICAL(KIND=C_BOOL) :: type__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin_ + LOGICAL(KIND=C_BOOL) :: zoom_ibegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc_ + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_loc__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin_ + LOGICAL(KIND=C_BOOL) :: zoom_jbegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc_ + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_loc__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni_ + LOGICAL(KIND=C_BOOL) :: zoom_ni__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni_loc_ + LOGICAL(KIND=C_BOOL) :: zoom_ni_loc__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj_ + LOGICAL(KIND=C_BOOL) :: zoom_nj__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj_loc_ + LOGICAL(KIND=C_BOOL) :: zoom_nj_loc__tmp + + IF (PRESENT(bounds_lat_)) THEN + bounds_lat__tmp=cxios_is_defined_domain_bounds_lat(domain_hdl%daddr) + bounds_lat_=bounds_lat__tmp + ENDIF + + IF (PRESENT(bounds_lon_)) THEN + bounds_lon__tmp=cxios_is_defined_domain_bounds_lon(domain_hdl%daddr) + bounds_lon_=bounds_lon__tmp + ENDIF + + IF (PRESENT(data_dim_)) THEN + data_dim__tmp=cxios_is_defined_domain_data_dim(domain_hdl%daddr) + data_dim_=data_dim__tmp + ENDIF + + IF (PRESENT(data_i_index_)) THEN + data_i_index__tmp=cxios_is_defined_domain_data_i_index(domain_hdl%daddr) + data_i_index_=data_i_index__tmp + ENDIF + + IF (PRESENT(data_ibegin_)) THEN + data_ibegin__tmp=cxios_is_defined_domain_data_ibegin(domain_hdl%daddr) + data_ibegin_=data_ibegin__tmp + ENDIF + + IF (PRESENT(data_j_index_)) THEN + data_j_index__tmp=cxios_is_defined_domain_data_j_index(domain_hdl%daddr) + data_j_index_=data_j_index__tmp + ENDIF + + IF (PRESENT(data_jbegin_)) THEN + data_jbegin__tmp=cxios_is_defined_domain_data_jbegin(domain_hdl%daddr) + data_jbegin_=data_jbegin__tmp + ENDIF + + IF (PRESENT(data_n_index_)) THEN + data_n_index__tmp=cxios_is_defined_domain_data_n_index(domain_hdl%daddr) + data_n_index_=data_n_index__tmp + ENDIF + + IF (PRESENT(data_ni_)) THEN + data_ni__tmp=cxios_is_defined_domain_data_ni(domain_hdl%daddr) + data_ni_=data_ni__tmp + ENDIF + + IF (PRESENT(data_nj_)) THEN + data_nj__tmp=cxios_is_defined_domain_data_nj(domain_hdl%daddr) + data_nj_=data_nj__tmp + ENDIF + + IF (PRESENT(domain_group_ref_)) THEN + domain_group_ref__tmp=cxios_is_defined_domain_domain_group_ref(domain_hdl%daddr) + domain_group_ref_=domain_group_ref__tmp + ENDIF + + IF (PRESENT(i_index_)) THEN + i_index__tmp=cxios_is_defined_domain_i_index(domain_hdl%daddr) + i_index_=i_index__tmp + ENDIF + + IF (PRESENT(ibegin_)) THEN + ibegin__tmp=cxios_is_defined_domain_ibegin(domain_hdl%daddr) + ibegin_=ibegin__tmp + ENDIF + + IF (PRESENT(iend_)) THEN + iend__tmp=cxios_is_defined_domain_iend(domain_hdl%daddr) + iend_=iend__tmp + ENDIF + + IF (PRESENT(j_index_)) THEN + j_index__tmp=cxios_is_defined_domain_j_index(domain_hdl%daddr) + j_index_=j_index__tmp + ENDIF + + IF (PRESENT(jbegin_)) THEN + jbegin__tmp=cxios_is_defined_domain_jbegin(domain_hdl%daddr) + jbegin_=jbegin__tmp + ENDIF + + IF (PRESENT(jend_)) THEN + jend__tmp=cxios_is_defined_domain_jend(domain_hdl%daddr) + jend_=jend__tmp + ENDIF + + IF (PRESENT(latvalue_)) THEN + latvalue__tmp=cxios_is_defined_domain_latvalue(domain_hdl%daddr) + latvalue_=latvalue__tmp + ENDIF + + IF (PRESENT(long_name_)) THEN + long_name__tmp=cxios_is_defined_domain_long_name(domain_hdl%daddr) + long_name_=long_name__tmp + ENDIF + + IF (PRESENT(lonvalue_)) THEN + lonvalue__tmp=cxios_is_defined_domain_lonvalue(domain_hdl%daddr) + lonvalue_=lonvalue__tmp + ENDIF + + IF (PRESENT(mask_)) THEN + mask__tmp=cxios_is_defined_domain_mask(domain_hdl%daddr) + mask_=mask__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_domain_name(domain_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(ni_)) THEN + ni__tmp=cxios_is_defined_domain_ni(domain_hdl%daddr) + ni_=ni__tmp + ENDIF + + IF (PRESENT(ni_glo_)) THEN + ni_glo__tmp=cxios_is_defined_domain_ni_glo(domain_hdl%daddr) + ni_glo_=ni_glo__tmp + ENDIF + + IF (PRESENT(nj_)) THEN + nj__tmp=cxios_is_defined_domain_nj(domain_hdl%daddr) + nj_=nj__tmp + ENDIF + + IF (PRESENT(nj_glo_)) THEN + nj_glo__tmp=cxios_is_defined_domain_nj_glo(domain_hdl%daddr) + nj_glo_=nj_glo__tmp + ENDIF + + IF (PRESENT(nvertex_)) THEN + nvertex__tmp=cxios_is_defined_domain_nvertex(domain_hdl%daddr) + nvertex_=nvertex__tmp + ENDIF + + IF (PRESENT(standard_name_)) THEN + standard_name__tmp=cxios_is_defined_domain_standard_name(domain_hdl%daddr) + standard_name_=standard_name__tmp + ENDIF + + IF (PRESENT(type_)) THEN + type__tmp=cxios_is_defined_domain_type(domain_hdl%daddr) + type_=type__tmp + ENDIF + + IF (PRESENT(zoom_ibegin_)) THEN + zoom_ibegin__tmp=cxios_is_defined_domain_zoom_ibegin(domain_hdl%daddr) + zoom_ibegin_=zoom_ibegin__tmp + ENDIF + + IF (PRESENT(zoom_ibegin_loc_)) THEN + zoom_ibegin_loc__tmp=cxios_is_defined_domain_zoom_ibegin_loc(domain_hdl%daddr) + zoom_ibegin_loc_=zoom_ibegin_loc__tmp + ENDIF + + IF (PRESENT(zoom_jbegin_)) THEN + zoom_jbegin__tmp=cxios_is_defined_domain_zoom_jbegin(domain_hdl%daddr) + zoom_jbegin_=zoom_jbegin__tmp + ENDIF + + IF (PRESENT(zoom_jbegin_loc_)) THEN + zoom_jbegin_loc__tmp=cxios_is_defined_domain_zoom_jbegin_loc(domain_hdl%daddr) + zoom_jbegin_loc_=zoom_jbegin_loc__tmp + ENDIF + + IF (PRESENT(zoom_ni_)) THEN + zoom_ni__tmp=cxios_is_defined_domain_zoom_ni(domain_hdl%daddr) + zoom_ni_=zoom_ni__tmp + ENDIF + + IF (PRESENT(zoom_ni_loc_)) THEN + zoom_ni_loc__tmp=cxios_is_defined_domain_zoom_ni_loc(domain_hdl%daddr) + zoom_ni_loc_=zoom_ni_loc__tmp + ENDIF + + IF (PRESENT(zoom_nj_)) THEN + zoom_nj__tmp=cxios_is_defined_domain_zoom_nj(domain_hdl%daddr) + zoom_nj_=zoom_nj__tmp + ENDIF + + IF (PRESENT(zoom_nj_loc_)) THEN + zoom_nj_loc__tmp=cxios_is_defined_domain_zoom_nj_loc(domain_hdl%daddr) + zoom_nj_loc_=zoom_nj_loc__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_domain_attr_hdl_) + +END MODULE idomain_attr diff --git a/src/interface/fortran_attr/idomaingroup_attr.F90 b/src/interface/fortran_attr/idomaingroup_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..a95f197e852bcace886e8a7258a0a7671faa6d48 --- /dev/null +++ b/src/interface/fortran_attr/idomaingroup_attr.F90 @@ -0,0 +1,1135 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE idomaingroup_attr + USE, INTRINSIC :: ISO_C_BINDING + USE idomain + USE domaingroup_interface_attr + +CONTAINS + + SUBROUTINE xios(set_domaingroup_attr) & + ( domaingroup_id, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) :: domaingroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::domaingroup_id + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lat(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lon(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: data_dim + INTEGER , OPTIONAL, INTENT(IN) :: data_i_index(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_ibegin + INTEGER , OPTIONAL, INTENT(IN) :: data_j_index(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_jbegin + INTEGER , OPTIONAL, INTENT(IN) :: data_n_index + INTEGER , OPTIONAL, INTENT(IN) :: data_ni + INTEGER , OPTIONAL, INTENT(IN) :: data_nj + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + INTEGER , OPTIONAL, INTENT(IN) :: i_index(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: ibegin + INTEGER , OPTIONAL, INTENT(IN) :: iend + INTEGER , OPTIONAL, INTENT(IN) :: j_index(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: jbegin + INTEGER , OPTIONAL, INTENT(IN) :: jend + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: latvalue(:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: lonvalue(:) + LOGICAL , OPTIONAL, INTENT(IN) :: mask(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + INTEGER , OPTIONAL, INTENT(IN) :: ni + INTEGER , OPTIONAL, INTENT(IN) :: ni_glo + INTEGER , OPTIONAL, INTENT(IN) :: nj + INTEGER , OPTIONAL, INTENT(IN) :: nj_glo + INTEGER , OPTIONAL, INTENT(IN) :: nvertex + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj_loc + + CALL xios(get_domaingroup_handle)(domaingroup_id,domaingroup_hdl) + CALL xios(set_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + END SUBROUTINE xios(set_domaingroup_attr) + + SUBROUTINE xios(set_domaingroup_attr_hdl) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) , INTENT(IN) :: domaingroup_hdl + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lat(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lon(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: data_dim + INTEGER , OPTIONAL, INTENT(IN) :: data_i_index(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_ibegin + INTEGER , OPTIONAL, INTENT(IN) :: data_j_index(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_jbegin + INTEGER , OPTIONAL, INTENT(IN) :: data_n_index + INTEGER , OPTIONAL, INTENT(IN) :: data_ni + INTEGER , OPTIONAL, INTENT(IN) :: data_nj + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + INTEGER , OPTIONAL, INTENT(IN) :: i_index(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: ibegin + INTEGER , OPTIONAL, INTENT(IN) :: iend + INTEGER , OPTIONAL, INTENT(IN) :: j_index(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: jbegin + INTEGER , OPTIONAL, INTENT(IN) :: jend + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: latvalue(:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: lonvalue(:) + LOGICAL , OPTIONAL, INTENT(IN) :: mask(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + INTEGER , OPTIONAL, INTENT(IN) :: ni + INTEGER , OPTIONAL, INTENT(IN) :: ni_glo + INTEGER , OPTIONAL, INTENT(IN) :: nj + INTEGER , OPTIONAL, INTENT(IN) :: nj_glo + INTEGER , OPTIONAL, INTENT(IN) :: nvertex + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni_loc + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj_loc + + CALL xios(set_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + END SUBROUTINE xios(set_domaingroup_attr_hdl) + + SUBROUTINE xios(set_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat_, bounds_lon_, data_dim_, data_i_index_, data_ibegin_, data_j_index_ & + , data_jbegin_, data_n_index_, data_ni_, data_nj_, domain_group_ref_, group_ref_, i_index_, ibegin_ & + , iend_, j_index_, jbegin_, jend_, latvalue_, long_name_, lonvalue_, mask_, name_, ni_, ni_glo_ & + , nj_, nj_glo_, nvertex_, standard_name_, type_, zoom_ibegin_, zoom_ibegin_loc_, zoom_jbegin_ & + , zoom_jbegin_loc_, zoom_ni_, zoom_ni_loc_, zoom_nj_, zoom_nj_loc_ ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) , INTENT(IN) :: domaingroup_hdl + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lat_(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: bounds_lon_(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: data_dim_ + INTEGER , OPTIONAL, INTENT(IN) :: data_i_index_(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_ibegin_ + INTEGER , OPTIONAL, INTENT(IN) :: data_j_index_(:) + INTEGER , OPTIONAL, INTENT(IN) :: data_jbegin_ + INTEGER , OPTIONAL, INTENT(IN) :: data_n_index_ + INTEGER , OPTIONAL, INTENT(IN) :: data_ni_ + INTEGER , OPTIONAL, INTENT(IN) :: data_nj_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_group_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref_ + INTEGER , OPTIONAL, INTENT(IN) :: i_index_(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: ibegin_ + INTEGER , OPTIONAL, INTENT(IN) :: iend_ + INTEGER , OPTIONAL, INTENT(IN) :: j_index_(:,:) + INTEGER , OPTIONAL, INTENT(IN) :: jbegin_ + INTEGER , OPTIONAL, INTENT(IN) :: jend_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: latvalue_(:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: lonvalue_(:) + LOGICAL , OPTIONAL, INTENT(IN) :: mask_(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask__tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + INTEGER , OPTIONAL, INTENT(IN) :: ni_ + INTEGER , OPTIONAL, INTENT(IN) :: ni_glo_ + INTEGER , OPTIONAL, INTENT(IN) :: nj_ + INTEGER , OPTIONAL, INTENT(IN) :: nj_glo_ + INTEGER , OPTIONAL, INTENT(IN) :: nvertex_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ibegin_loc_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_jbegin_loc_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_ni_loc_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj_ + INTEGER , OPTIONAL, INTENT(IN) :: zoom_nj_loc_ + + IF (PRESENT(bounds_lat_)) THEN + CALL cxios_set_domaingroup_bounds_lat(domaingroup_hdl%daddr, bounds_lat_,size(bounds_lat_,1),size(bounds_lat_,2)) + ENDIF + + IF (PRESENT(bounds_lon_)) THEN + CALL cxios_set_domaingroup_bounds_lon(domaingroup_hdl%daddr, bounds_lon_,size(bounds_lon_,1),size(bounds_lon_,2)) + ENDIF + + IF (PRESENT(data_dim_)) THEN + CALL cxios_set_domaingroup_data_dim(domaingroup_hdl%daddr, data_dim_) + ENDIF + + IF (PRESENT(data_i_index_)) THEN + CALL cxios_set_domaingroup_data_i_index(domaingroup_hdl%daddr, data_i_index_,size(data_i_index_,1)) + ENDIF + + IF (PRESENT(data_ibegin_)) THEN + CALL cxios_set_domaingroup_data_ibegin(domaingroup_hdl%daddr, data_ibegin_) + ENDIF + + IF (PRESENT(data_j_index_)) THEN + CALL cxios_set_domaingroup_data_j_index(domaingroup_hdl%daddr, data_j_index_,size(data_j_index_,1)) + ENDIF + + IF (PRESENT(data_jbegin_)) THEN + CALL cxios_set_domaingroup_data_jbegin(domaingroup_hdl%daddr, data_jbegin_) + ENDIF + + IF (PRESENT(data_n_index_)) THEN + CALL cxios_set_domaingroup_data_n_index(domaingroup_hdl%daddr, data_n_index_) + ENDIF + + IF (PRESENT(data_ni_)) THEN + CALL cxios_set_domaingroup_data_ni(domaingroup_hdl%daddr, data_ni_) + ENDIF + + IF (PRESENT(data_nj_)) THEN + CALL cxios_set_domaingroup_data_nj(domaingroup_hdl%daddr, data_nj_) + ENDIF + + IF (PRESENT(domain_group_ref_)) THEN + CALL cxios_set_domaingroup_domain_group_ref(domaingroup_hdl%daddr, domain_group_ref_, len(domain_group_ref_)) + ENDIF + + IF (PRESENT(group_ref_)) THEN + CALL cxios_set_domaingroup_group_ref(domaingroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(i_index_)) THEN + CALL cxios_set_domaingroup_i_index(domaingroup_hdl%daddr, i_index_,size(i_index_,1),size(i_index_,2)) + ENDIF + + IF (PRESENT(ibegin_)) THEN + CALL cxios_set_domaingroup_ibegin(domaingroup_hdl%daddr, ibegin_) + ENDIF + + IF (PRESENT(iend_)) THEN + CALL cxios_set_domaingroup_iend(domaingroup_hdl%daddr, iend_) + ENDIF + + IF (PRESENT(j_index_)) THEN + CALL cxios_set_domaingroup_j_index(domaingroup_hdl%daddr, j_index_,size(j_index_,1),size(j_index_,2)) + ENDIF + + IF (PRESENT(jbegin_)) THEN + CALL cxios_set_domaingroup_jbegin(domaingroup_hdl%daddr, jbegin_) + ENDIF + + IF (PRESENT(jend_)) THEN + CALL cxios_set_domaingroup_jend(domaingroup_hdl%daddr, jend_) + ENDIF + + IF (PRESENT(latvalue_)) THEN + CALL cxios_set_domaingroup_latvalue(domaingroup_hdl%daddr, latvalue_,size(latvalue_,1)) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_set_domaingroup_long_name(domaingroup_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(lonvalue_)) THEN + CALL cxios_set_domaingroup_lonvalue(domaingroup_hdl%daddr, lonvalue_,size(lonvalue_,1)) + ENDIF + + IF (PRESENT(mask_)) THEN + ALLOCATE(mask__tmp(size(mask_,1),size(mask_,2))) + mask__tmp=mask_ + CALL cxios_set_domaingroup_mask(domaingroup_hdl%daddr, mask__tmp,size(mask_,1),size(mask_,2)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_domaingroup_name(domaingroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(ni_)) THEN + CALL cxios_set_domaingroup_ni(domaingroup_hdl%daddr, ni_) + ENDIF + + IF (PRESENT(ni_glo_)) THEN + CALL cxios_set_domaingroup_ni_glo(domaingroup_hdl%daddr, ni_glo_) + ENDIF + + IF (PRESENT(nj_)) THEN + CALL cxios_set_domaingroup_nj(domaingroup_hdl%daddr, nj_) + ENDIF + + IF (PRESENT(nj_glo_)) THEN + CALL cxios_set_domaingroup_nj_glo(domaingroup_hdl%daddr, nj_glo_) + ENDIF + + IF (PRESENT(nvertex_)) THEN + CALL cxios_set_domaingroup_nvertex(domaingroup_hdl%daddr, nvertex_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_set_domaingroup_standard_name(domaingroup_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_set_domaingroup_type(domaingroup_hdl%daddr, type_, len(type_)) + ENDIF + + IF (PRESENT(zoom_ibegin_)) THEN + CALL cxios_set_domaingroup_zoom_ibegin(domaingroup_hdl%daddr, zoom_ibegin_) + ENDIF + + IF (PRESENT(zoom_ibegin_loc_)) THEN + CALL cxios_set_domaingroup_zoom_ibegin_loc(domaingroup_hdl%daddr, zoom_ibegin_loc_) + ENDIF + + IF (PRESENT(zoom_jbegin_)) THEN + CALL cxios_set_domaingroup_zoom_jbegin(domaingroup_hdl%daddr, zoom_jbegin_) + ENDIF + + IF (PRESENT(zoom_jbegin_loc_)) THEN + CALL cxios_set_domaingroup_zoom_jbegin_loc(domaingroup_hdl%daddr, zoom_jbegin_loc_) + ENDIF + + IF (PRESENT(zoom_ni_)) THEN + CALL cxios_set_domaingroup_zoom_ni(domaingroup_hdl%daddr, zoom_ni_) + ENDIF + + IF (PRESENT(zoom_ni_loc_)) THEN + CALL cxios_set_domaingroup_zoom_ni_loc(domaingroup_hdl%daddr, zoom_ni_loc_) + ENDIF + + IF (PRESENT(zoom_nj_)) THEN + CALL cxios_set_domaingroup_zoom_nj(domaingroup_hdl%daddr, zoom_nj_) + ENDIF + + IF (PRESENT(zoom_nj_loc_)) THEN + CALL cxios_set_domaingroup_zoom_nj_loc(domaingroup_hdl%daddr, zoom_nj_loc_) + ENDIF + + + + END SUBROUTINE xios(set_domaingroup_attr_hdl_) + + SUBROUTINE xios(get_domaingroup_attr) & + ( domaingroup_id, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) :: domaingroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::domaingroup_id + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lat(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lon(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_dim + INTEGER , OPTIONAL, INTENT(OUT) :: data_i_index(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: data_j_index(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: data_n_index + INTEGER , OPTIONAL, INTENT(OUT) :: data_ni + INTEGER , OPTIONAL, INTENT(OUT) :: data_nj + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + INTEGER , OPTIONAL, INTENT(OUT) :: i_index(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: iend + INTEGER , OPTIONAL, INTENT(OUT) :: j_index(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: jend + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: latvalue(:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: lonvalue(:) + LOGICAL , OPTIONAL, INTENT(OUT) :: mask(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + INTEGER , OPTIONAL, INTENT(OUT) :: ni + INTEGER , OPTIONAL, INTENT(OUT) :: ni_glo + INTEGER , OPTIONAL, INTENT(OUT) :: nj + INTEGER , OPTIONAL, INTENT(OUT) :: nj_glo + INTEGER , OPTIONAL, INTENT(OUT) :: nvertex + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj_loc + + CALL xios(get_domaingroup_handle)(domaingroup_id,domaingroup_hdl) + CALL xios(get_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + END SUBROUTINE xios(get_domaingroup_attr) + + SUBROUTINE xios(get_domaingroup_attr_hdl) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) , INTENT(IN) :: domaingroup_hdl + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lat(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lon(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_dim + INTEGER , OPTIONAL, INTENT(OUT) :: data_i_index(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: data_j_index(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: data_n_index + INTEGER , OPTIONAL, INTENT(OUT) :: data_ni + INTEGER , OPTIONAL, INTENT(OUT) :: data_nj + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + INTEGER , OPTIONAL, INTENT(OUT) :: i_index(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: iend + INTEGER , OPTIONAL, INTENT(OUT) :: j_index(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: jend + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: latvalue(:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: lonvalue(:) + LOGICAL , OPTIONAL, INTENT(OUT) :: mask(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + INTEGER , OPTIONAL, INTENT(OUT) :: ni + INTEGER , OPTIONAL, INTENT(OUT) :: ni_glo + INTEGER , OPTIONAL, INTENT(OUT) :: nj + INTEGER , OPTIONAL, INTENT(OUT) :: nj_glo + INTEGER , OPTIONAL, INTENT(OUT) :: nvertex + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni_loc + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj_loc + + CALL xios(get_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + END SUBROUTINE xios(get_domaingroup_attr_hdl) + + SUBROUTINE xios(get_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat_, bounds_lon_, data_dim_, data_i_index_, data_ibegin_, data_j_index_ & + , data_jbegin_, data_n_index_, data_ni_, data_nj_, domain_group_ref_, group_ref_, i_index_, ibegin_ & + , iend_, j_index_, jbegin_, jend_, latvalue_, long_name_, lonvalue_, mask_, name_, ni_, ni_glo_ & + , nj_, nj_glo_, nvertex_, standard_name_, type_, zoom_ibegin_, zoom_ibegin_loc_, zoom_jbegin_ & + , zoom_jbegin_loc_, zoom_ni_, zoom_ni_loc_, zoom_nj_, zoom_nj_loc_ ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) , INTENT(IN) :: domaingroup_hdl + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lat_(:,:) + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: bounds_lon_(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_dim_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_i_index_(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_ibegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_j_index_(:) + INTEGER , OPTIONAL, INTENT(OUT) :: data_jbegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_n_index_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_ni_ + INTEGER , OPTIONAL, INTENT(OUT) :: data_nj_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_group_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref_ + INTEGER , OPTIONAL, INTENT(OUT) :: i_index_(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: ibegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: iend_ + INTEGER , OPTIONAL, INTENT(OUT) :: j_index_(:,:) + INTEGER , OPTIONAL, INTENT(OUT) :: jbegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: jend_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: latvalue_(:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: lonvalue_(:) + LOGICAL , OPTIONAL, INTENT(OUT) :: mask_(:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask__tmp(:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + INTEGER , OPTIONAL, INTENT(OUT) :: ni_ + INTEGER , OPTIONAL, INTENT(OUT) :: ni_glo_ + INTEGER , OPTIONAL, INTENT(OUT) :: nj_ + INTEGER , OPTIONAL, INTENT(OUT) :: nj_glo_ + INTEGER , OPTIONAL, INTENT(OUT) :: nvertex_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_ni_loc_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj_ + INTEGER , OPTIONAL, INTENT(OUT) :: zoom_nj_loc_ + + IF (PRESENT(bounds_lat_)) THEN + CALL cxios_get_domaingroup_bounds_lat(domaingroup_hdl%daddr, bounds_lat_,size(bounds_lat_,1),size(bounds_lat_,2)) + ENDIF + + IF (PRESENT(bounds_lon_)) THEN + CALL cxios_get_domaingroup_bounds_lon(domaingroup_hdl%daddr, bounds_lon_,size(bounds_lon_,1),size(bounds_lon_,2)) + ENDIF + + IF (PRESENT(data_dim_)) THEN + CALL cxios_get_domaingroup_data_dim(domaingroup_hdl%daddr, data_dim_) + ENDIF + + IF (PRESENT(data_i_index_)) THEN + CALL cxios_get_domaingroup_data_i_index(domaingroup_hdl%daddr, data_i_index_,size(data_i_index_,1)) + ENDIF + + IF (PRESENT(data_ibegin_)) THEN + CALL cxios_get_domaingroup_data_ibegin(domaingroup_hdl%daddr, data_ibegin_) + ENDIF + + IF (PRESENT(data_j_index_)) THEN + CALL cxios_get_domaingroup_data_j_index(domaingroup_hdl%daddr, data_j_index_,size(data_j_index_,1)) + ENDIF + + IF (PRESENT(data_jbegin_)) THEN + CALL cxios_get_domaingroup_data_jbegin(domaingroup_hdl%daddr, data_jbegin_) + ENDIF + + IF (PRESENT(data_n_index_)) THEN + CALL cxios_get_domaingroup_data_n_index(domaingroup_hdl%daddr, data_n_index_) + ENDIF + + IF (PRESENT(data_ni_)) THEN + CALL cxios_get_domaingroup_data_ni(domaingroup_hdl%daddr, data_ni_) + ENDIF + + IF (PRESENT(data_nj_)) THEN + CALL cxios_get_domaingroup_data_nj(domaingroup_hdl%daddr, data_nj_) + ENDIF + + IF (PRESENT(domain_group_ref_)) THEN + CALL cxios_get_domaingroup_domain_group_ref(domaingroup_hdl%daddr, domain_group_ref_, len(domain_group_ref_)) + ENDIF + + IF (PRESENT(group_ref_)) THEN + CALL cxios_get_domaingroup_group_ref(domaingroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(i_index_)) THEN + CALL cxios_get_domaingroup_i_index(domaingroup_hdl%daddr, i_index_,size(i_index_,1),size(i_index_,2)) + ENDIF + + IF (PRESENT(ibegin_)) THEN + CALL cxios_get_domaingroup_ibegin(domaingroup_hdl%daddr, ibegin_) + ENDIF + + IF (PRESENT(iend_)) THEN + CALL cxios_get_domaingroup_iend(domaingroup_hdl%daddr, iend_) + ENDIF + + IF (PRESENT(j_index_)) THEN + CALL cxios_get_domaingroup_j_index(domaingroup_hdl%daddr, j_index_,size(j_index_,1),size(j_index_,2)) + ENDIF + + IF (PRESENT(jbegin_)) THEN + CALL cxios_get_domaingroup_jbegin(domaingroup_hdl%daddr, jbegin_) + ENDIF + + IF (PRESENT(jend_)) THEN + CALL cxios_get_domaingroup_jend(domaingroup_hdl%daddr, jend_) + ENDIF + + IF (PRESENT(latvalue_)) THEN + CALL cxios_get_domaingroup_latvalue(domaingroup_hdl%daddr, latvalue_,size(latvalue_,1)) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_get_domaingroup_long_name(domaingroup_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(lonvalue_)) THEN + CALL cxios_get_domaingroup_lonvalue(domaingroup_hdl%daddr, lonvalue_,size(lonvalue_,1)) + ENDIF + + IF (PRESENT(mask_)) THEN + ALLOCATE(mask__tmp(size(mask_,1),size(mask_,2))) + CALL cxios_get_domaingroup_mask(domaingroup_hdl%daddr, mask__tmp,size(mask_,1),size(mask_,2)) + mask_=mask__tmp + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_domaingroup_name(domaingroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(ni_)) THEN + CALL cxios_get_domaingroup_ni(domaingroup_hdl%daddr, ni_) + ENDIF + + IF (PRESENT(ni_glo_)) THEN + CALL cxios_get_domaingroup_ni_glo(domaingroup_hdl%daddr, ni_glo_) + ENDIF + + IF (PRESENT(nj_)) THEN + CALL cxios_get_domaingroup_nj(domaingroup_hdl%daddr, nj_) + ENDIF + + IF (PRESENT(nj_glo_)) THEN + CALL cxios_get_domaingroup_nj_glo(domaingroup_hdl%daddr, nj_glo_) + ENDIF + + IF (PRESENT(nvertex_)) THEN + CALL cxios_get_domaingroup_nvertex(domaingroup_hdl%daddr, nvertex_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_get_domaingroup_standard_name(domaingroup_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_get_domaingroup_type(domaingroup_hdl%daddr, type_, len(type_)) + ENDIF + + IF (PRESENT(zoom_ibegin_)) THEN + CALL cxios_get_domaingroup_zoom_ibegin(domaingroup_hdl%daddr, zoom_ibegin_) + ENDIF + + IF (PRESENT(zoom_ibegin_loc_)) THEN + CALL cxios_get_domaingroup_zoom_ibegin_loc(domaingroup_hdl%daddr, zoom_ibegin_loc_) + ENDIF + + IF (PRESENT(zoom_jbegin_)) THEN + CALL cxios_get_domaingroup_zoom_jbegin(domaingroup_hdl%daddr, zoom_jbegin_) + ENDIF + + IF (PRESENT(zoom_jbegin_loc_)) THEN + CALL cxios_get_domaingroup_zoom_jbegin_loc(domaingroup_hdl%daddr, zoom_jbegin_loc_) + ENDIF + + IF (PRESENT(zoom_ni_)) THEN + CALL cxios_get_domaingroup_zoom_ni(domaingroup_hdl%daddr, zoom_ni_) + ENDIF + + IF (PRESENT(zoom_ni_loc_)) THEN + CALL cxios_get_domaingroup_zoom_ni_loc(domaingroup_hdl%daddr, zoom_ni_loc_) + ENDIF + + IF (PRESENT(zoom_nj_)) THEN + CALL cxios_get_domaingroup_zoom_nj(domaingroup_hdl%daddr, zoom_nj_) + ENDIF + + IF (PRESENT(zoom_nj_loc_)) THEN + CALL cxios_get_domaingroup_zoom_nj_loc(domaingroup_hdl%daddr, zoom_nj_loc_) + ENDIF + + + + END SUBROUTINE xios(get_domaingroup_attr_hdl_) + + SUBROUTINE xios(is_defined_domaingroup_attr) & + ( domaingroup_id, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) :: domaingroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::domaingroup_id + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lat + LOGICAL(KIND=C_BOOL) :: bounds_lat_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lon + LOGICAL(KIND=C_BOOL) :: bounds_lon_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_dim + LOGICAL(KIND=C_BOOL) :: data_dim_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_i_index + LOGICAL(KIND=C_BOOL) :: data_i_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ibegin + LOGICAL(KIND=C_BOOL) :: data_ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_j_index + LOGICAL(KIND=C_BOOL) :: data_j_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_jbegin + LOGICAL(KIND=C_BOOL) :: data_jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_n_index + LOGICAL(KIND=C_BOOL) :: data_n_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ni + LOGICAL(KIND=C_BOOL) :: data_ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_nj + LOGICAL(KIND=C_BOOL) :: data_nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_group_ref + LOGICAL(KIND=C_BOOL) :: domain_group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: i_index + LOGICAL(KIND=C_BOOL) :: i_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ibegin + LOGICAL(KIND=C_BOOL) :: ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: iend + LOGICAL(KIND=C_BOOL) :: iend_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: j_index + LOGICAL(KIND=C_BOOL) :: j_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jbegin + LOGICAL(KIND=C_BOOL) :: jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jend + LOGICAL(KIND=C_BOOL) :: jend_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: latvalue + LOGICAL(KIND=C_BOOL) :: latvalue_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: lonvalue + LOGICAL(KIND=C_BOOL) :: lonvalue_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask + LOGICAL(KIND=C_BOOL) :: mask_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni + LOGICAL(KIND=C_BOOL) :: ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni_glo + LOGICAL(KIND=C_BOOL) :: ni_glo_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj + LOGICAL(KIND=C_BOOL) :: nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj_glo + LOGICAL(KIND=C_BOOL) :: nj_glo_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nvertex + LOGICAL(KIND=C_BOOL) :: nvertex_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni + LOGICAL(KIND=C_BOOL) :: zoom_ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni_loc + LOGICAL(KIND=C_BOOL) :: zoom_ni_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj + LOGICAL(KIND=C_BOOL) :: zoom_nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj_loc + LOGICAL(KIND=C_BOOL) :: zoom_nj_loc_tmp + + CALL xios(get_domaingroup_handle)(domaingroup_id,domaingroup_hdl) + CALL xios(is_defined_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + END SUBROUTINE xios(is_defined_domaingroup_attr) + + SUBROUTINE xios(is_defined_domaingroup_attr_hdl) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) , INTENT(IN) :: domaingroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lat + LOGICAL(KIND=C_BOOL) :: bounds_lat_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lon + LOGICAL(KIND=C_BOOL) :: bounds_lon_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_dim + LOGICAL(KIND=C_BOOL) :: data_dim_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_i_index + LOGICAL(KIND=C_BOOL) :: data_i_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ibegin + LOGICAL(KIND=C_BOOL) :: data_ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_j_index + LOGICAL(KIND=C_BOOL) :: data_j_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_jbegin + LOGICAL(KIND=C_BOOL) :: data_jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_n_index + LOGICAL(KIND=C_BOOL) :: data_n_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ni + LOGICAL(KIND=C_BOOL) :: data_ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_nj + LOGICAL(KIND=C_BOOL) :: data_nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_group_ref + LOGICAL(KIND=C_BOOL) :: domain_group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: i_index + LOGICAL(KIND=C_BOOL) :: i_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ibegin + LOGICAL(KIND=C_BOOL) :: ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: iend + LOGICAL(KIND=C_BOOL) :: iend_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: j_index + LOGICAL(KIND=C_BOOL) :: j_index_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jbegin + LOGICAL(KIND=C_BOOL) :: jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jend + LOGICAL(KIND=C_BOOL) :: jend_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: latvalue + LOGICAL(KIND=C_BOOL) :: latvalue_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: lonvalue + LOGICAL(KIND=C_BOOL) :: lonvalue_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask + LOGICAL(KIND=C_BOOL) :: mask_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni + LOGICAL(KIND=C_BOOL) :: ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni_glo + LOGICAL(KIND=C_BOOL) :: ni_glo_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj + LOGICAL(KIND=C_BOOL) :: nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj_glo + LOGICAL(KIND=C_BOOL) :: nj_glo_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nvertex + LOGICAL(KIND=C_BOOL) :: nvertex_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni + LOGICAL(KIND=C_BOOL) :: zoom_ni_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni_loc + LOGICAL(KIND=C_BOOL) :: zoom_ni_loc_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj + LOGICAL(KIND=C_BOOL) :: zoom_nj_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj_loc + LOGICAL(KIND=C_BOOL) :: zoom_nj_loc_tmp + + CALL xios(is_defined_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat, bounds_lon, data_dim, data_i_index, data_ibegin, data_j_index & + , data_jbegin, data_n_index, data_ni, data_nj, domain_group_ref, group_ref, i_index, ibegin & + , iend, j_index, jbegin, jend, latvalue, long_name, lonvalue, mask, name, ni, ni_glo, nj, nj_glo & + , nvertex, standard_name, type, zoom_ibegin, zoom_ibegin_loc, zoom_jbegin, zoom_jbegin_loc, zoom_ni & + , zoom_ni_loc, zoom_nj, zoom_nj_loc ) + + END SUBROUTINE xios(is_defined_domaingroup_attr_hdl) + + SUBROUTINE xios(is_defined_domaingroup_attr_hdl_) & + ( domaingroup_hdl, bounds_lat_, bounds_lon_, data_dim_, data_i_index_, data_ibegin_, data_j_index_ & + , data_jbegin_, data_n_index_, data_ni_, data_nj_, domain_group_ref_, group_ref_, i_index_, ibegin_ & + , iend_, j_index_, jbegin_, jend_, latvalue_, long_name_, lonvalue_, mask_, name_, ni_, ni_glo_ & + , nj_, nj_glo_, nvertex_, standard_name_, type_, zoom_ibegin_, zoom_ibegin_loc_, zoom_jbegin_ & + , zoom_jbegin_loc_, zoom_ni_, zoom_ni_loc_, zoom_nj_, zoom_nj_loc_ ) + + IMPLICIT NONE + TYPE(txios(domaingroup)) , INTENT(IN) :: domaingroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lat_ + LOGICAL(KIND=C_BOOL) :: bounds_lat__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: bounds_lon_ + LOGICAL(KIND=C_BOOL) :: bounds_lon__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_dim_ + LOGICAL(KIND=C_BOOL) :: data_dim__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_i_index_ + LOGICAL(KIND=C_BOOL) :: data_i_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ibegin_ + LOGICAL(KIND=C_BOOL) :: data_ibegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_j_index_ + LOGICAL(KIND=C_BOOL) :: data_j_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_jbegin_ + LOGICAL(KIND=C_BOOL) :: data_jbegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_n_index_ + LOGICAL(KIND=C_BOOL) :: data_n_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_ni_ + LOGICAL(KIND=C_BOOL) :: data_ni__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: data_nj_ + LOGICAL(KIND=C_BOOL) :: data_nj__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_group_ref_ + LOGICAL(KIND=C_BOOL) :: domain_group_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref_ + LOGICAL(KIND=C_BOOL) :: group_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: i_index_ + LOGICAL(KIND=C_BOOL) :: i_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ibegin_ + LOGICAL(KIND=C_BOOL) :: ibegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: iend_ + LOGICAL(KIND=C_BOOL) :: iend__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: j_index_ + LOGICAL(KIND=C_BOOL) :: j_index__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jbegin_ + LOGICAL(KIND=C_BOOL) :: jbegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: jend_ + LOGICAL(KIND=C_BOOL) :: jend__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: latvalue_ + LOGICAL(KIND=C_BOOL) :: latvalue__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name_ + LOGICAL(KIND=C_BOOL) :: long_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: lonvalue_ + LOGICAL(KIND=C_BOOL) :: lonvalue__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask_ + LOGICAL(KIND=C_BOOL) :: mask__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni_ + LOGICAL(KIND=C_BOOL) :: ni__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: ni_glo_ + LOGICAL(KIND=C_BOOL) :: ni_glo__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj_ + LOGICAL(KIND=C_BOOL) :: nj__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nj_glo_ + LOGICAL(KIND=C_BOOL) :: nj_glo__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: nvertex_ + LOGICAL(KIND=C_BOOL) :: nvertex__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name_ + LOGICAL(KIND=C_BOOL) :: standard_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type_ + LOGICAL(KIND=C_BOOL) :: type__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin_ + LOGICAL(KIND=C_BOOL) :: zoom_ibegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ibegin_loc_ + LOGICAL(KIND=C_BOOL) :: zoom_ibegin_loc__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin_ + LOGICAL(KIND=C_BOOL) :: zoom_jbegin__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_jbegin_loc_ + LOGICAL(KIND=C_BOOL) :: zoom_jbegin_loc__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni_ + LOGICAL(KIND=C_BOOL) :: zoom_ni__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_ni_loc_ + LOGICAL(KIND=C_BOOL) :: zoom_ni_loc__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj_ + LOGICAL(KIND=C_BOOL) :: zoom_nj__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: zoom_nj_loc_ + LOGICAL(KIND=C_BOOL) :: zoom_nj_loc__tmp + + IF (PRESENT(bounds_lat_)) THEN + bounds_lat__tmp=cxios_is_defined_domaingroup_bounds_lat(domaingroup_hdl%daddr) + bounds_lat_=bounds_lat__tmp + ENDIF + + IF (PRESENT(bounds_lon_)) THEN + bounds_lon__tmp=cxios_is_defined_domaingroup_bounds_lon(domaingroup_hdl%daddr) + bounds_lon_=bounds_lon__tmp + ENDIF + + IF (PRESENT(data_dim_)) THEN + data_dim__tmp=cxios_is_defined_domaingroup_data_dim(domaingroup_hdl%daddr) + data_dim_=data_dim__tmp + ENDIF + + IF (PRESENT(data_i_index_)) THEN + data_i_index__tmp=cxios_is_defined_domaingroup_data_i_index(domaingroup_hdl%daddr) + data_i_index_=data_i_index__tmp + ENDIF + + IF (PRESENT(data_ibegin_)) THEN + data_ibegin__tmp=cxios_is_defined_domaingroup_data_ibegin(domaingroup_hdl%daddr) + data_ibegin_=data_ibegin__tmp + ENDIF + + IF (PRESENT(data_j_index_)) THEN + data_j_index__tmp=cxios_is_defined_domaingroup_data_j_index(domaingroup_hdl%daddr) + data_j_index_=data_j_index__tmp + ENDIF + + IF (PRESENT(data_jbegin_)) THEN + data_jbegin__tmp=cxios_is_defined_domaingroup_data_jbegin(domaingroup_hdl%daddr) + data_jbegin_=data_jbegin__tmp + ENDIF + + IF (PRESENT(data_n_index_)) THEN + data_n_index__tmp=cxios_is_defined_domaingroup_data_n_index(domaingroup_hdl%daddr) + data_n_index_=data_n_index__tmp + ENDIF + + IF (PRESENT(data_ni_)) THEN + data_ni__tmp=cxios_is_defined_domaingroup_data_ni(domaingroup_hdl%daddr) + data_ni_=data_ni__tmp + ENDIF + + IF (PRESENT(data_nj_)) THEN + data_nj__tmp=cxios_is_defined_domaingroup_data_nj(domaingroup_hdl%daddr) + data_nj_=data_nj__tmp + ENDIF + + IF (PRESENT(domain_group_ref_)) THEN + domain_group_ref__tmp=cxios_is_defined_domaingroup_domain_group_ref(domaingroup_hdl%daddr) + domain_group_ref_=domain_group_ref__tmp + ENDIF + + IF (PRESENT(group_ref_)) THEN + group_ref__tmp=cxios_is_defined_domaingroup_group_ref(domaingroup_hdl%daddr) + group_ref_=group_ref__tmp + ENDIF + + IF (PRESENT(i_index_)) THEN + i_index__tmp=cxios_is_defined_domaingroup_i_index(domaingroup_hdl%daddr) + i_index_=i_index__tmp + ENDIF + + IF (PRESENT(ibegin_)) THEN + ibegin__tmp=cxios_is_defined_domaingroup_ibegin(domaingroup_hdl%daddr) + ibegin_=ibegin__tmp + ENDIF + + IF (PRESENT(iend_)) THEN + iend__tmp=cxios_is_defined_domaingroup_iend(domaingroup_hdl%daddr) + iend_=iend__tmp + ENDIF + + IF (PRESENT(j_index_)) THEN + j_index__tmp=cxios_is_defined_domaingroup_j_index(domaingroup_hdl%daddr) + j_index_=j_index__tmp + ENDIF + + IF (PRESENT(jbegin_)) THEN + jbegin__tmp=cxios_is_defined_domaingroup_jbegin(domaingroup_hdl%daddr) + jbegin_=jbegin__tmp + ENDIF + + IF (PRESENT(jend_)) THEN + jend__tmp=cxios_is_defined_domaingroup_jend(domaingroup_hdl%daddr) + jend_=jend__tmp + ENDIF + + IF (PRESENT(latvalue_)) THEN + latvalue__tmp=cxios_is_defined_domaingroup_latvalue(domaingroup_hdl%daddr) + latvalue_=latvalue__tmp + ENDIF + + IF (PRESENT(long_name_)) THEN + long_name__tmp=cxios_is_defined_domaingroup_long_name(domaingroup_hdl%daddr) + long_name_=long_name__tmp + ENDIF + + IF (PRESENT(lonvalue_)) THEN + lonvalue__tmp=cxios_is_defined_domaingroup_lonvalue(domaingroup_hdl%daddr) + lonvalue_=lonvalue__tmp + ENDIF + + IF (PRESENT(mask_)) THEN + mask__tmp=cxios_is_defined_domaingroup_mask(domaingroup_hdl%daddr) + mask_=mask__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_domaingroup_name(domaingroup_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(ni_)) THEN + ni__tmp=cxios_is_defined_domaingroup_ni(domaingroup_hdl%daddr) + ni_=ni__tmp + ENDIF + + IF (PRESENT(ni_glo_)) THEN + ni_glo__tmp=cxios_is_defined_domaingroup_ni_glo(domaingroup_hdl%daddr) + ni_glo_=ni_glo__tmp + ENDIF + + IF (PRESENT(nj_)) THEN + nj__tmp=cxios_is_defined_domaingroup_nj(domaingroup_hdl%daddr) + nj_=nj__tmp + ENDIF + + IF (PRESENT(nj_glo_)) THEN + nj_glo__tmp=cxios_is_defined_domaingroup_nj_glo(domaingroup_hdl%daddr) + nj_glo_=nj_glo__tmp + ENDIF + + IF (PRESENT(nvertex_)) THEN + nvertex__tmp=cxios_is_defined_domaingroup_nvertex(domaingroup_hdl%daddr) + nvertex_=nvertex__tmp + ENDIF + + IF (PRESENT(standard_name_)) THEN + standard_name__tmp=cxios_is_defined_domaingroup_standard_name(domaingroup_hdl%daddr) + standard_name_=standard_name__tmp + ENDIF + + IF (PRESENT(type_)) THEN + type__tmp=cxios_is_defined_domaingroup_type(domaingroup_hdl%daddr) + type_=type__tmp + ENDIF + + IF (PRESENT(zoom_ibegin_)) THEN + zoom_ibegin__tmp=cxios_is_defined_domaingroup_zoom_ibegin(domaingroup_hdl%daddr) + zoom_ibegin_=zoom_ibegin__tmp + ENDIF + + IF (PRESENT(zoom_ibegin_loc_)) THEN + zoom_ibegin_loc__tmp=cxios_is_defined_domaingroup_zoom_ibegin_loc(domaingroup_hdl%daddr) + zoom_ibegin_loc_=zoom_ibegin_loc__tmp + ENDIF + + IF (PRESENT(zoom_jbegin_)) THEN + zoom_jbegin__tmp=cxios_is_defined_domaingroup_zoom_jbegin(domaingroup_hdl%daddr) + zoom_jbegin_=zoom_jbegin__tmp + ENDIF + + IF (PRESENT(zoom_jbegin_loc_)) THEN + zoom_jbegin_loc__tmp=cxios_is_defined_domaingroup_zoom_jbegin_loc(domaingroup_hdl%daddr) + zoom_jbegin_loc_=zoom_jbegin_loc__tmp + ENDIF + + IF (PRESENT(zoom_ni_)) THEN + zoom_ni__tmp=cxios_is_defined_domaingroup_zoom_ni(domaingroup_hdl%daddr) + zoom_ni_=zoom_ni__tmp + ENDIF + + IF (PRESENT(zoom_ni_loc_)) THEN + zoom_ni_loc__tmp=cxios_is_defined_domaingroup_zoom_ni_loc(domaingroup_hdl%daddr) + zoom_ni_loc_=zoom_ni_loc__tmp + ENDIF + + IF (PRESENT(zoom_nj_)) THEN + zoom_nj__tmp=cxios_is_defined_domaingroup_zoom_nj(domaingroup_hdl%daddr) + zoom_nj_=zoom_nj__tmp + ENDIF + + IF (PRESENT(zoom_nj_loc_)) THEN + zoom_nj_loc__tmp=cxios_is_defined_domaingroup_zoom_nj_loc(domaingroup_hdl%daddr) + zoom_nj_loc_=zoom_nj_loc__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_domaingroup_attr_hdl_) + +END MODULE idomaingroup_attr diff --git a/src/interface/fortran_attr/ifield_attr.F90 b/src/interface/fortran_attr/ifield_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..c6d61d5600ed1a9e9216d32cb939d0f285426b46 --- /dev/null +++ b/src/interface/fortran_attr/ifield_attr.F90 @@ -0,0 +1,661 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE ifield_attr + USE, INTRINSIC :: ISO_C_BINDING + USE ifield + USE field_interface_attr + +CONTAINS + + SUBROUTINE xios(set_field_attr) & + ( field_id, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled, field_ref & + , freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor, standard_name & + , unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(field)) :: field_hdl + CHARACTER(LEN=*), INTENT(IN) ::field_id + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: add_offset + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: default_value + LOGICAL , OPTIONAL, INTENT(IN) :: detect_missing_value + LOGICAL (KIND=C_BOOL) :: detect_missing_value_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref + LOGICAL , OPTIONAL, INTENT(IN) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: field_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_offset + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_op + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: grid_ref + INTEGER , OPTIONAL, INTENT(IN) :: level + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: operation + INTEGER , OPTIONAL, INTENT(IN) :: prec + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: scale_factor + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_max + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_min + + CALL xios(get_field_handle)(field_id,field_hdl) + CALL xios(set_field_attr_hdl_) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(set_field_attr) + + SUBROUTINE xios(set_field_attr_hdl) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(field)) , INTENT(IN) :: field_hdl + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: add_offset + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: default_value + LOGICAL , OPTIONAL, INTENT(IN) :: detect_missing_value + LOGICAL (KIND=C_BOOL) :: detect_missing_value_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref + LOGICAL , OPTIONAL, INTENT(IN) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: field_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_offset + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_op + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: grid_ref + INTEGER , OPTIONAL, INTENT(IN) :: level + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: operation + INTEGER , OPTIONAL, INTENT(IN) :: prec + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: scale_factor + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_max + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_min + + CALL xios(set_field_attr_hdl_) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(set_field_attr_hdl) + + SUBROUTINE xios(set_field_attr_hdl_) & + ( field_hdl, add_offset_, axis_ref_, default_value_, detect_missing_value_, domain_ref_, enabled_ & + , field_ref_, freq_offset_, freq_op_, grid_ref_, level_, long_name_, name_, operation_, prec_ & + , scale_factor_, standard_name_, unit_, valid_max_, valid_min_ ) + + IMPLICIT NONE + TYPE(txios(field)) , INTENT(IN) :: field_hdl + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: add_offset_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: default_value_ + LOGICAL , OPTIONAL, INTENT(IN) :: detect_missing_value_ + LOGICAL (KIND=C_BOOL) :: detect_missing_value__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref_ + LOGICAL , OPTIONAL, INTENT(IN) :: enabled_ + LOGICAL (KIND=C_BOOL) :: enabled__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: field_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_offset_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_op_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: grid_ref_ + INTEGER , OPTIONAL, INTENT(IN) :: level_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: operation_ + INTEGER , OPTIONAL, INTENT(IN) :: prec_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: scale_factor_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_max_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_min_ + + IF (PRESENT(add_offset_)) THEN + CALL cxios_set_field_add_offset(field_hdl%daddr, add_offset_) + ENDIF + + IF (PRESENT(axis_ref_)) THEN + CALL cxios_set_field_axis_ref(field_hdl%daddr, axis_ref_, len(axis_ref_)) + ENDIF + + IF (PRESENT(default_value_)) THEN + CALL cxios_set_field_default_value(field_hdl%daddr, default_value_) + ENDIF + + IF (PRESENT(detect_missing_value_)) THEN + detect_missing_value__tmp=detect_missing_value_ + CALL cxios_set_field_detect_missing_value(field_hdl%daddr, detect_missing_value__tmp) + ENDIF + + IF (PRESENT(domain_ref_)) THEN + CALL cxios_set_field_domain_ref(field_hdl%daddr, domain_ref_, len(domain_ref_)) + ENDIF + + IF (PRESENT(enabled_)) THEN + enabled__tmp=enabled_ + CALL cxios_set_field_enabled(field_hdl%daddr, enabled__tmp) + ENDIF + + IF (PRESENT(field_ref_)) THEN + CALL cxios_set_field_field_ref(field_hdl%daddr, field_ref_, len(field_ref_)) + ENDIF + + IF (PRESENT(freq_offset_)) THEN + CALL cxios_set_field_freq_offset(field_hdl%daddr, freq_offset_, len(freq_offset_)) + ENDIF + + IF (PRESENT(freq_op_)) THEN + CALL cxios_set_field_freq_op(field_hdl%daddr, freq_op_, len(freq_op_)) + ENDIF + + IF (PRESENT(grid_ref_)) THEN + CALL cxios_set_field_grid_ref(field_hdl%daddr, grid_ref_, len(grid_ref_)) + ENDIF + + IF (PRESENT(level_)) THEN + CALL cxios_set_field_level(field_hdl%daddr, level_) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_set_field_long_name(field_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_field_name(field_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(operation_)) THEN + CALL cxios_set_field_operation(field_hdl%daddr, operation_, len(operation_)) + ENDIF + + IF (PRESENT(prec_)) THEN + CALL cxios_set_field_prec(field_hdl%daddr, prec_) + ENDIF + + IF (PRESENT(scale_factor_)) THEN + CALL cxios_set_field_scale_factor(field_hdl%daddr, scale_factor_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_set_field_standard_name(field_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(unit_)) THEN + CALL cxios_set_field_unit(field_hdl%daddr, unit_, len(unit_)) + ENDIF + + IF (PRESENT(valid_max_)) THEN + CALL cxios_set_field_valid_max(field_hdl%daddr, valid_max_) + ENDIF + + IF (PRESENT(valid_min_)) THEN + CALL cxios_set_field_valid_min(field_hdl%daddr, valid_min_) + ENDIF + + + + END SUBROUTINE xios(set_field_attr_hdl_) + + SUBROUTINE xios(get_field_attr) & + ( field_id, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled, field_ref & + , freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor, standard_name & + , unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(field)) :: field_hdl + CHARACTER(LEN=*), INTENT(IN) ::field_id + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: add_offset + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: default_value + LOGICAL , OPTIONAL, INTENT(OUT) :: detect_missing_value + LOGICAL (KIND=C_BOOL) :: detect_missing_value_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: field_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_offset + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_op + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: grid_ref + INTEGER , OPTIONAL, INTENT(OUT) :: level + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: operation + INTEGER , OPTIONAL, INTENT(OUT) :: prec + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: scale_factor + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_max + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_min + + CALL xios(get_field_handle)(field_id,field_hdl) + CALL xios(get_field_attr_hdl_) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(get_field_attr) + + SUBROUTINE xios(get_field_attr_hdl) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(field)) , INTENT(IN) :: field_hdl + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: add_offset + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: default_value + LOGICAL , OPTIONAL, INTENT(OUT) :: detect_missing_value + LOGICAL (KIND=C_BOOL) :: detect_missing_value_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: field_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_offset + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_op + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: grid_ref + INTEGER , OPTIONAL, INTENT(OUT) :: level + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: operation + INTEGER , OPTIONAL, INTENT(OUT) :: prec + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: scale_factor + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_max + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_min + + CALL xios(get_field_attr_hdl_) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(get_field_attr_hdl) + + SUBROUTINE xios(get_field_attr_hdl_) & + ( field_hdl, add_offset_, axis_ref_, default_value_, detect_missing_value_, domain_ref_, enabled_ & + , field_ref_, freq_offset_, freq_op_, grid_ref_, level_, long_name_, name_, operation_, prec_ & + , scale_factor_, standard_name_, unit_, valid_max_, valid_min_ ) + + IMPLICIT NONE + TYPE(txios(field)) , INTENT(IN) :: field_hdl + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: add_offset_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: default_value_ + LOGICAL , OPTIONAL, INTENT(OUT) :: detect_missing_value_ + LOGICAL (KIND=C_BOOL) :: detect_missing_value__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref_ + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled_ + LOGICAL (KIND=C_BOOL) :: enabled__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: field_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_offset_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_op_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: grid_ref_ + INTEGER , OPTIONAL, INTENT(OUT) :: level_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: operation_ + INTEGER , OPTIONAL, INTENT(OUT) :: prec_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: scale_factor_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_max_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_min_ + + IF (PRESENT(add_offset_)) THEN + CALL cxios_get_field_add_offset(field_hdl%daddr, add_offset_) + ENDIF + + IF (PRESENT(axis_ref_)) THEN + CALL cxios_get_field_axis_ref(field_hdl%daddr, axis_ref_, len(axis_ref_)) + ENDIF + + IF (PRESENT(default_value_)) THEN + CALL cxios_get_field_default_value(field_hdl%daddr, default_value_) + ENDIF + + IF (PRESENT(detect_missing_value_)) THEN + CALL cxios_get_field_detect_missing_value(field_hdl%daddr, detect_missing_value__tmp) + detect_missing_value_=detect_missing_value__tmp + ENDIF + + IF (PRESENT(domain_ref_)) THEN + CALL cxios_get_field_domain_ref(field_hdl%daddr, domain_ref_, len(domain_ref_)) + ENDIF + + IF (PRESENT(enabled_)) THEN + CALL cxios_get_field_enabled(field_hdl%daddr, enabled__tmp) + enabled_=enabled__tmp + ENDIF + + IF (PRESENT(field_ref_)) THEN + CALL cxios_get_field_field_ref(field_hdl%daddr, field_ref_, len(field_ref_)) + ENDIF + + IF (PRESENT(freq_offset_)) THEN + CALL cxios_get_field_freq_offset(field_hdl%daddr, freq_offset_, len(freq_offset_)) + ENDIF + + IF (PRESENT(freq_op_)) THEN + CALL cxios_get_field_freq_op(field_hdl%daddr, freq_op_, len(freq_op_)) + ENDIF + + IF (PRESENT(grid_ref_)) THEN + CALL cxios_get_field_grid_ref(field_hdl%daddr, grid_ref_, len(grid_ref_)) + ENDIF + + IF (PRESENT(level_)) THEN + CALL cxios_get_field_level(field_hdl%daddr, level_) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_get_field_long_name(field_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_field_name(field_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(operation_)) THEN + CALL cxios_get_field_operation(field_hdl%daddr, operation_, len(operation_)) + ENDIF + + IF (PRESENT(prec_)) THEN + CALL cxios_get_field_prec(field_hdl%daddr, prec_) + ENDIF + + IF (PRESENT(scale_factor_)) THEN + CALL cxios_get_field_scale_factor(field_hdl%daddr, scale_factor_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_get_field_standard_name(field_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(unit_)) THEN + CALL cxios_get_field_unit(field_hdl%daddr, unit_, len(unit_)) + ENDIF + + IF (PRESENT(valid_max_)) THEN + CALL cxios_get_field_valid_max(field_hdl%daddr, valid_max_) + ENDIF + + IF (PRESENT(valid_min_)) THEN + CALL cxios_get_field_valid_min(field_hdl%daddr, valid_min_) + ENDIF + + + + END SUBROUTINE xios(get_field_attr_hdl_) + + SUBROUTINE xios(is_defined_field_attr) & + ( field_id, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled, field_ref & + , freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor, standard_name & + , unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(field)) :: field_hdl + CHARACTER(LEN=*), INTENT(IN) ::field_id + LOGICAL, OPTIONAL, INTENT(OUT) :: add_offset + LOGICAL(KIND=C_BOOL) :: add_offset_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref + LOGICAL(KIND=C_BOOL) :: axis_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: default_value + LOGICAL(KIND=C_BOOL) :: default_value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: detect_missing_value + LOGICAL(KIND=C_BOOL) :: detect_missing_value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL(KIND=C_BOOL) :: domain_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled + LOGICAL(KIND=C_BOOL) :: enabled_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: field_ref + LOGICAL(KIND=C_BOOL) :: field_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_offset + LOGICAL(KIND=C_BOOL) :: freq_offset_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_op + LOGICAL(KIND=C_BOOL) :: freq_op_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: grid_ref + LOGICAL(KIND=C_BOOL) :: grid_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: level + LOGICAL(KIND=C_BOOL) :: level_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: operation + LOGICAL(KIND=C_BOOL) :: operation_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: prec + LOGICAL(KIND=C_BOOL) :: prec_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: scale_factor + LOGICAL(KIND=C_BOOL) :: scale_factor_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit + LOGICAL(KIND=C_BOOL) :: unit_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_max + LOGICAL(KIND=C_BOOL) :: valid_max_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_min + LOGICAL(KIND=C_BOOL) :: valid_min_tmp + + CALL xios(get_field_handle)(field_id,field_hdl) + CALL xios(is_defined_field_attr_hdl_) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(is_defined_field_attr) + + SUBROUTINE xios(is_defined_field_attr_hdl) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(field)) , INTENT(IN) :: field_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: add_offset + LOGICAL(KIND=C_BOOL) :: add_offset_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref + LOGICAL(KIND=C_BOOL) :: axis_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: default_value + LOGICAL(KIND=C_BOOL) :: default_value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: detect_missing_value + LOGICAL(KIND=C_BOOL) :: detect_missing_value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL(KIND=C_BOOL) :: domain_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled + LOGICAL(KIND=C_BOOL) :: enabled_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: field_ref + LOGICAL(KIND=C_BOOL) :: field_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_offset + LOGICAL(KIND=C_BOOL) :: freq_offset_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_op + LOGICAL(KIND=C_BOOL) :: freq_op_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: grid_ref + LOGICAL(KIND=C_BOOL) :: grid_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: level + LOGICAL(KIND=C_BOOL) :: level_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: operation + LOGICAL(KIND=C_BOOL) :: operation_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: prec + LOGICAL(KIND=C_BOOL) :: prec_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: scale_factor + LOGICAL(KIND=C_BOOL) :: scale_factor_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit + LOGICAL(KIND=C_BOOL) :: unit_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_max + LOGICAL(KIND=C_BOOL) :: valid_max_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_min + LOGICAL(KIND=C_BOOL) :: valid_min_tmp + + CALL xios(is_defined_field_attr_hdl_) & + ( field_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, level, long_name, name, operation, prec, scale_factor & + , standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(is_defined_field_attr_hdl) + + SUBROUTINE xios(is_defined_field_attr_hdl_) & + ( field_hdl, add_offset_, axis_ref_, default_value_, detect_missing_value_, domain_ref_, enabled_ & + , field_ref_, freq_offset_, freq_op_, grid_ref_, level_, long_name_, name_, operation_, prec_ & + , scale_factor_, standard_name_, unit_, valid_max_, valid_min_ ) + + IMPLICIT NONE + TYPE(txios(field)) , INTENT(IN) :: field_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: add_offset_ + LOGICAL(KIND=C_BOOL) :: add_offset__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref_ + LOGICAL(KIND=C_BOOL) :: axis_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: default_value_ + LOGICAL(KIND=C_BOOL) :: default_value__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: detect_missing_value_ + LOGICAL(KIND=C_BOOL) :: detect_missing_value__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref_ + LOGICAL(KIND=C_BOOL) :: domain_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled_ + LOGICAL(KIND=C_BOOL) :: enabled__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: field_ref_ + LOGICAL(KIND=C_BOOL) :: field_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_offset_ + LOGICAL(KIND=C_BOOL) :: freq_offset__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_op_ + LOGICAL(KIND=C_BOOL) :: freq_op__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: grid_ref_ + LOGICAL(KIND=C_BOOL) :: grid_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: level_ + LOGICAL(KIND=C_BOOL) :: level__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name_ + LOGICAL(KIND=C_BOOL) :: long_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: operation_ + LOGICAL(KIND=C_BOOL) :: operation__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: prec_ + LOGICAL(KIND=C_BOOL) :: prec__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: scale_factor_ + LOGICAL(KIND=C_BOOL) :: scale_factor__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name_ + LOGICAL(KIND=C_BOOL) :: standard_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit_ + LOGICAL(KIND=C_BOOL) :: unit__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_max_ + LOGICAL(KIND=C_BOOL) :: valid_max__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_min_ + LOGICAL(KIND=C_BOOL) :: valid_min__tmp + + IF (PRESENT(add_offset_)) THEN + add_offset__tmp=cxios_is_defined_field_add_offset(field_hdl%daddr) + add_offset_=add_offset__tmp + ENDIF + + IF (PRESENT(axis_ref_)) THEN + axis_ref__tmp=cxios_is_defined_field_axis_ref(field_hdl%daddr) + axis_ref_=axis_ref__tmp + ENDIF + + IF (PRESENT(default_value_)) THEN + default_value__tmp=cxios_is_defined_field_default_value(field_hdl%daddr) + default_value_=default_value__tmp + ENDIF + + IF (PRESENT(detect_missing_value_)) THEN + detect_missing_value__tmp=cxios_is_defined_field_detect_missing_value(field_hdl%daddr) + detect_missing_value_=detect_missing_value__tmp + ENDIF + + IF (PRESENT(domain_ref_)) THEN + domain_ref__tmp=cxios_is_defined_field_domain_ref(field_hdl%daddr) + domain_ref_=domain_ref__tmp + ENDIF + + IF (PRESENT(enabled_)) THEN + enabled__tmp=cxios_is_defined_field_enabled(field_hdl%daddr) + enabled_=enabled__tmp + ENDIF + + IF (PRESENT(field_ref_)) THEN + field_ref__tmp=cxios_is_defined_field_field_ref(field_hdl%daddr) + field_ref_=field_ref__tmp + ENDIF + + IF (PRESENT(freq_offset_)) THEN + freq_offset__tmp=cxios_is_defined_field_freq_offset(field_hdl%daddr) + freq_offset_=freq_offset__tmp + ENDIF + + IF (PRESENT(freq_op_)) THEN + freq_op__tmp=cxios_is_defined_field_freq_op(field_hdl%daddr) + freq_op_=freq_op__tmp + ENDIF + + IF (PRESENT(grid_ref_)) THEN + grid_ref__tmp=cxios_is_defined_field_grid_ref(field_hdl%daddr) + grid_ref_=grid_ref__tmp + ENDIF + + IF (PRESENT(level_)) THEN + level__tmp=cxios_is_defined_field_level(field_hdl%daddr) + level_=level__tmp + ENDIF + + IF (PRESENT(long_name_)) THEN + long_name__tmp=cxios_is_defined_field_long_name(field_hdl%daddr) + long_name_=long_name__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_field_name(field_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(operation_)) THEN + operation__tmp=cxios_is_defined_field_operation(field_hdl%daddr) + operation_=operation__tmp + ENDIF + + IF (PRESENT(prec_)) THEN + prec__tmp=cxios_is_defined_field_prec(field_hdl%daddr) + prec_=prec__tmp + ENDIF + + IF (PRESENT(scale_factor_)) THEN + scale_factor__tmp=cxios_is_defined_field_scale_factor(field_hdl%daddr) + scale_factor_=scale_factor__tmp + ENDIF + + IF (PRESENT(standard_name_)) THEN + standard_name__tmp=cxios_is_defined_field_standard_name(field_hdl%daddr) + standard_name_=standard_name__tmp + ENDIF + + IF (PRESENT(unit_)) THEN + unit__tmp=cxios_is_defined_field_unit(field_hdl%daddr) + unit_=unit__tmp + ENDIF + + IF (PRESENT(valid_max_)) THEN + valid_max__tmp=cxios_is_defined_field_valid_max(field_hdl%daddr) + valid_max_=valid_max__tmp + ENDIF + + IF (PRESENT(valid_min_)) THEN + valid_min__tmp=cxios_is_defined_field_valid_min(field_hdl%daddr) + valid_min_=valid_min__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_field_attr_hdl_) + +END MODULE ifield_attr diff --git a/src/interface/fortran_attr/ifieldgroup_attr.F90 b/src/interface/fortran_attr/ifieldgroup_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..01e9fdab34b8d6dfda5aee0771470485a5341a64 --- /dev/null +++ b/src/interface/fortran_attr/ifieldgroup_attr.F90 @@ -0,0 +1,686 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE ifieldgroup_attr + USE, INTRINSIC :: ISO_C_BINDING + USE ifield + USE fieldgroup_interface_attr + +CONTAINS + + SUBROUTINE xios(set_fieldgroup_attr) & + ( fieldgroup_id, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) :: fieldgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::fieldgroup_id + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: add_offset + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: default_value + LOGICAL , OPTIONAL, INTENT(IN) :: detect_missing_value + LOGICAL (KIND=C_BOOL) :: detect_missing_value_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref + LOGICAL , OPTIONAL, INTENT(IN) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: field_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_offset + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_op + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: grid_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + INTEGER , OPTIONAL, INTENT(IN) :: level + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: operation + INTEGER , OPTIONAL, INTENT(IN) :: prec + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: scale_factor + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_max + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_min + + CALL xios(get_fieldgroup_handle)(fieldgroup_id,fieldgroup_hdl) + CALL xios(set_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(set_fieldgroup_attr) + + SUBROUTINE xios(set_fieldgroup_attr_hdl) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) , INTENT(IN) :: fieldgroup_hdl + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: add_offset + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: default_value + LOGICAL , OPTIONAL, INTENT(IN) :: detect_missing_value + LOGICAL (KIND=C_BOOL) :: detect_missing_value_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref + LOGICAL , OPTIONAL, INTENT(IN) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: field_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_offset + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_op + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: grid_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + INTEGER , OPTIONAL, INTENT(IN) :: level + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: operation + INTEGER , OPTIONAL, INTENT(IN) :: prec + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: scale_factor + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_max + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_min + + CALL xios(set_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(set_fieldgroup_attr_hdl) + + SUBROUTINE xios(set_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset_, axis_ref_, default_value_, detect_missing_value_, domain_ref_ & + , enabled_, field_ref_, freq_offset_, freq_op_, grid_ref_, group_ref_, level_, long_name_, name_ & + , operation_, prec_, scale_factor_, standard_name_, unit_, valid_max_, valid_min_ ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) , INTENT(IN) :: fieldgroup_hdl + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: add_offset_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: default_value_ + LOGICAL , OPTIONAL, INTENT(IN) :: detect_missing_value_ + LOGICAL (KIND=C_BOOL) :: detect_missing_value__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref_ + LOGICAL , OPTIONAL, INTENT(IN) :: enabled_ + LOGICAL (KIND=C_BOOL) :: enabled__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: field_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_offset_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: freq_op_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: grid_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref_ + INTEGER , OPTIONAL, INTENT(IN) :: level_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: long_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: operation_ + INTEGER , OPTIONAL, INTENT(IN) :: prec_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: scale_factor_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: unit_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_max_ + REAL (KIND=8) , OPTIONAL, INTENT(IN) :: valid_min_ + + IF (PRESENT(add_offset_)) THEN + CALL cxios_set_fieldgroup_add_offset(fieldgroup_hdl%daddr, add_offset_) + ENDIF + + IF (PRESENT(axis_ref_)) THEN + CALL cxios_set_fieldgroup_axis_ref(fieldgroup_hdl%daddr, axis_ref_, len(axis_ref_)) + ENDIF + + IF (PRESENT(default_value_)) THEN + CALL cxios_set_fieldgroup_default_value(fieldgroup_hdl%daddr, default_value_) + ENDIF + + IF (PRESENT(detect_missing_value_)) THEN + detect_missing_value__tmp=detect_missing_value_ + CALL cxios_set_fieldgroup_detect_missing_value(fieldgroup_hdl%daddr, detect_missing_value__tmp) + ENDIF + + IF (PRESENT(domain_ref_)) THEN + CALL cxios_set_fieldgroup_domain_ref(fieldgroup_hdl%daddr, domain_ref_, len(domain_ref_)) + ENDIF + + IF (PRESENT(enabled_)) THEN + enabled__tmp=enabled_ + CALL cxios_set_fieldgroup_enabled(fieldgroup_hdl%daddr, enabled__tmp) + ENDIF + + IF (PRESENT(field_ref_)) THEN + CALL cxios_set_fieldgroup_field_ref(fieldgroup_hdl%daddr, field_ref_, len(field_ref_)) + ENDIF + + IF (PRESENT(freq_offset_)) THEN + CALL cxios_set_fieldgroup_freq_offset(fieldgroup_hdl%daddr, freq_offset_, len(freq_offset_)) + ENDIF + + IF (PRESENT(freq_op_)) THEN + CALL cxios_set_fieldgroup_freq_op(fieldgroup_hdl%daddr, freq_op_, len(freq_op_)) + ENDIF + + IF (PRESENT(grid_ref_)) THEN + CALL cxios_set_fieldgroup_grid_ref(fieldgroup_hdl%daddr, grid_ref_, len(grid_ref_)) + ENDIF + + IF (PRESENT(group_ref_)) THEN + CALL cxios_set_fieldgroup_group_ref(fieldgroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(level_)) THEN + CALL cxios_set_fieldgroup_level(fieldgroup_hdl%daddr, level_) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_set_fieldgroup_long_name(fieldgroup_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_fieldgroup_name(fieldgroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(operation_)) THEN + CALL cxios_set_fieldgroup_operation(fieldgroup_hdl%daddr, operation_, len(operation_)) + ENDIF + + IF (PRESENT(prec_)) THEN + CALL cxios_set_fieldgroup_prec(fieldgroup_hdl%daddr, prec_) + ENDIF + + IF (PRESENT(scale_factor_)) THEN + CALL cxios_set_fieldgroup_scale_factor(fieldgroup_hdl%daddr, scale_factor_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_set_fieldgroup_standard_name(fieldgroup_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(unit_)) THEN + CALL cxios_set_fieldgroup_unit(fieldgroup_hdl%daddr, unit_, len(unit_)) + ENDIF + + IF (PRESENT(valid_max_)) THEN + CALL cxios_set_fieldgroup_valid_max(fieldgroup_hdl%daddr, valid_max_) + ENDIF + + IF (PRESENT(valid_min_)) THEN + CALL cxios_set_fieldgroup_valid_min(fieldgroup_hdl%daddr, valid_min_) + ENDIF + + + + END SUBROUTINE xios(set_fieldgroup_attr_hdl_) + + SUBROUTINE xios(get_fieldgroup_attr) & + ( fieldgroup_id, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) :: fieldgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::fieldgroup_id + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: add_offset + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: default_value + LOGICAL , OPTIONAL, INTENT(OUT) :: detect_missing_value + LOGICAL (KIND=C_BOOL) :: detect_missing_value_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: field_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_offset + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_op + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: grid_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + INTEGER , OPTIONAL, INTENT(OUT) :: level + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: operation + INTEGER , OPTIONAL, INTENT(OUT) :: prec + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: scale_factor + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_max + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_min + + CALL xios(get_fieldgroup_handle)(fieldgroup_id,fieldgroup_hdl) + CALL xios(get_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(get_fieldgroup_attr) + + SUBROUTINE xios(get_fieldgroup_attr_hdl) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) , INTENT(IN) :: fieldgroup_hdl + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: add_offset + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: default_value + LOGICAL , OPTIONAL, INTENT(OUT) :: detect_missing_value + LOGICAL (KIND=C_BOOL) :: detect_missing_value_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: field_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_offset + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_op + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: grid_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + INTEGER , OPTIONAL, INTENT(OUT) :: level + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: operation + INTEGER , OPTIONAL, INTENT(OUT) :: prec + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: scale_factor + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_max + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_min + + CALL xios(get_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(get_fieldgroup_attr_hdl) + + SUBROUTINE xios(get_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset_, axis_ref_, default_value_, detect_missing_value_, domain_ref_ & + , enabled_, field_ref_, freq_offset_, freq_op_, grid_ref_, group_ref_, level_, long_name_, name_ & + , operation_, prec_, scale_factor_, standard_name_, unit_, valid_max_, valid_min_ ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) , INTENT(IN) :: fieldgroup_hdl + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: add_offset_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: default_value_ + LOGICAL , OPTIONAL, INTENT(OUT) :: detect_missing_value_ + LOGICAL (KIND=C_BOOL) :: detect_missing_value__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref_ + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled_ + LOGICAL (KIND=C_BOOL) :: enabled__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: field_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_offset_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: freq_op_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: grid_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref_ + INTEGER , OPTIONAL, INTENT(OUT) :: level_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: long_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: operation_ + INTEGER , OPTIONAL, INTENT(OUT) :: prec_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: scale_factor_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: standard_name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: unit_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_max_ + REAL (KIND=8) , OPTIONAL, INTENT(OUT) :: valid_min_ + + IF (PRESENT(add_offset_)) THEN + CALL cxios_get_fieldgroup_add_offset(fieldgroup_hdl%daddr, add_offset_) + ENDIF + + IF (PRESENT(axis_ref_)) THEN + CALL cxios_get_fieldgroup_axis_ref(fieldgroup_hdl%daddr, axis_ref_, len(axis_ref_)) + ENDIF + + IF (PRESENT(default_value_)) THEN + CALL cxios_get_fieldgroup_default_value(fieldgroup_hdl%daddr, default_value_) + ENDIF + + IF (PRESENT(detect_missing_value_)) THEN + CALL cxios_get_fieldgroup_detect_missing_value(fieldgroup_hdl%daddr, detect_missing_value__tmp) + detect_missing_value_=detect_missing_value__tmp + ENDIF + + IF (PRESENT(domain_ref_)) THEN + CALL cxios_get_fieldgroup_domain_ref(fieldgroup_hdl%daddr, domain_ref_, len(domain_ref_)) + ENDIF + + IF (PRESENT(enabled_)) THEN + CALL cxios_get_fieldgroup_enabled(fieldgroup_hdl%daddr, enabled__tmp) + enabled_=enabled__tmp + ENDIF + + IF (PRESENT(field_ref_)) THEN + CALL cxios_get_fieldgroup_field_ref(fieldgroup_hdl%daddr, field_ref_, len(field_ref_)) + ENDIF + + IF (PRESENT(freq_offset_)) THEN + CALL cxios_get_fieldgroup_freq_offset(fieldgroup_hdl%daddr, freq_offset_, len(freq_offset_)) + ENDIF + + IF (PRESENT(freq_op_)) THEN + CALL cxios_get_fieldgroup_freq_op(fieldgroup_hdl%daddr, freq_op_, len(freq_op_)) + ENDIF + + IF (PRESENT(grid_ref_)) THEN + CALL cxios_get_fieldgroup_grid_ref(fieldgroup_hdl%daddr, grid_ref_, len(grid_ref_)) + ENDIF + + IF (PRESENT(group_ref_)) THEN + CALL cxios_get_fieldgroup_group_ref(fieldgroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(level_)) THEN + CALL cxios_get_fieldgroup_level(fieldgroup_hdl%daddr, level_) + ENDIF + + IF (PRESENT(long_name_)) THEN + CALL cxios_get_fieldgroup_long_name(fieldgroup_hdl%daddr, long_name_, len(long_name_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_fieldgroup_name(fieldgroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(operation_)) THEN + CALL cxios_get_fieldgroup_operation(fieldgroup_hdl%daddr, operation_, len(operation_)) + ENDIF + + IF (PRESENT(prec_)) THEN + CALL cxios_get_fieldgroup_prec(fieldgroup_hdl%daddr, prec_) + ENDIF + + IF (PRESENT(scale_factor_)) THEN + CALL cxios_get_fieldgroup_scale_factor(fieldgroup_hdl%daddr, scale_factor_) + ENDIF + + IF (PRESENT(standard_name_)) THEN + CALL cxios_get_fieldgroup_standard_name(fieldgroup_hdl%daddr, standard_name_, len(standard_name_)) + ENDIF + + IF (PRESENT(unit_)) THEN + CALL cxios_get_fieldgroup_unit(fieldgroup_hdl%daddr, unit_, len(unit_)) + ENDIF + + IF (PRESENT(valid_max_)) THEN + CALL cxios_get_fieldgroup_valid_max(fieldgroup_hdl%daddr, valid_max_) + ENDIF + + IF (PRESENT(valid_min_)) THEN + CALL cxios_get_fieldgroup_valid_min(fieldgroup_hdl%daddr, valid_min_) + ENDIF + + + + END SUBROUTINE xios(get_fieldgroup_attr_hdl_) + + SUBROUTINE xios(is_defined_fieldgroup_attr) & + ( fieldgroup_id, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) :: fieldgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::fieldgroup_id + LOGICAL, OPTIONAL, INTENT(OUT) :: add_offset + LOGICAL(KIND=C_BOOL) :: add_offset_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref + LOGICAL(KIND=C_BOOL) :: axis_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: default_value + LOGICAL(KIND=C_BOOL) :: default_value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: detect_missing_value + LOGICAL(KIND=C_BOOL) :: detect_missing_value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL(KIND=C_BOOL) :: domain_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled + LOGICAL(KIND=C_BOOL) :: enabled_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: field_ref + LOGICAL(KIND=C_BOOL) :: field_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_offset + LOGICAL(KIND=C_BOOL) :: freq_offset_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_op + LOGICAL(KIND=C_BOOL) :: freq_op_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: grid_ref + LOGICAL(KIND=C_BOOL) :: grid_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: level + LOGICAL(KIND=C_BOOL) :: level_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: operation + LOGICAL(KIND=C_BOOL) :: operation_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: prec + LOGICAL(KIND=C_BOOL) :: prec_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: scale_factor + LOGICAL(KIND=C_BOOL) :: scale_factor_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit + LOGICAL(KIND=C_BOOL) :: unit_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_max + LOGICAL(KIND=C_BOOL) :: valid_max_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_min + LOGICAL(KIND=C_BOOL) :: valid_min_tmp + + CALL xios(get_fieldgroup_handle)(fieldgroup_id,fieldgroup_hdl) + CALL xios(is_defined_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(is_defined_fieldgroup_attr) + + SUBROUTINE xios(is_defined_fieldgroup_attr_hdl) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) , INTENT(IN) :: fieldgroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: add_offset + LOGICAL(KIND=C_BOOL) :: add_offset_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref + LOGICAL(KIND=C_BOOL) :: axis_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: default_value + LOGICAL(KIND=C_BOOL) :: default_value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: detect_missing_value + LOGICAL(KIND=C_BOOL) :: detect_missing_value_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL(KIND=C_BOOL) :: domain_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled + LOGICAL(KIND=C_BOOL) :: enabled_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: field_ref + LOGICAL(KIND=C_BOOL) :: field_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_offset + LOGICAL(KIND=C_BOOL) :: freq_offset_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_op + LOGICAL(KIND=C_BOOL) :: freq_op_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: grid_ref + LOGICAL(KIND=C_BOOL) :: grid_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: level + LOGICAL(KIND=C_BOOL) :: level_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name + LOGICAL(KIND=C_BOOL) :: long_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: operation + LOGICAL(KIND=C_BOOL) :: operation_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: prec + LOGICAL(KIND=C_BOOL) :: prec_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: scale_factor + LOGICAL(KIND=C_BOOL) :: scale_factor_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name + LOGICAL(KIND=C_BOOL) :: standard_name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit + LOGICAL(KIND=C_BOOL) :: unit_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_max + LOGICAL(KIND=C_BOOL) :: valid_max_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_min + LOGICAL(KIND=C_BOOL) :: valid_min_tmp + + CALL xios(is_defined_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset, axis_ref, default_value, detect_missing_value, domain_ref, enabled & + , field_ref, freq_offset, freq_op, grid_ref, group_ref, level, long_name, name, operation, prec & + , scale_factor, standard_name, unit, valid_max, valid_min ) + + END SUBROUTINE xios(is_defined_fieldgroup_attr_hdl) + + SUBROUTINE xios(is_defined_fieldgroup_attr_hdl_) & + ( fieldgroup_hdl, add_offset_, axis_ref_, default_value_, detect_missing_value_, domain_ref_ & + , enabled_, field_ref_, freq_offset_, freq_op_, grid_ref_, group_ref_, level_, long_name_, name_ & + , operation_, prec_, scale_factor_, standard_name_, unit_, valid_max_, valid_min_ ) + + IMPLICIT NONE + TYPE(txios(fieldgroup)) , INTENT(IN) :: fieldgroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: add_offset_ + LOGICAL(KIND=C_BOOL) :: add_offset__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref_ + LOGICAL(KIND=C_BOOL) :: axis_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: default_value_ + LOGICAL(KIND=C_BOOL) :: default_value__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: detect_missing_value_ + LOGICAL(KIND=C_BOOL) :: detect_missing_value__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref_ + LOGICAL(KIND=C_BOOL) :: domain_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled_ + LOGICAL(KIND=C_BOOL) :: enabled__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: field_ref_ + LOGICAL(KIND=C_BOOL) :: field_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_offset_ + LOGICAL(KIND=C_BOOL) :: freq_offset__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: freq_op_ + LOGICAL(KIND=C_BOOL) :: freq_op__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: grid_ref_ + LOGICAL(KIND=C_BOOL) :: grid_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref_ + LOGICAL(KIND=C_BOOL) :: group_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: level_ + LOGICAL(KIND=C_BOOL) :: level__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: long_name_ + LOGICAL(KIND=C_BOOL) :: long_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: operation_ + LOGICAL(KIND=C_BOOL) :: operation__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: prec_ + LOGICAL(KIND=C_BOOL) :: prec__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: scale_factor_ + LOGICAL(KIND=C_BOOL) :: scale_factor__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: standard_name_ + LOGICAL(KIND=C_BOOL) :: standard_name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: unit_ + LOGICAL(KIND=C_BOOL) :: unit__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_max_ + LOGICAL(KIND=C_BOOL) :: valid_max__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: valid_min_ + LOGICAL(KIND=C_BOOL) :: valid_min__tmp + + IF (PRESENT(add_offset_)) THEN + add_offset__tmp=cxios_is_defined_fieldgroup_add_offset(fieldgroup_hdl%daddr) + add_offset_=add_offset__tmp + ENDIF + + IF (PRESENT(axis_ref_)) THEN + axis_ref__tmp=cxios_is_defined_fieldgroup_axis_ref(fieldgroup_hdl%daddr) + axis_ref_=axis_ref__tmp + ENDIF + + IF (PRESENT(default_value_)) THEN + default_value__tmp=cxios_is_defined_fieldgroup_default_value(fieldgroup_hdl%daddr) + default_value_=default_value__tmp + ENDIF + + IF (PRESENT(detect_missing_value_)) THEN + detect_missing_value__tmp=cxios_is_defined_fieldgroup_detect_missing_value(fieldgroup_hdl%daddr) + detect_missing_value_=detect_missing_value__tmp + ENDIF + + IF (PRESENT(domain_ref_)) THEN + domain_ref__tmp=cxios_is_defined_fieldgroup_domain_ref(fieldgroup_hdl%daddr) + domain_ref_=domain_ref__tmp + ENDIF + + IF (PRESENT(enabled_)) THEN + enabled__tmp=cxios_is_defined_fieldgroup_enabled(fieldgroup_hdl%daddr) + enabled_=enabled__tmp + ENDIF + + IF (PRESENT(field_ref_)) THEN + field_ref__tmp=cxios_is_defined_fieldgroup_field_ref(fieldgroup_hdl%daddr) + field_ref_=field_ref__tmp + ENDIF + + IF (PRESENT(freq_offset_)) THEN + freq_offset__tmp=cxios_is_defined_fieldgroup_freq_offset(fieldgroup_hdl%daddr) + freq_offset_=freq_offset__tmp + ENDIF + + IF (PRESENT(freq_op_)) THEN + freq_op__tmp=cxios_is_defined_fieldgroup_freq_op(fieldgroup_hdl%daddr) + freq_op_=freq_op__tmp + ENDIF + + IF (PRESENT(grid_ref_)) THEN + grid_ref__tmp=cxios_is_defined_fieldgroup_grid_ref(fieldgroup_hdl%daddr) + grid_ref_=grid_ref__tmp + ENDIF + + IF (PRESENT(group_ref_)) THEN + group_ref__tmp=cxios_is_defined_fieldgroup_group_ref(fieldgroup_hdl%daddr) + group_ref_=group_ref__tmp + ENDIF + + IF (PRESENT(level_)) THEN + level__tmp=cxios_is_defined_fieldgroup_level(fieldgroup_hdl%daddr) + level_=level__tmp + ENDIF + + IF (PRESENT(long_name_)) THEN + long_name__tmp=cxios_is_defined_fieldgroup_long_name(fieldgroup_hdl%daddr) + long_name_=long_name__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_fieldgroup_name(fieldgroup_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(operation_)) THEN + operation__tmp=cxios_is_defined_fieldgroup_operation(fieldgroup_hdl%daddr) + operation_=operation__tmp + ENDIF + + IF (PRESENT(prec_)) THEN + prec__tmp=cxios_is_defined_fieldgroup_prec(fieldgroup_hdl%daddr) + prec_=prec__tmp + ENDIF + + IF (PRESENT(scale_factor_)) THEN + scale_factor__tmp=cxios_is_defined_fieldgroup_scale_factor(fieldgroup_hdl%daddr) + scale_factor_=scale_factor__tmp + ENDIF + + IF (PRESENT(standard_name_)) THEN + standard_name__tmp=cxios_is_defined_fieldgroup_standard_name(fieldgroup_hdl%daddr) + standard_name_=standard_name__tmp + ENDIF + + IF (PRESENT(unit_)) THEN + unit__tmp=cxios_is_defined_fieldgroup_unit(fieldgroup_hdl%daddr) + unit_=unit__tmp + ENDIF + + IF (PRESENT(valid_max_)) THEN + valid_max__tmp=cxios_is_defined_fieldgroup_valid_max(fieldgroup_hdl%daddr) + valid_max_=valid_max__tmp + ENDIF + + IF (PRESENT(valid_min_)) THEN + valid_min__tmp=cxios_is_defined_fieldgroup_valid_min(fieldgroup_hdl%daddr) + valid_min_=valid_min__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_fieldgroup_attr_hdl_) + +END MODULE ifieldgroup_attr diff --git a/src/interface/fortran_attr/ifile_attr.F90 b/src/interface/fortran_attr/ifile_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..587781b03e314db7c0f9161e98025dde70cb5803 --- /dev/null +++ b/src/interface/fortran_attr/ifile_attr.F90 @@ -0,0 +1,438 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE ifile_attr + USE, INTRINSIC :: ISO_C_BINDING + USE ifile + USE file_interface_attr + +CONTAINS + + SUBROUTINE xios(set_file_attr) & + ( file_id, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(file)) :: file_hdl + CHARACTER(LEN=*), INTENT(IN) ::file_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description + LOGICAL , OPTIONAL, INTENT(IN) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + INTEGER , OPTIONAL, INTENT(IN) :: min_digits + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_suffix + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_freq + INTEGER , OPTIONAL, INTENT(IN) :: output_level + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: par_access + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq_format + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: sync_freq + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + + CALL xios(get_file_handle)(file_id,file_hdl) + CALL xios(set_file_attr_hdl_) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(set_file_attr) + + SUBROUTINE xios(set_file_attr_hdl) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(file)) , INTENT(IN) :: file_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description + LOGICAL , OPTIONAL, INTENT(IN) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + INTEGER , OPTIONAL, INTENT(IN) :: min_digits + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_suffix + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_freq + INTEGER , OPTIONAL, INTENT(IN) :: output_level + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: par_access + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq_format + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: sync_freq + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + + CALL xios(set_file_attr_hdl_) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(set_file_attr_hdl) + + SUBROUTINE xios(set_file_attr_hdl_) & + ( file_hdl, description_, enabled_, min_digits_, name_, name_suffix_, output_freq_, output_level_ & + , par_access_, split_freq_, split_freq_format_, sync_freq_, type_ ) + + IMPLICIT NONE + TYPE(txios(file)) , INTENT(IN) :: file_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description_ + LOGICAL , OPTIONAL, INTENT(IN) :: enabled_ + LOGICAL (KIND=C_BOOL) :: enabled__tmp + INTEGER , OPTIONAL, INTENT(IN) :: min_digits_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_suffix_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_freq_ + INTEGER , OPTIONAL, INTENT(IN) :: output_level_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: par_access_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq_format_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: sync_freq_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type_ + + IF (PRESENT(description_)) THEN + CALL cxios_set_file_description(file_hdl%daddr, description_, len(description_)) + ENDIF + + IF (PRESENT(enabled_)) THEN + enabled__tmp=enabled_ + CALL cxios_set_file_enabled(file_hdl%daddr, enabled__tmp) + ENDIF + + IF (PRESENT(min_digits_)) THEN + CALL cxios_set_file_min_digits(file_hdl%daddr, min_digits_) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_file_name(file_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(name_suffix_)) THEN + CALL cxios_set_file_name_suffix(file_hdl%daddr, name_suffix_, len(name_suffix_)) + ENDIF + + IF (PRESENT(output_freq_)) THEN + CALL cxios_set_file_output_freq(file_hdl%daddr, output_freq_, len(output_freq_)) + ENDIF + + IF (PRESENT(output_level_)) THEN + CALL cxios_set_file_output_level(file_hdl%daddr, output_level_) + ENDIF + + IF (PRESENT(par_access_)) THEN + CALL cxios_set_file_par_access(file_hdl%daddr, par_access_, len(par_access_)) + ENDIF + + IF (PRESENT(split_freq_)) THEN + CALL cxios_set_file_split_freq(file_hdl%daddr, split_freq_, len(split_freq_)) + ENDIF + + IF (PRESENT(split_freq_format_)) THEN + CALL cxios_set_file_split_freq_format(file_hdl%daddr, split_freq_format_, len(split_freq_format_)) + ENDIF + + IF (PRESENT(sync_freq_)) THEN + CALL cxios_set_file_sync_freq(file_hdl%daddr, sync_freq_, len(sync_freq_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_set_file_type(file_hdl%daddr, type_, len(type_)) + ENDIF + + + + END SUBROUTINE xios(set_file_attr_hdl_) + + SUBROUTINE xios(get_file_attr) & + ( file_id, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(file)) :: file_hdl + CHARACTER(LEN=*), INTENT(IN) ::file_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + INTEGER , OPTIONAL, INTENT(OUT) :: min_digits + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_suffix + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_freq + INTEGER , OPTIONAL, INTENT(OUT) :: output_level + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: par_access + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq_format + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: sync_freq + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + + CALL xios(get_file_handle)(file_id,file_hdl) + CALL xios(get_file_attr_hdl_) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(get_file_attr) + + SUBROUTINE xios(get_file_attr_hdl) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(file)) , INTENT(IN) :: file_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + INTEGER , OPTIONAL, INTENT(OUT) :: min_digits + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_suffix + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_freq + INTEGER , OPTIONAL, INTENT(OUT) :: output_level + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: par_access + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq_format + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: sync_freq + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + + CALL xios(get_file_attr_hdl_) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(get_file_attr_hdl) + + SUBROUTINE xios(get_file_attr_hdl_) & + ( file_hdl, description_, enabled_, min_digits_, name_, name_suffix_, output_freq_, output_level_ & + , par_access_, split_freq_, split_freq_format_, sync_freq_, type_ ) + + IMPLICIT NONE + TYPE(txios(file)) , INTENT(IN) :: file_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description_ + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled_ + LOGICAL (KIND=C_BOOL) :: enabled__tmp + INTEGER , OPTIONAL, INTENT(OUT) :: min_digits_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_suffix_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_freq_ + INTEGER , OPTIONAL, INTENT(OUT) :: output_level_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: par_access_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq_format_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: sync_freq_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type_ + + IF (PRESENT(description_)) THEN + CALL cxios_get_file_description(file_hdl%daddr, description_, len(description_)) + ENDIF + + IF (PRESENT(enabled_)) THEN + CALL cxios_get_file_enabled(file_hdl%daddr, enabled__tmp) + enabled_=enabled__tmp + ENDIF + + IF (PRESENT(min_digits_)) THEN + CALL cxios_get_file_min_digits(file_hdl%daddr, min_digits_) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_file_name(file_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(name_suffix_)) THEN + CALL cxios_get_file_name_suffix(file_hdl%daddr, name_suffix_, len(name_suffix_)) + ENDIF + + IF (PRESENT(output_freq_)) THEN + CALL cxios_get_file_output_freq(file_hdl%daddr, output_freq_, len(output_freq_)) + ENDIF + + IF (PRESENT(output_level_)) THEN + CALL cxios_get_file_output_level(file_hdl%daddr, output_level_) + ENDIF + + IF (PRESENT(par_access_)) THEN + CALL cxios_get_file_par_access(file_hdl%daddr, par_access_, len(par_access_)) + ENDIF + + IF (PRESENT(split_freq_)) THEN + CALL cxios_get_file_split_freq(file_hdl%daddr, split_freq_, len(split_freq_)) + ENDIF + + IF (PRESENT(split_freq_format_)) THEN + CALL cxios_get_file_split_freq_format(file_hdl%daddr, split_freq_format_, len(split_freq_format_)) + ENDIF + + IF (PRESENT(sync_freq_)) THEN + CALL cxios_get_file_sync_freq(file_hdl%daddr, sync_freq_, len(sync_freq_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_get_file_type(file_hdl%daddr, type_, len(type_)) + ENDIF + + + + END SUBROUTINE xios(get_file_attr_hdl_) + + SUBROUTINE xios(is_defined_file_attr) & + ( file_id, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(file)) :: file_hdl + CHARACTER(LEN=*), INTENT(IN) ::file_id + LOGICAL, OPTIONAL, INTENT(OUT) :: description + LOGICAL(KIND=C_BOOL) :: description_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled + LOGICAL(KIND=C_BOOL) :: enabled_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: min_digits + LOGICAL(KIND=C_BOOL) :: min_digits_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_suffix + LOGICAL(KIND=C_BOOL) :: name_suffix_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_freq + LOGICAL(KIND=C_BOOL) :: output_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_level + LOGICAL(KIND=C_BOOL) :: output_level_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: par_access + LOGICAL(KIND=C_BOOL) :: par_access_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq + LOGICAL(KIND=C_BOOL) :: split_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq_format + LOGICAL(KIND=C_BOOL) :: split_freq_format_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: sync_freq + LOGICAL(KIND=C_BOOL) :: sync_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + + CALL xios(get_file_handle)(file_id,file_hdl) + CALL xios(is_defined_file_attr_hdl_) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(is_defined_file_attr) + + SUBROUTINE xios(is_defined_file_attr_hdl) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(file)) , INTENT(IN) :: file_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: description + LOGICAL(KIND=C_BOOL) :: description_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled + LOGICAL(KIND=C_BOOL) :: enabled_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: min_digits + LOGICAL(KIND=C_BOOL) :: min_digits_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_suffix + LOGICAL(KIND=C_BOOL) :: name_suffix_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_freq + LOGICAL(KIND=C_BOOL) :: output_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_level + LOGICAL(KIND=C_BOOL) :: output_level_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: par_access + LOGICAL(KIND=C_BOOL) :: par_access_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq + LOGICAL(KIND=C_BOOL) :: split_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq_format + LOGICAL(KIND=C_BOOL) :: split_freq_format_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: sync_freq + LOGICAL(KIND=C_BOOL) :: sync_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + + CALL xios(is_defined_file_attr_hdl_) & + ( file_hdl, description, enabled, min_digits, name, name_suffix, output_freq, output_level, par_access & + , split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(is_defined_file_attr_hdl) + + SUBROUTINE xios(is_defined_file_attr_hdl_) & + ( file_hdl, description_, enabled_, min_digits_, name_, name_suffix_, output_freq_, output_level_ & + , par_access_, split_freq_, split_freq_format_, sync_freq_, type_ ) + + IMPLICIT NONE + TYPE(txios(file)) , INTENT(IN) :: file_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: description_ + LOGICAL(KIND=C_BOOL) :: description__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled_ + LOGICAL(KIND=C_BOOL) :: enabled__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: min_digits_ + LOGICAL(KIND=C_BOOL) :: min_digits__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_suffix_ + LOGICAL(KIND=C_BOOL) :: name_suffix__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_freq_ + LOGICAL(KIND=C_BOOL) :: output_freq__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_level_ + LOGICAL(KIND=C_BOOL) :: output_level__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: par_access_ + LOGICAL(KIND=C_BOOL) :: par_access__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq_ + LOGICAL(KIND=C_BOOL) :: split_freq__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq_format_ + LOGICAL(KIND=C_BOOL) :: split_freq_format__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: sync_freq_ + LOGICAL(KIND=C_BOOL) :: sync_freq__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type_ + LOGICAL(KIND=C_BOOL) :: type__tmp + + IF (PRESENT(description_)) THEN + description__tmp=cxios_is_defined_file_description(file_hdl%daddr) + description_=description__tmp + ENDIF + + IF (PRESENT(enabled_)) THEN + enabled__tmp=cxios_is_defined_file_enabled(file_hdl%daddr) + enabled_=enabled__tmp + ENDIF + + IF (PRESENT(min_digits_)) THEN + min_digits__tmp=cxios_is_defined_file_min_digits(file_hdl%daddr) + min_digits_=min_digits__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_file_name(file_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(name_suffix_)) THEN + name_suffix__tmp=cxios_is_defined_file_name_suffix(file_hdl%daddr) + name_suffix_=name_suffix__tmp + ENDIF + + IF (PRESENT(output_freq_)) THEN + output_freq__tmp=cxios_is_defined_file_output_freq(file_hdl%daddr) + output_freq_=output_freq__tmp + ENDIF + + IF (PRESENT(output_level_)) THEN + output_level__tmp=cxios_is_defined_file_output_level(file_hdl%daddr) + output_level_=output_level__tmp + ENDIF + + IF (PRESENT(par_access_)) THEN + par_access__tmp=cxios_is_defined_file_par_access(file_hdl%daddr) + par_access_=par_access__tmp + ENDIF + + IF (PRESENT(split_freq_)) THEN + split_freq__tmp=cxios_is_defined_file_split_freq(file_hdl%daddr) + split_freq_=split_freq__tmp + ENDIF + + IF (PRESENT(split_freq_format_)) THEN + split_freq_format__tmp=cxios_is_defined_file_split_freq_format(file_hdl%daddr) + split_freq_format_=split_freq_format__tmp + ENDIF + + IF (PRESENT(sync_freq_)) THEN + sync_freq__tmp=cxios_is_defined_file_sync_freq(file_hdl%daddr) + sync_freq_=sync_freq__tmp + ENDIF + + IF (PRESENT(type_)) THEN + type__tmp=cxios_is_defined_file_type(file_hdl%daddr) + type_=type__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_file_attr_hdl_) + +END MODULE ifile_attr diff --git a/src/interface/fortran_attr/ifilegroup_attr.F90 b/src/interface/fortran_attr/ifilegroup_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..45e536c61b655216695e443a4a23ab201f184a35 --- /dev/null +++ b/src/interface/fortran_attr/ifilegroup_attr.F90 @@ -0,0 +1,463 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE ifilegroup_attr + USE, INTRINSIC :: ISO_C_BINDING + USE ifile + USE filegroup_interface_attr + +CONTAINS + + SUBROUTINE xios(set_filegroup_attr) & + ( filegroup_id, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(filegroup)) :: filegroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::filegroup_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description + LOGICAL , OPTIONAL, INTENT(IN) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + INTEGER , OPTIONAL, INTENT(IN) :: min_digits + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_suffix + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_freq + INTEGER , OPTIONAL, INTENT(IN) :: output_level + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: par_access + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq_format + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: sync_freq + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + + CALL xios(get_filegroup_handle)(filegroup_id,filegroup_hdl) + CALL xios(set_filegroup_attr_hdl_) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(set_filegroup_attr) + + SUBROUTINE xios(set_filegroup_attr_hdl) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(filegroup)) , INTENT(IN) :: filegroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description + LOGICAL , OPTIONAL, INTENT(IN) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + INTEGER , OPTIONAL, INTENT(IN) :: min_digits + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_suffix + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_freq + INTEGER , OPTIONAL, INTENT(IN) :: output_level + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: par_access + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq_format + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: sync_freq + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + + CALL xios(set_filegroup_attr_hdl_) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(set_filegroup_attr_hdl) + + SUBROUTINE xios(set_filegroup_attr_hdl_) & + ( filegroup_hdl, description_, enabled_, group_ref_, min_digits_, name_, name_suffix_, output_freq_ & + , output_level_, par_access_, split_freq_, split_freq_format_, sync_freq_, type_ ) + + IMPLICIT NONE + TYPE(txios(filegroup)) , INTENT(IN) :: filegroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description_ + LOGICAL , OPTIONAL, INTENT(IN) :: enabled_ + LOGICAL (KIND=C_BOOL) :: enabled__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref_ + INTEGER , OPTIONAL, INTENT(IN) :: min_digits_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_suffix_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: output_freq_ + INTEGER , OPTIONAL, INTENT(IN) :: output_level_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: par_access_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: split_freq_format_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: sync_freq_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type_ + + IF (PRESENT(description_)) THEN + CALL cxios_set_filegroup_description(filegroup_hdl%daddr, description_, len(description_)) + ENDIF + + IF (PRESENT(enabled_)) THEN + enabled__tmp=enabled_ + CALL cxios_set_filegroup_enabled(filegroup_hdl%daddr, enabled__tmp) + ENDIF + + IF (PRESENT(group_ref_)) THEN + CALL cxios_set_filegroup_group_ref(filegroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(min_digits_)) THEN + CALL cxios_set_filegroup_min_digits(filegroup_hdl%daddr, min_digits_) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_filegroup_name(filegroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(name_suffix_)) THEN + CALL cxios_set_filegroup_name_suffix(filegroup_hdl%daddr, name_suffix_, len(name_suffix_)) + ENDIF + + IF (PRESENT(output_freq_)) THEN + CALL cxios_set_filegroup_output_freq(filegroup_hdl%daddr, output_freq_, len(output_freq_)) + ENDIF + + IF (PRESENT(output_level_)) THEN + CALL cxios_set_filegroup_output_level(filegroup_hdl%daddr, output_level_) + ENDIF + + IF (PRESENT(par_access_)) THEN + CALL cxios_set_filegroup_par_access(filegroup_hdl%daddr, par_access_, len(par_access_)) + ENDIF + + IF (PRESENT(split_freq_)) THEN + CALL cxios_set_filegroup_split_freq(filegroup_hdl%daddr, split_freq_, len(split_freq_)) + ENDIF + + IF (PRESENT(split_freq_format_)) THEN + CALL cxios_set_filegroup_split_freq_format(filegroup_hdl%daddr, split_freq_format_, len(split_freq_format_)) + ENDIF + + IF (PRESENT(sync_freq_)) THEN + CALL cxios_set_filegroup_sync_freq(filegroup_hdl%daddr, sync_freq_, len(sync_freq_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_set_filegroup_type(filegroup_hdl%daddr, type_, len(type_)) + ENDIF + + + + END SUBROUTINE xios(set_filegroup_attr_hdl_) + + SUBROUTINE xios(get_filegroup_attr) & + ( filegroup_id, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(filegroup)) :: filegroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::filegroup_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + INTEGER , OPTIONAL, INTENT(OUT) :: min_digits + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_suffix + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_freq + INTEGER , OPTIONAL, INTENT(OUT) :: output_level + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: par_access + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq_format + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: sync_freq + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + + CALL xios(get_filegroup_handle)(filegroup_id,filegroup_hdl) + CALL xios(get_filegroup_attr_hdl_) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(get_filegroup_attr) + + SUBROUTINE xios(get_filegroup_attr_hdl) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(filegroup)) , INTENT(IN) :: filegroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled + LOGICAL (KIND=C_BOOL) :: enabled_tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + INTEGER , OPTIONAL, INTENT(OUT) :: min_digits + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_suffix + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_freq + INTEGER , OPTIONAL, INTENT(OUT) :: output_level + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: par_access + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq_format + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: sync_freq + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + + CALL xios(get_filegroup_attr_hdl_) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(get_filegroup_attr_hdl) + + SUBROUTINE xios(get_filegroup_attr_hdl_) & + ( filegroup_hdl, description_, enabled_, group_ref_, min_digits_, name_, name_suffix_, output_freq_ & + , output_level_, par_access_, split_freq_, split_freq_format_, sync_freq_, type_ ) + + IMPLICIT NONE + TYPE(txios(filegroup)) , INTENT(IN) :: filegroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description_ + LOGICAL , OPTIONAL, INTENT(OUT) :: enabled_ + LOGICAL (KIND=C_BOOL) :: enabled__tmp + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref_ + INTEGER , OPTIONAL, INTENT(OUT) :: min_digits_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_suffix_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: output_freq_ + INTEGER , OPTIONAL, INTENT(OUT) :: output_level_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: par_access_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: split_freq_format_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: sync_freq_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type_ + + IF (PRESENT(description_)) THEN + CALL cxios_get_filegroup_description(filegroup_hdl%daddr, description_, len(description_)) + ENDIF + + IF (PRESENT(enabled_)) THEN + CALL cxios_get_filegroup_enabled(filegroup_hdl%daddr, enabled__tmp) + enabled_=enabled__tmp + ENDIF + + IF (PRESENT(group_ref_)) THEN + CALL cxios_get_filegroup_group_ref(filegroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(min_digits_)) THEN + CALL cxios_get_filegroup_min_digits(filegroup_hdl%daddr, min_digits_) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_filegroup_name(filegroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(name_suffix_)) THEN + CALL cxios_get_filegroup_name_suffix(filegroup_hdl%daddr, name_suffix_, len(name_suffix_)) + ENDIF + + IF (PRESENT(output_freq_)) THEN + CALL cxios_get_filegroup_output_freq(filegroup_hdl%daddr, output_freq_, len(output_freq_)) + ENDIF + + IF (PRESENT(output_level_)) THEN + CALL cxios_get_filegroup_output_level(filegroup_hdl%daddr, output_level_) + ENDIF + + IF (PRESENT(par_access_)) THEN + CALL cxios_get_filegroup_par_access(filegroup_hdl%daddr, par_access_, len(par_access_)) + ENDIF + + IF (PRESENT(split_freq_)) THEN + CALL cxios_get_filegroup_split_freq(filegroup_hdl%daddr, split_freq_, len(split_freq_)) + ENDIF + + IF (PRESENT(split_freq_format_)) THEN + CALL cxios_get_filegroup_split_freq_format(filegroup_hdl%daddr, split_freq_format_, len(split_freq_format_)) + ENDIF + + IF (PRESENT(sync_freq_)) THEN + CALL cxios_get_filegroup_sync_freq(filegroup_hdl%daddr, sync_freq_, len(sync_freq_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_get_filegroup_type(filegroup_hdl%daddr, type_, len(type_)) + ENDIF + + + + END SUBROUTINE xios(get_filegroup_attr_hdl_) + + SUBROUTINE xios(is_defined_filegroup_attr) & + ( filegroup_id, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(filegroup)) :: filegroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::filegroup_id + LOGICAL, OPTIONAL, INTENT(OUT) :: description + LOGICAL(KIND=C_BOOL) :: description_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled + LOGICAL(KIND=C_BOOL) :: enabled_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: min_digits + LOGICAL(KIND=C_BOOL) :: min_digits_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_suffix + LOGICAL(KIND=C_BOOL) :: name_suffix_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_freq + LOGICAL(KIND=C_BOOL) :: output_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_level + LOGICAL(KIND=C_BOOL) :: output_level_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: par_access + LOGICAL(KIND=C_BOOL) :: par_access_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq + LOGICAL(KIND=C_BOOL) :: split_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq_format + LOGICAL(KIND=C_BOOL) :: split_freq_format_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: sync_freq + LOGICAL(KIND=C_BOOL) :: sync_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + + CALL xios(get_filegroup_handle)(filegroup_id,filegroup_hdl) + CALL xios(is_defined_filegroup_attr_hdl_) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(is_defined_filegroup_attr) + + SUBROUTINE xios(is_defined_filegroup_attr_hdl) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + IMPLICIT NONE + TYPE(txios(filegroup)) , INTENT(IN) :: filegroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: description + LOGICAL(KIND=C_BOOL) :: description_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled + LOGICAL(KIND=C_BOOL) :: enabled_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: min_digits + LOGICAL(KIND=C_BOOL) :: min_digits_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_suffix + LOGICAL(KIND=C_BOOL) :: name_suffix_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_freq + LOGICAL(KIND=C_BOOL) :: output_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_level + LOGICAL(KIND=C_BOOL) :: output_level_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: par_access + LOGICAL(KIND=C_BOOL) :: par_access_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq + LOGICAL(KIND=C_BOOL) :: split_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq_format + LOGICAL(KIND=C_BOOL) :: split_freq_format_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: sync_freq + LOGICAL(KIND=C_BOOL) :: sync_freq_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + + CALL xios(is_defined_filegroup_attr_hdl_) & + ( filegroup_hdl, description, enabled, group_ref, min_digits, name, name_suffix, output_freq & + , output_level, par_access, split_freq, split_freq_format, sync_freq, type ) + + END SUBROUTINE xios(is_defined_filegroup_attr_hdl) + + SUBROUTINE xios(is_defined_filegroup_attr_hdl_) & + ( filegroup_hdl, description_, enabled_, group_ref_, min_digits_, name_, name_suffix_, output_freq_ & + , output_level_, par_access_, split_freq_, split_freq_format_, sync_freq_, type_ ) + + IMPLICIT NONE + TYPE(txios(filegroup)) , INTENT(IN) :: filegroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: description_ + LOGICAL(KIND=C_BOOL) :: description__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: enabled_ + LOGICAL(KIND=C_BOOL) :: enabled__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref_ + LOGICAL(KIND=C_BOOL) :: group_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: min_digits_ + LOGICAL(KIND=C_BOOL) :: min_digits__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_suffix_ + LOGICAL(KIND=C_BOOL) :: name_suffix__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_freq_ + LOGICAL(KIND=C_BOOL) :: output_freq__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: output_level_ + LOGICAL(KIND=C_BOOL) :: output_level__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: par_access_ + LOGICAL(KIND=C_BOOL) :: par_access__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq_ + LOGICAL(KIND=C_BOOL) :: split_freq__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: split_freq_format_ + LOGICAL(KIND=C_BOOL) :: split_freq_format__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: sync_freq_ + LOGICAL(KIND=C_BOOL) :: sync_freq__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type_ + LOGICAL(KIND=C_BOOL) :: type__tmp + + IF (PRESENT(description_)) THEN + description__tmp=cxios_is_defined_filegroup_description(filegroup_hdl%daddr) + description_=description__tmp + ENDIF + + IF (PRESENT(enabled_)) THEN + enabled__tmp=cxios_is_defined_filegroup_enabled(filegroup_hdl%daddr) + enabled_=enabled__tmp + ENDIF + + IF (PRESENT(group_ref_)) THEN + group_ref__tmp=cxios_is_defined_filegroup_group_ref(filegroup_hdl%daddr) + group_ref_=group_ref__tmp + ENDIF + + IF (PRESENT(min_digits_)) THEN + min_digits__tmp=cxios_is_defined_filegroup_min_digits(filegroup_hdl%daddr) + min_digits_=min_digits__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_filegroup_name(filegroup_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(name_suffix_)) THEN + name_suffix__tmp=cxios_is_defined_filegroup_name_suffix(filegroup_hdl%daddr) + name_suffix_=name_suffix__tmp + ENDIF + + IF (PRESENT(output_freq_)) THEN + output_freq__tmp=cxios_is_defined_filegroup_output_freq(filegroup_hdl%daddr) + output_freq_=output_freq__tmp + ENDIF + + IF (PRESENT(output_level_)) THEN + output_level__tmp=cxios_is_defined_filegroup_output_level(filegroup_hdl%daddr) + output_level_=output_level__tmp + ENDIF + + IF (PRESENT(par_access_)) THEN + par_access__tmp=cxios_is_defined_filegroup_par_access(filegroup_hdl%daddr) + par_access_=par_access__tmp + ENDIF + + IF (PRESENT(split_freq_)) THEN + split_freq__tmp=cxios_is_defined_filegroup_split_freq(filegroup_hdl%daddr) + split_freq_=split_freq__tmp + ENDIF + + IF (PRESENT(split_freq_format_)) THEN + split_freq_format__tmp=cxios_is_defined_filegroup_split_freq_format(filegroup_hdl%daddr) + split_freq_format_=split_freq_format__tmp + ENDIF + + IF (PRESENT(sync_freq_)) THEN + sync_freq__tmp=cxios_is_defined_filegroup_sync_freq(filegroup_hdl%daddr) + sync_freq_=sync_freq__tmp + ENDIF + + IF (PRESENT(type_)) THEN + type__tmp=cxios_is_defined_filegroup_type(filegroup_hdl%daddr) + type_=type__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_filegroup_attr_hdl_) + +END MODULE ifilegroup_attr diff --git a/src/interface/fortran_attr/igrid_attr.F90 b/src/interface/fortran_attr/igrid_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..0b37c57b0719c01207a249826d4ef54f0d87bf15 --- /dev/null +++ b/src/interface/fortran_attr/igrid_attr.F90 @@ -0,0 +1,250 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE igrid_attr + USE, INTRINSIC :: ISO_C_BINDING + USE igrid + USE grid_interface_attr + +CONTAINS + + SUBROUTINE xios(set_grid_attr) & + ( grid_id, axis_ref, description, domain_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(grid)) :: grid_hdl + CHARACTER(LEN=*), INTENT(IN) ::grid_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref + LOGICAL , OPTIONAL, INTENT(IN) :: mask(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + + CALL xios(get_grid_handle)(grid_id,grid_hdl) + CALL xios(set_grid_attr_hdl_) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + END SUBROUTINE xios(set_grid_attr) + + SUBROUTINE xios(set_grid_attr_hdl) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(grid)) , INTENT(IN) :: grid_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref + LOGICAL , OPTIONAL, INTENT(IN) :: mask(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + + CALL xios(set_grid_attr_hdl_) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + END SUBROUTINE xios(set_grid_attr_hdl) + + SUBROUTINE xios(set_grid_attr_hdl_) & + ( grid_hdl, axis_ref_, description_, domain_ref_, mask_, name_ ) + + IMPLICIT NONE + TYPE(txios(grid)) , INTENT(IN) :: grid_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref_ + LOGICAL , OPTIONAL, INTENT(IN) :: mask_(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask__tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + + IF (PRESENT(axis_ref_)) THEN + CALL cxios_set_grid_axis_ref(grid_hdl%daddr, axis_ref_, len(axis_ref_)) + ENDIF + + IF (PRESENT(description_)) THEN + CALL cxios_set_grid_description(grid_hdl%daddr, description_, len(description_)) + ENDIF + + IF (PRESENT(domain_ref_)) THEN + CALL cxios_set_grid_domain_ref(grid_hdl%daddr, domain_ref_, len(domain_ref_)) + ENDIF + + IF (PRESENT(mask_)) THEN + ALLOCATE(mask__tmp(size(mask_,1),size(mask_,2),size(mask_,3))) + mask__tmp=mask_ + CALL cxios_set_grid_mask(grid_hdl%daddr, mask__tmp,size(mask_,1),size(mask_,2),size(mask_,3)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_grid_name(grid_hdl%daddr, name_, len(name_)) + ENDIF + + + + END SUBROUTINE xios(set_grid_attr_hdl_) + + SUBROUTINE xios(get_grid_attr) & + ( grid_id, axis_ref, description, domain_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(grid)) :: grid_hdl + CHARACTER(LEN=*), INTENT(IN) ::grid_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL , OPTIONAL, INTENT(OUT) :: mask(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + + CALL xios(get_grid_handle)(grid_id,grid_hdl) + CALL xios(get_grid_attr_hdl_) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + END SUBROUTINE xios(get_grid_attr) + + SUBROUTINE xios(get_grid_attr_hdl) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(grid)) , INTENT(IN) :: grid_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL , OPTIONAL, INTENT(OUT) :: mask(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + + CALL xios(get_grid_attr_hdl_) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + END SUBROUTINE xios(get_grid_attr_hdl) + + SUBROUTINE xios(get_grid_attr_hdl_) & + ( grid_hdl, axis_ref_, description_, domain_ref_, mask_, name_ ) + + IMPLICIT NONE + TYPE(txios(grid)) , INTENT(IN) :: grid_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref_ + LOGICAL , OPTIONAL, INTENT(OUT) :: mask_(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask__tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + + IF (PRESENT(axis_ref_)) THEN + CALL cxios_get_grid_axis_ref(grid_hdl%daddr, axis_ref_, len(axis_ref_)) + ENDIF + + IF (PRESENT(description_)) THEN + CALL cxios_get_grid_description(grid_hdl%daddr, description_, len(description_)) + ENDIF + + IF (PRESENT(domain_ref_)) THEN + CALL cxios_get_grid_domain_ref(grid_hdl%daddr, domain_ref_, len(domain_ref_)) + ENDIF + + IF (PRESENT(mask_)) THEN + ALLOCATE(mask__tmp(size(mask_,1),size(mask_,2),size(mask_,3))) + CALL cxios_get_grid_mask(grid_hdl%daddr, mask__tmp,size(mask_,1),size(mask_,2),size(mask_,3)) + mask_=mask__tmp + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_grid_name(grid_hdl%daddr, name_, len(name_)) + ENDIF + + + + END SUBROUTINE xios(get_grid_attr_hdl_) + + SUBROUTINE xios(is_defined_grid_attr) & + ( grid_id, axis_ref, description, domain_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(grid)) :: grid_hdl + CHARACTER(LEN=*), INTENT(IN) ::grid_id + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref + LOGICAL(KIND=C_BOOL) :: axis_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: description + LOGICAL(KIND=C_BOOL) :: description_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL(KIND=C_BOOL) :: domain_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask + LOGICAL(KIND=C_BOOL) :: mask_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + + CALL xios(get_grid_handle)(grid_id,grid_hdl) + CALL xios(is_defined_grid_attr_hdl_) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + END SUBROUTINE xios(is_defined_grid_attr) + + SUBROUTINE xios(is_defined_grid_attr_hdl) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(grid)) , INTENT(IN) :: grid_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref + LOGICAL(KIND=C_BOOL) :: axis_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: description + LOGICAL(KIND=C_BOOL) :: description_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL(KIND=C_BOOL) :: domain_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask + LOGICAL(KIND=C_BOOL) :: mask_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + + CALL xios(is_defined_grid_attr_hdl_) & + ( grid_hdl, axis_ref, description, domain_ref, mask, name ) + + END SUBROUTINE xios(is_defined_grid_attr_hdl) + + SUBROUTINE xios(is_defined_grid_attr_hdl_) & + ( grid_hdl, axis_ref_, description_, domain_ref_, mask_, name_ ) + + IMPLICIT NONE + TYPE(txios(grid)) , INTENT(IN) :: grid_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref_ + LOGICAL(KIND=C_BOOL) :: axis_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: description_ + LOGICAL(KIND=C_BOOL) :: description__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref_ + LOGICAL(KIND=C_BOOL) :: domain_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask_ + LOGICAL(KIND=C_BOOL) :: mask__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + + IF (PRESENT(axis_ref_)) THEN + axis_ref__tmp=cxios_is_defined_grid_axis_ref(grid_hdl%daddr) + axis_ref_=axis_ref__tmp + ENDIF + + IF (PRESENT(description_)) THEN + description__tmp=cxios_is_defined_grid_description(grid_hdl%daddr) + description_=description__tmp + ENDIF + + IF (PRESENT(domain_ref_)) THEN + domain_ref__tmp=cxios_is_defined_grid_domain_ref(grid_hdl%daddr) + domain_ref_=domain_ref__tmp + ENDIF + + IF (PRESENT(mask_)) THEN + mask__tmp=cxios_is_defined_grid_mask(grid_hdl%daddr) + mask_=mask__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_grid_name(grid_hdl%daddr) + name_=name__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_grid_attr_hdl_) + +END MODULE igrid_attr diff --git a/src/interface/fortran_attr/igridgroup_attr.F90 b/src/interface/fortran_attr/igridgroup_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..ca39ef8b2c94d80d097073edb91978f5ada307ee --- /dev/null +++ b/src/interface/fortran_attr/igridgroup_attr.F90 @@ -0,0 +1,275 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE igridgroup_attr + USE, INTRINSIC :: ISO_C_BINDING + USE igrid + USE gridgroup_interface_attr + +CONTAINS + + SUBROUTINE xios(set_gridgroup_attr) & + ( gridgroup_id, axis_ref, description, domain_ref, group_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) :: gridgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::gridgroup_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + LOGICAL , OPTIONAL, INTENT(IN) :: mask(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + + CALL xios(get_gridgroup_handle)(gridgroup_id,gridgroup_hdl) + CALL xios(set_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + END SUBROUTINE xios(set_gridgroup_attr) + + SUBROUTINE xios(set_gridgroup_attr_hdl) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) , INTENT(IN) :: gridgroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + LOGICAL , OPTIONAL, INTENT(IN) :: mask(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + + CALL xios(set_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + END SUBROUTINE xios(set_gridgroup_attr_hdl) + + SUBROUTINE xios(set_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref_, description_, domain_ref_, group_ref_, mask_, name_ ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) , INTENT(IN) :: gridgroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: axis_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: description_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: domain_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref_ + LOGICAL , OPTIONAL, INTENT(IN) :: mask_(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask__tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + + IF (PRESENT(axis_ref_)) THEN + CALL cxios_set_gridgroup_axis_ref(gridgroup_hdl%daddr, axis_ref_, len(axis_ref_)) + ENDIF + + IF (PRESENT(description_)) THEN + CALL cxios_set_gridgroup_description(gridgroup_hdl%daddr, description_, len(description_)) + ENDIF + + IF (PRESENT(domain_ref_)) THEN + CALL cxios_set_gridgroup_domain_ref(gridgroup_hdl%daddr, domain_ref_, len(domain_ref_)) + ENDIF + + IF (PRESENT(group_ref_)) THEN + CALL cxios_set_gridgroup_group_ref(gridgroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(mask_)) THEN + ALLOCATE(mask__tmp(size(mask_,1),size(mask_,2),size(mask_,3))) + mask__tmp=mask_ + CALL cxios_set_gridgroup_mask(gridgroup_hdl%daddr, mask__tmp,size(mask_,1),size(mask_,2),size(mask_,3)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_gridgroup_name(gridgroup_hdl%daddr, name_, len(name_)) + ENDIF + + + + END SUBROUTINE xios(set_gridgroup_attr_hdl_) + + SUBROUTINE xios(get_gridgroup_attr) & + ( gridgroup_id, axis_ref, description, domain_ref, group_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) :: gridgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::gridgroup_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL , OPTIONAL, INTENT(OUT) :: mask(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + + CALL xios(get_gridgroup_handle)(gridgroup_id,gridgroup_hdl) + CALL xios(get_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + END SUBROUTINE xios(get_gridgroup_attr) + + SUBROUTINE xios(get_gridgroup_attr_hdl) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) , INTENT(IN) :: gridgroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL , OPTIONAL, INTENT(OUT) :: mask(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask_tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + + CALL xios(get_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + END SUBROUTINE xios(get_gridgroup_attr_hdl) + + SUBROUTINE xios(get_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref_, description_, domain_ref_, group_ref_, mask_, name_ ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) , INTENT(IN) :: gridgroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: axis_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: description_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: domain_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref_ + LOGICAL , OPTIONAL, INTENT(OUT) :: mask_(:,:,:) + LOGICAL (KIND=C_BOOL) , ALLOCATABLE :: mask__tmp(:,:,:) + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + + IF (PRESENT(axis_ref_)) THEN + CALL cxios_get_gridgroup_axis_ref(gridgroup_hdl%daddr, axis_ref_, len(axis_ref_)) + ENDIF + + IF (PRESENT(description_)) THEN + CALL cxios_get_gridgroup_description(gridgroup_hdl%daddr, description_, len(description_)) + ENDIF + + IF (PRESENT(domain_ref_)) THEN + CALL cxios_get_gridgroup_domain_ref(gridgroup_hdl%daddr, domain_ref_, len(domain_ref_)) + ENDIF + + IF (PRESENT(group_ref_)) THEN + CALL cxios_get_gridgroup_group_ref(gridgroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(mask_)) THEN + ALLOCATE(mask__tmp(size(mask_,1),size(mask_,2),size(mask_,3))) + CALL cxios_get_gridgroup_mask(gridgroup_hdl%daddr, mask__tmp,size(mask_,1),size(mask_,2),size(mask_,3)) + mask_=mask__tmp + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_gridgroup_name(gridgroup_hdl%daddr, name_, len(name_)) + ENDIF + + + + END SUBROUTINE xios(get_gridgroup_attr_hdl_) + + SUBROUTINE xios(is_defined_gridgroup_attr) & + ( gridgroup_id, axis_ref, description, domain_ref, group_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) :: gridgroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::gridgroup_id + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref + LOGICAL(KIND=C_BOOL) :: axis_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: description + LOGICAL(KIND=C_BOOL) :: description_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL(KIND=C_BOOL) :: domain_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask + LOGICAL(KIND=C_BOOL) :: mask_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + + CALL xios(get_gridgroup_handle)(gridgroup_id,gridgroup_hdl) + CALL xios(is_defined_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + END SUBROUTINE xios(is_defined_gridgroup_attr) + + SUBROUTINE xios(is_defined_gridgroup_attr_hdl) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) , INTENT(IN) :: gridgroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref + LOGICAL(KIND=C_BOOL) :: axis_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: description + LOGICAL(KIND=C_BOOL) :: description_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref + LOGICAL(KIND=C_BOOL) :: domain_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask + LOGICAL(KIND=C_BOOL) :: mask_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + + CALL xios(is_defined_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref, description, domain_ref, group_ref, mask, name ) + + END SUBROUTINE xios(is_defined_gridgroup_attr_hdl) + + SUBROUTINE xios(is_defined_gridgroup_attr_hdl_) & + ( gridgroup_hdl, axis_ref_, description_, domain_ref_, group_ref_, mask_, name_ ) + + IMPLICIT NONE + TYPE(txios(gridgroup)) , INTENT(IN) :: gridgroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: axis_ref_ + LOGICAL(KIND=C_BOOL) :: axis_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: description_ + LOGICAL(KIND=C_BOOL) :: description__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: domain_ref_ + LOGICAL(KIND=C_BOOL) :: domain_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref_ + LOGICAL(KIND=C_BOOL) :: group_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: mask_ + LOGICAL(KIND=C_BOOL) :: mask__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + + IF (PRESENT(axis_ref_)) THEN + axis_ref__tmp=cxios_is_defined_gridgroup_axis_ref(gridgroup_hdl%daddr) + axis_ref_=axis_ref__tmp + ENDIF + + IF (PRESENT(description_)) THEN + description__tmp=cxios_is_defined_gridgroup_description(gridgroup_hdl%daddr) + description_=description__tmp + ENDIF + + IF (PRESENT(domain_ref_)) THEN + domain_ref__tmp=cxios_is_defined_gridgroup_domain_ref(gridgroup_hdl%daddr) + domain_ref_=domain_ref__tmp + ENDIF + + IF (PRESENT(group_ref_)) THEN + group_ref__tmp=cxios_is_defined_gridgroup_group_ref(gridgroup_hdl%daddr) + group_ref_=group_ref__tmp + ENDIF + + IF (PRESENT(mask_)) THEN + mask__tmp=cxios_is_defined_gridgroup_mask(gridgroup_hdl%daddr) + mask_=mask__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_gridgroup_name(gridgroup_hdl%daddr) + name_=name__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_gridgroup_attr_hdl_) + +END MODULE igridgroup_attr diff --git a/src/interface/fortran_attr/ivariable_attr.F90 b/src/interface/fortran_attr/ivariable_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..a7f81900f894184b83449deeead2b2d152cdeb13 --- /dev/null +++ b/src/interface/fortran_attr/ivariable_attr.F90 @@ -0,0 +1,165 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE ivariable_attr + USE, INTRINSIC :: ISO_C_BINDING + USE ivariable + USE variable_interface_attr + +CONTAINS + + SUBROUTINE xios(set_variable_attr) & + ( variable_id, name, type ) + + IMPLICIT NONE + TYPE(txios(variable)) :: variable_hdl + CHARACTER(LEN=*), INTENT(IN) ::variable_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + + CALL xios(get_variable_handle)(variable_id,variable_hdl) + CALL xios(set_variable_attr_hdl_) & + ( variable_hdl, name, type ) + + END SUBROUTINE xios(set_variable_attr) + + SUBROUTINE xios(set_variable_attr_hdl) & + ( variable_hdl, name, type ) + + IMPLICIT NONE + TYPE(txios(variable)) , INTENT(IN) :: variable_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + + CALL xios(set_variable_attr_hdl_) & + ( variable_hdl, name, type ) + + END SUBROUTINE xios(set_variable_attr_hdl) + + SUBROUTINE xios(set_variable_attr_hdl_) & + ( variable_hdl, name_, type_ ) + + IMPLICIT NONE + TYPE(txios(variable)) , INTENT(IN) :: variable_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type_ + + IF (PRESENT(name_)) THEN + CALL cxios_set_variable_name(variable_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_set_variable_type(variable_hdl%daddr, type_, len(type_)) + ENDIF + + + + END SUBROUTINE xios(set_variable_attr_hdl_) + + SUBROUTINE xios(get_variable_attr) & + ( variable_id, name, type ) + + IMPLICIT NONE + TYPE(txios(variable)) :: variable_hdl + CHARACTER(LEN=*), INTENT(IN) ::variable_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + + CALL xios(get_variable_handle)(variable_id,variable_hdl) + CALL xios(get_variable_attr_hdl_) & + ( variable_hdl, name, type ) + + END SUBROUTINE xios(get_variable_attr) + + SUBROUTINE xios(get_variable_attr_hdl) & + ( variable_hdl, name, type ) + + IMPLICIT NONE + TYPE(txios(variable)) , INTENT(IN) :: variable_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + + CALL xios(get_variable_attr_hdl_) & + ( variable_hdl, name, type ) + + END SUBROUTINE xios(get_variable_attr_hdl) + + SUBROUTINE xios(get_variable_attr_hdl_) & + ( variable_hdl, name_, type_ ) + + IMPLICIT NONE + TYPE(txios(variable)) , INTENT(IN) :: variable_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type_ + + IF (PRESENT(name_)) THEN + CALL cxios_get_variable_name(variable_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_get_variable_type(variable_hdl%daddr, type_, len(type_)) + ENDIF + + + + END SUBROUTINE xios(get_variable_attr_hdl_) + + SUBROUTINE xios(is_defined_variable_attr) & + ( variable_id, name, type ) + + IMPLICIT NONE + TYPE(txios(variable)) :: variable_hdl + CHARACTER(LEN=*), INTENT(IN) ::variable_id + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + + CALL xios(get_variable_handle)(variable_id,variable_hdl) + CALL xios(is_defined_variable_attr_hdl_) & + ( variable_hdl, name, type ) + + END SUBROUTINE xios(is_defined_variable_attr) + + SUBROUTINE xios(is_defined_variable_attr_hdl) & + ( variable_hdl, name, type ) + + IMPLICIT NONE + TYPE(txios(variable)) , INTENT(IN) :: variable_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + + CALL xios(is_defined_variable_attr_hdl_) & + ( variable_hdl, name, type ) + + END SUBROUTINE xios(is_defined_variable_attr_hdl) + + SUBROUTINE xios(is_defined_variable_attr_hdl_) & + ( variable_hdl, name_, type_ ) + + IMPLICIT NONE + TYPE(txios(variable)) , INTENT(IN) :: variable_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type_ + LOGICAL(KIND=C_BOOL) :: type__tmp + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_variable_name(variable_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(type_)) THEN + type__tmp=cxios_is_defined_variable_type(variable_hdl%daddr) + type_=type__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_variable_attr_hdl_) + +END MODULE ivariable_attr diff --git a/src/interface/fortran_attr/ivariablegroup_attr.F90 b/src/interface/fortran_attr/ivariablegroup_attr.F90 new file mode 100644 index 0000000000000000000000000000000000000000..9cf2318b0c39c66d2d90cbc80bfe6a978d39a535 --- /dev/null +++ b/src/interface/fortran_attr/ivariablegroup_attr.F90 @@ -0,0 +1,190 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * +#include "xios_fortran_prefix.hpp" + +MODULE ivariablegroup_attr + USE, INTRINSIC :: ISO_C_BINDING + USE ivariable + USE variablegroup_interface_attr + +CONTAINS + + SUBROUTINE xios(set_variablegroup_attr) & + ( variablegroup_id, group_ref, name, type ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) :: variablegroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::variablegroup_id + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + + CALL xios(get_variablegroup_handle)(variablegroup_id,variablegroup_hdl) + CALL xios(set_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref, name, type ) + + END SUBROUTINE xios(set_variablegroup_attr) + + SUBROUTINE xios(set_variablegroup_attr_hdl) & + ( variablegroup_hdl, group_ref, name, type ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) , INTENT(IN) :: variablegroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type + + CALL xios(set_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref, name, type ) + + END SUBROUTINE xios(set_variablegroup_attr_hdl) + + SUBROUTINE xios(set_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref_, name_, type_ ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) , INTENT(IN) :: variablegroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: group_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(IN) :: type_ + + IF (PRESENT(group_ref_)) THEN + CALL cxios_set_variablegroup_group_ref(variablegroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_set_variablegroup_name(variablegroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_set_variablegroup_type(variablegroup_hdl%daddr, type_, len(type_)) + ENDIF + + + + END SUBROUTINE xios(set_variablegroup_attr_hdl_) + + SUBROUTINE xios(get_variablegroup_attr) & + ( variablegroup_id, group_ref, name, type ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) :: variablegroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::variablegroup_id + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + + CALL xios(get_variablegroup_handle)(variablegroup_id,variablegroup_hdl) + CALL xios(get_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref, name, type ) + + END SUBROUTINE xios(get_variablegroup_attr) + + SUBROUTINE xios(get_variablegroup_attr_hdl) & + ( variablegroup_hdl, group_ref, name, type ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) , INTENT(IN) :: variablegroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type + + CALL xios(get_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref, name, type ) + + END SUBROUTINE xios(get_variablegroup_attr_hdl) + + SUBROUTINE xios(get_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref_, name_, type_ ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) , INTENT(IN) :: variablegroup_hdl + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: group_ref_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: name_ + CHARACTER(len = *) , OPTIONAL, INTENT(OUT) :: type_ + + IF (PRESENT(group_ref_)) THEN + CALL cxios_get_variablegroup_group_ref(variablegroup_hdl%daddr, group_ref_, len(group_ref_)) + ENDIF + + IF (PRESENT(name_)) THEN + CALL cxios_get_variablegroup_name(variablegroup_hdl%daddr, name_, len(name_)) + ENDIF + + IF (PRESENT(type_)) THEN + CALL cxios_get_variablegroup_type(variablegroup_hdl%daddr, type_, len(type_)) + ENDIF + + + + END SUBROUTINE xios(get_variablegroup_attr_hdl_) + + SUBROUTINE xios(is_defined_variablegroup_attr) & + ( variablegroup_id, group_ref, name, type ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) :: variablegroup_hdl + CHARACTER(LEN=*), INTENT(IN) ::variablegroup_id + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + + CALL xios(get_variablegroup_handle)(variablegroup_id,variablegroup_hdl) + CALL xios(is_defined_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref, name, type ) + + END SUBROUTINE xios(is_defined_variablegroup_attr) + + SUBROUTINE xios(is_defined_variablegroup_attr_hdl) & + ( variablegroup_hdl, group_ref, name, type ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) , INTENT(IN) :: variablegroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref + LOGICAL(KIND=C_BOOL) :: group_ref_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name + LOGICAL(KIND=C_BOOL) :: name_tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type + LOGICAL(KIND=C_BOOL) :: type_tmp + + CALL xios(is_defined_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref, name, type ) + + END SUBROUTINE xios(is_defined_variablegroup_attr_hdl) + + SUBROUTINE xios(is_defined_variablegroup_attr_hdl_) & + ( variablegroup_hdl, group_ref_, name_, type_ ) + + IMPLICIT NONE + TYPE(txios(variablegroup)) , INTENT(IN) :: variablegroup_hdl + LOGICAL, OPTIONAL, INTENT(OUT) :: group_ref_ + LOGICAL(KIND=C_BOOL) :: group_ref__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: name_ + LOGICAL(KIND=C_BOOL) :: name__tmp + LOGICAL, OPTIONAL, INTENT(OUT) :: type_ + LOGICAL(KIND=C_BOOL) :: type__tmp + + IF (PRESENT(group_ref_)) THEN + group_ref__tmp=cxios_is_defined_variablegroup_group_ref(variablegroup_hdl%daddr) + group_ref_=group_ref__tmp + ENDIF + + IF (PRESENT(name_)) THEN + name__tmp=cxios_is_defined_variablegroup_name(variablegroup_hdl%daddr) + name_=name__tmp + ENDIF + + IF (PRESENT(type_)) THEN + type__tmp=cxios_is_defined_variablegroup_type(variablegroup_hdl%daddr) + type_=type__tmp + ENDIF + + + + END SUBROUTINE xios(is_defined_variablegroup_attr_hdl_) + +END MODULE ivariablegroup_attr diff --git a/src/interface/fortran_attr/variable_interface_attr.f90 b/src/interface/fortran_attr/variable_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..de5a1904c7aa7278c8afdf2cb3b84b6188c3869e --- /dev/null +++ b/src/interface/fortran_attr/variable_interface_attr.f90 @@ -0,0 +1,55 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE variable_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_variable_name(variable_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variable_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_variable_name + + SUBROUTINE cxios_get_variable_name(variable_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variable_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_variable_name + + FUNCTION cxios_is_defined_variable_name(variable_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_variable_name + INTEGER (kind = C_INTPTR_T), VALUE :: variable_hdl + END FUNCTION cxios_is_defined_variable_name + + + SUBROUTINE cxios_set_variable_type(variable_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variable_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_set_variable_type + + SUBROUTINE cxios_get_variable_type(variable_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variable_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_get_variable_type + + FUNCTION cxios_is_defined_variable_type(variable_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_variable_type + INTEGER (kind = C_INTPTR_T), VALUE :: variable_hdl + END FUNCTION cxios_is_defined_variable_type + + + END INTERFACE + +END MODULE variable_interface_attr diff --git a/src/interface/fortran_attr/variablegroup_interface_attr.f90 b/src/interface/fortran_attr/variablegroup_interface_attr.f90 new file mode 100644 index 0000000000000000000000000000000000000000..495b48b7e28d3d9f6e3b13b5e07707286535635d --- /dev/null +++ b/src/interface/fortran_attr/variablegroup_interface_attr.f90 @@ -0,0 +1,76 @@ +! * ************************************************************************** * +! * Interface auto generated - do not modify * +! * ************************************************************************** * + +MODULE variablegroup_interface_attr + USE, INTRINSIC :: ISO_C_BINDING + + INTERFACE ! Do not call directly / interface FORTRAN 2003 <-> C99 + + + SUBROUTINE cxios_set_variablegroup_group_ref(variablegroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_set_variablegroup_group_ref + + SUBROUTINE cxios_get_variablegroup_group_ref(variablegroup_hdl, group_ref, group_ref_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: group_ref + INTEGER (kind = C_INT) , VALUE :: group_ref_size + END SUBROUTINE cxios_get_variablegroup_group_ref + + FUNCTION cxios_is_defined_variablegroup_group_ref(variablegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_variablegroup_group_ref + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + END FUNCTION cxios_is_defined_variablegroup_group_ref + + + SUBROUTINE cxios_set_variablegroup_name(variablegroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_set_variablegroup_name + + SUBROUTINE cxios_get_variablegroup_name(variablegroup_hdl, name, name_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: name + INTEGER (kind = C_INT) , VALUE :: name_size + END SUBROUTINE cxios_get_variablegroup_name + + FUNCTION cxios_is_defined_variablegroup_name(variablegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_variablegroup_name + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + END FUNCTION cxios_is_defined_variablegroup_name + + + SUBROUTINE cxios_set_variablegroup_type(variablegroup_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_set_variablegroup_type + + SUBROUTINE cxios_get_variablegroup_type(variablegroup_hdl, type, type_size) BIND(C) + USE ISO_C_BINDING + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + CHARACTER(kind = C_CHAR) , DIMENSION(*) :: type + INTEGER (kind = C_INT) , VALUE :: type_size + END SUBROUTINE cxios_get_variablegroup_type + + FUNCTION cxios_is_defined_variablegroup_type(variablegroup_hdl ) BIND(C) + USE ISO_C_BINDING + LOGICAL(kind=C_BOOL) :: cxios_is_defined_variablegroup_type + INTEGER (kind = C_INTPTR_T), VALUE :: variablegroup_hdl + END FUNCTION cxios_is_defined_variablegroup_type + + + END INTERFACE + +END MODULE variablegroup_interface_attr diff --git a/src/log.cpp b/src/log.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d0d56fa3201666231f8886adac5361dd55a54bce --- /dev/null +++ b/src/log.cpp @@ -0,0 +1,8 @@ +#include "log.hpp" + +namespace xios +{ + CLog info("info") ; + CLog report("report") ; + CLog error("error", cerr.rdbuf()) ; +} diff --git a/src/log.hpp b/src/log.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f31573a03532d5d42ba116b65d8d32f23007c12d --- /dev/null +++ b/src/log.hpp @@ -0,0 +1,59 @@ +#ifndef __XIOS_LOG_HPP__ +#define __XIOS_LOG_HPP__ + +#include +#include +#include + +namespace xios +{ + using namespace std ; + + class CLog : public ostream + { + public : + CLog(const string& name_, std::streambuf* sBuff = cout.rdbuf()) + : ostream(sBuff), level(0), name(name_), strBuf_(sBuff) {} + CLog& operator()(int l) + { + if (l<=level) + { + rdbuf(strBuf_); + *this<<"-> "< +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "memtrack.hpp" +#undef new // IMPORTANT! + +extern "C" +{ + void addr2line(const char *file_name, char** addr, int naddr) ; +} +/* ------------------------------------------------------------ */ +/* -------------------- namespace MemTrack -------------------- */ +/* ------------------------------------------------------------ */ + +namespace MemTrack +{ + + /* ------------------------------------------------------------ */ + /* --------------------- class BlockHeader -------------------- */ + /* ------------------------------------------------------------ */ + + class BlockHeader + { + private: // static member variables + static BlockHeader *ourFirstNode; + + private: // member variables + BlockHeader *myPrevNode; + BlockHeader *myNextNode; + size_t myRequestedSize; + char const *myFilename; + int myLineNum; + char const *myTypeName; + + size_t stackSize ; + void* stackArray[20] ; + + public: // members + BlockHeader(size_t requestedSize); + ~BlockHeader(); + + size_t GetRequestedSize() const { return myRequestedSize; } + char const *GetFilename() const { return myFilename; } + int GetLineNum() const { return myLineNum; } + char const *GetTypeName() const { return myTypeName; } + + void Stamp(char const *filename, int lineNum, char const *typeName); + void backTrace(void) ; + + static void AddNode(BlockHeader *node); + static void RemoveNode(BlockHeader *node); + static size_t CountBlocks(); + static void GetBlocks(BlockHeader **blockHeaderPP); + static bool TypeGreaterThan(BlockHeader *header1, BlockHeader *header2); + }; + + /* ---------------------------------------- BlockHeader static member variables */ + + BlockHeader *BlockHeader::ourFirstNode = NULL; + + /* ---------------------------------------- BlockHeader constructor */ + + BlockHeader::BlockHeader(size_t requestedSize) + { + myPrevNode = NULL; + myNextNode = NULL; + myRequestedSize = requestedSize; + myFilename = "[unknown]"; + myLineNum = 0; + myTypeName = "[unknown]"; + stackSize=backtrace(stackArray,20) ; + } + + /* ---------------------------------------- BlockHeader destructor */ + + BlockHeader::~BlockHeader() + { + } + + /* ---------------------------------------- BlockHeader Stamp */ + + void BlockHeader::Stamp(char const *filename, int lineNum, char const *typeName) + { + myFilename = filename; + myLineNum = lineNum; + myTypeName = typeName; + } + + void BlockHeader::backTrace(void) + { + +// oss<<"addr2line -C -f -i -s -e ../bin/test_client.exe " ; + char *addr ; + char buffer[20] ; + addr=buffer ; + for(int i=0;imyPrevNode == NULL); + assert(node->myNextNode == NULL); + + // If we have at least one node in the list ... + if (ourFirstNode != NULL) + { + // ... make the new node the first node's predecessor. + assert(ourFirstNode->myPrevNode == NULL); + ourFirstNode->myPrevNode = node; + } + + // Make the first node the new node's succesor. + node->myNextNode = ourFirstNode; + + // Make the new node the first node. + ourFirstNode = node; + } + + /* ---------------------------------------- BlockHeader RemoveNode */ + + void BlockHeader::RemoveNode(BlockHeader *node) + { + assert(node != NULL); + assert(ourFirstNode != NULL); + + // If target node is the first node in the list... + if (ourFirstNode == node) + { + // ... make the target node's successor the first node. + assert(ourFirstNode->myPrevNode == NULL); + ourFirstNode = node->myNextNode; + } + + // Link target node's predecessor, if any, to its successor. + if (node->myPrevNode != NULL) + { + node->myPrevNode->myNextNode = node->myNextNode; + } + + // Link target node's successor, if any, to its predecessor. + if (node->myNextNode != NULL) + { + node->myNextNode->myPrevNode = node->myPrevNode; + } + + // Clear target node's previous and next pointers. + node->myPrevNode = NULL; + node->myNextNode = NULL; + } + + /* ---------------------------------------- BlockHeader CountBlocks */ + + size_t BlockHeader::CountBlocks() + { + size_t count = 0; + BlockHeader *currNode = ourFirstNode; + while (currNode != NULL) + { + count++; + currNode = currNode->myNextNode; + } + return count; + } + + /* ---------------------------------------- BlockHeader GetBlocks */ + + void BlockHeader::GetBlocks(BlockHeader **blockHeaderPP) + { + BlockHeader *currNode = ourFirstNode; + while (currNode != NULL) + { + *blockHeaderPP = currNode; + blockHeaderPP++; + currNode = currNode->myNextNode; + } + } + + /* ---------------------------------------- BlockHeader TypeGreaterThan */ + + bool BlockHeader::TypeGreaterThan(BlockHeader *header1, BlockHeader *header2) + { + return (strcmp(header1->myTypeName, header2->myTypeName) > 0); + } + + /* ------------------------------------------------------------ */ + /* ---------------------- class Signature --------------------- */ + /* ------------------------------------------------------------ */ + + class Signature + { + private: // constants + static const unsigned int SIGNATURE1 = 0xCAFEBABE; + static const unsigned int SIGNATURE2 = 0xFACEFACE; + + private: // member variables + unsigned int mySignature1; + unsigned int mySignature2; + + public: // construction/destruction + Signature() : mySignature1(SIGNATURE1), mySignature2(SIGNATURE2) {}; + ~Signature() { mySignature1 = 0; mySignature2 = 0; } + + public: // static member functions + static bool IsValidSignature(const Signature *pProspectiveSignature) + { + try + { + if (pProspectiveSignature->mySignature1 != SIGNATURE1) return false; + if (pProspectiveSignature->mySignature2 != SIGNATURE2) return false; + return true; + } + catch (...) + { + return false; + } + } + }; + + /* ------------------------------------------------------------ */ + /* -------------------- address conversion -------------------- */ + /* ------------------------------------------------------------ */ + + /* We divide the memory blocks we allocate into two "chunks", the + * "prolog chunk" where we store information about the allocation, + * and the "user chunk" which we return to the caller to use. + */ + + /* ---------------------------------------- alignment */ + + const size_t ALIGNMENT = 4; + + /* If "value" (a memory size or offset) falls on an alignment boundary, + * then just return it. Otherwise return the smallest number larger + * than "value" that falls on an alignment boundary. + */ + + #define PAD_TO_ALIGNMENT_BOUNDARY(value) \ + ((value) + ((ALIGNMENT - ((value) % ALIGNMENT)) % ALIGNMENT)) + + /* ---------------------------------------- chunk structs */ + + /* We declare incomplete structures for each chunk, just to + * provide type safety. + */ + + struct PrologChunk; + struct UserChunk; + + /* ---------------------------------------- chunk sizes and offsets */ + + const size_t SIZE_BlockHeader = PAD_TO_ALIGNMENT_BOUNDARY(sizeof(BlockHeader)); + const size_t SIZE_Signature = PAD_TO_ALIGNMENT_BOUNDARY(sizeof(Signature)); + + const size_t OFFSET_BlockHeader = 0; + const size_t OFFSET_Signature = OFFSET_BlockHeader + SIZE_BlockHeader; + const size_t OFFSET_UserChunk = OFFSET_Signature + SIZE_Signature; + + const size_t SIZE_PrologChunk = OFFSET_UserChunk; + + /* ---------------------------------------- GetUserAddress */ + + static UserChunk *GetUserAddress(PrologChunk *pProlog) + { + char *pchProlog = reinterpret_cast(pProlog); + char *pchUser = pchProlog + OFFSET_UserChunk; + UserChunk *pUser = reinterpret_cast(pchUser); + return pUser; + } + + /* ---------------------------------------- GetPrologAddress */ + + static PrologChunk *GetPrologAddress(UserChunk *pUser) + { + char *pchUser = reinterpret_cast(pUser); + char *pchProlog = pchUser - OFFSET_UserChunk; + PrologChunk *pProlog = reinterpret_cast(pchProlog); + return pProlog; + } + + /* ---------------------------------------- GetHeaderAddress */ + + static BlockHeader *GetHeaderAddress(PrologChunk *pProlog) + { + char *pchProlog = reinterpret_cast(pProlog); + char *pchHeader = pchProlog + OFFSET_BlockHeader; + BlockHeader *pHeader = reinterpret_cast(pchHeader); + return pHeader; + } + + /* ---------------------------------------- GetSignatureAddress */ + + static Signature *GetSignatureAddress(PrologChunk *pProlog) + { + char *pchProlog = reinterpret_cast(pProlog); + char *pchSignature = pchProlog + OFFSET_Signature; + Signature *pSignature = reinterpret_cast(pchSignature); + return pSignature; + } + + /* ------------------------------------------------------------ */ + /* -------------- memory allocation and stamping -------------- */ + /* ------------------------------------------------------------ */ + + /* ---------------------------------------- TrackMalloc */ + + void *TrackMalloc(size_t size) + { + // Allocate the memory, including space for the prolog. + PrologChunk *pProlog = (PrologChunk *)malloc(SIZE_PrologChunk + size); + + // If the allocation failed, then return NULL. + if (pProlog == NULL) return NULL; + + // Use placement new to construct the block header in place. + BlockHeader *pBlockHeader = new (pProlog) BlockHeader(size); + + // Link the block header into the list of extant block headers. + BlockHeader::AddNode(pBlockHeader); + + // Use placement new to construct the signature in place. + Signature *pSignature = new (GetSignatureAddress(pProlog)) Signature; + + // Get the offset to the user chunk and return it. + UserChunk *pUser = GetUserAddress(pProlog); + + return pUser; + } + + /* ---------------------------------------- TrackFree */ + + void TrackFree(void *p) + { + // It's perfectly valid for "p" to be null; return if it is. + if (p == NULL) return; + + // Get the prolog address for this memory block. + UserChunk *pUser = reinterpret_cast(p); + PrologChunk *pProlog = GetPrologAddress(pUser); + + // Check the signature, and if it's invalid, return immediately. + Signature *pSignature = GetSignatureAddress(pProlog); + if (!Signature::IsValidSignature(pSignature)) return; + + // Destroy the signature. + pSignature->~Signature(); + pSignature = NULL; + + // Unlink the block header from the list and destroy it. + BlockHeader *pBlockHeader = GetHeaderAddress(pProlog); + BlockHeader::RemoveNode(pBlockHeader); + pBlockHeader->~BlockHeader(); + pBlockHeader = NULL; + + // Free the memory block. + free(pProlog); + } + + /* ---------------------------------------- TrackStamp */ + + void TrackStamp(void *p, const MemStamp &stamp, char const *typeName) + { + // Get the header and signature address for this pointer. + UserChunk *pUser = reinterpret_cast(p); + PrologChunk *pProlog = GetPrologAddress(pUser); + BlockHeader *pHeader = GetHeaderAddress(pProlog); + Signature *pSignature = GetSignatureAddress(pProlog); + + // If the signature is not valid, then return immediately. + if (!Signature::IsValidSignature(pSignature)) return; + + // "Stamp" the information onto the header. + pHeader->Stamp(stamp.filename, stamp.lineNum, typeName); + } + + /* ---------------------------------------- TrackDumpBlocks */ + + void TrackDumpBlocks() + { + // Get an array of pointers to all extant blocks. + size_t numBlocks = BlockHeader::CountBlocks(); + BlockHeader **ppBlockHeader = + (BlockHeader **)calloc(numBlocks, sizeof(*ppBlockHeader)); + BlockHeader::GetBlocks(ppBlockHeader); + + // Dump information about the memory blocks. + printf("\n"); + printf("=====================\n"); + printf("Current Memory Blocks\n"); + printf("=====================\n"); + printf("\n"); + for (size_t i = 0; i < numBlocks; i++) + { + BlockHeader *pBlockHeader = ppBlockHeader[i]; + char const *typeName = pBlockHeader->GetTypeName(); + size_t size = pBlockHeader->GetRequestedSize(); + char const *fileName = pBlockHeader->GetFilename(); + int lineNum = pBlockHeader->GetLineNum(); + printf("*** #%-6d %5d bytes %-50s\n", i, size, typeName); + printf("... %s:%d\n", fileName, lineNum); + pBlockHeader->backTrace(); + } + + // Clean up. + free(ppBlockHeader); + } + + /* ---------------------------------------- struct MemDigest */ + + struct MemDigest + { + char const *typeName; + int blockCount; + size_t totalSize; + + static bool TotalSizeGreaterThan(const MemDigest &md1, const MemDigest &md2) + { return md1.totalSize > md2.totalSize; } + }; + + + /* ---------------------------------------- SummarizeMemoryUsageForType */ + + static void SummarizeMemoryUsageForType( + MemDigest *pMemDigest, + BlockHeader **ppBlockHeader, + size_t startPost, + size_t endPost + ) + { + pMemDigest->typeName = ppBlockHeader[startPost]->GetTypeName(); + pMemDigest->blockCount = 0; + pMemDigest->totalSize = 0; + for (size_t i = startPost; i < endPost; i++) + { + pMemDigest->blockCount++; + pMemDigest->totalSize += ppBlockHeader[i]->GetRequestedSize(); + assert(strcmp(ppBlockHeader[i]->GetTypeName(), pMemDigest->typeName) == 0); + } + } + + /* ---------------------------------------- TrackListMemoryUsage */ + + void TrackListMemoryUsage() + { + // If there are no allocated blocks, then return now. + size_t numBlocks = BlockHeader::CountBlocks(); + if (numBlocks == 0) return; + + // Get an array of pointers to all extant blocks. + BlockHeader **ppBlockHeader = + (BlockHeader **)calloc(numBlocks, sizeof(*ppBlockHeader)); + BlockHeader::GetBlocks(ppBlockHeader); + + // Sort the blocks by type name. + std::sort( + ppBlockHeader, + ppBlockHeader + numBlocks, + BlockHeader::TypeGreaterThan + ); + + // Find out how many unique types we have. + size_t numUniqueTypes = 1; + for (size_t i = 1; i < numBlocks; i++) + { + char const *prevTypeName = ppBlockHeader[i - 1]->GetTypeName(); + char const *currTypeName = ppBlockHeader[i]->GetTypeName(); + if (strcmp(prevTypeName, currTypeName) != 0) numUniqueTypes++; + } + + // Create an array of "digests" summarizing memory usage by type. + size_t startPost = 0; + size_t uniqueTypeIndex = 0; + MemDigest *pMemDigestArray = + (MemDigest *)calloc(numUniqueTypes, sizeof(*pMemDigestArray)); + for (size_t i = 1; i <= numBlocks; i++) // yes, less than or *equal* to + { + char const *prevTypeName = ppBlockHeader[i - 1]->GetTypeName(); + char const *currTypeName = (i < numBlocks) ? ppBlockHeader[i]->GetTypeName() : ""; + if (strcmp(prevTypeName, currTypeName) != 0) + { + size_t endPost = i; + SummarizeMemoryUsageForType( + pMemDigestArray + uniqueTypeIndex, + ppBlockHeader, + startPost, + endPost + ); + startPost = endPost; + uniqueTypeIndex++; + } + } + assert(uniqueTypeIndex = numUniqueTypes); + + // Sort the digests by total memory usage. + std::sort( + pMemDigestArray, + pMemDigestArray + numUniqueTypes, + MemDigest::TotalSizeGreaterThan + ); + + // Compute the grand total memory usage. + size_t grandTotalNumBlocks = 0; + size_t grandTotalSize = 0; + for (size_t i = 0; i < numUniqueTypes; i++) + { + grandTotalNumBlocks += pMemDigestArray[i].blockCount; + grandTotalSize += pMemDigestArray[i].totalSize; + } + + // Dump the memory usage statistics. + printf("\n"); + printf("-----------------------\n"); + printf("Memory Usage Statistics\n"); + printf("-----------------------\n"); + printf("\n"); + printf("%-50s%5s %5s %7s %s \n", "allocated type", "blocks", "", "bytes", ""); + printf("%-50s%5s %5s %7s %s \n", "--------------", "------", "", "-----", ""); + + for (size_t i = 0; i < numUniqueTypes; i++) + { + MemDigest *pMD = pMemDigestArray + i; + size_t blockCount = pMD->blockCount; + double blockCountPct = 100.0 * blockCount / grandTotalNumBlocks; + size_t totalSize = pMD->totalSize; + double totalSizePct = 100.0 * totalSize / grandTotalSize; + + printf( + "%-50s %5d %5.1f%% %7d %5.1f%%\n", + pMD->typeName, + blockCount, + blockCountPct, + totalSize, + totalSizePct + ); + } + printf("%-50s %5s %5s %7s %s \n", "--------", "-----", "", "-------", ""); + printf("%-50s %5d %5s %7d %s \n", "[totals]", grandTotalNumBlocks, "", grandTotalSize, ""); + + // Clean up. + free(ppBlockHeader); + free(pMemDigestArray); + } + +} // namespace MemTrack + +/* ------------------------------------------------------------ */ +/* ---------------------- new and delete ---------------------- */ +/* ------------------------------------------------------------ */ + +/* ---------------------------------------- operator new */ + +void *operator new(size_t size) +{ + void *p = MemTrack::TrackMalloc(size); + if (p == NULL) throw std::bad_alloc(); + return p; +} + +/* ---------------------------------------- operator delete */ + +void operator delete(void *p) +{ + MemTrack::TrackFree(p); +} + +/* ---------------------------------------- operator new[] */ + +void *operator new[](size_t size) +{ + void *p = MemTrack::TrackMalloc(size); + if (p == NULL) throw std::bad_alloc(); + return p; +} + +/* ---------------------------------------- operator delete[] */ + +void operator delete[](void *p) +{ + MemTrack::TrackFree(p); +} + +#endif diff --git a/src/memtrack.hpp b/src/memtrack.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6e927957e54f7eef4ac6c71ce698a5406f544963 --- /dev/null +++ b/src/memtrack.hpp @@ -0,0 +1,81 @@ +#ifdef XIOS_MEMTRACK +/* +Copyright (c) 2002, 2008 Curtis Bartley +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 Curtis Bartley nor the names of any other +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 MemTrack_H_ +#define MemTrack_H_ + +#include +#include + +namespace MemTrack +{ + /* ---------------------------------------- class MemStamp */ + + class MemStamp + { + public: // member variables + char const * const filename; + int const lineNum; + public: // construction/destruction + MemStamp(char const *filename, int lineNum) + : filename(filename), lineNum(lineNum) { } + ~MemStamp() { } + }; + + /* ---------------------------------------- memory allocation and stamping prototypes */ + + void *TrackMalloc(size_t size); + void TrackFree(void *p); + void TrackStamp(void *p, const MemStamp &stamp, char const *typeName); + void TrackDumpBlocks(); + void TrackListMemoryUsage(); + + /* ---------------------------------------- operator * (MemStamp, ptr) */ + + template inline T *operator*(const MemStamp &stamp, T *p) + { + TrackStamp(p, stamp, typeid(T).name()); + return p; + } + +} // namespace MemTrack + +/* ---------------------------------------- new macro */ + +#define MEMTRACK_NEW MemTrack::MemStamp(__FILE__, __LINE__) * new +#define new MEMTRACK_NEW + +#endif // MemTrack_H_ + +#endif diff --git a/src/mpi.hpp b/src/mpi.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2850efaee269032bffc55680d61514deaa48b594 --- /dev/null +++ b/src/mpi.hpp @@ -0,0 +1,15 @@ +#ifndef __XIOS_MPI_HPP__ +#define __XIOS_MPI_HPP__ + +/* skip C++ Binding for mpich , intel MPI */ +#define MPICH_SKIP_MPICXX + +/* skip C++ Binding for SGI MPI library */ +#define MPI_NO_CPPBIND + +/* skip C++ Binding for OpenMPI */ +#define OMPI_SKIP_MPICXX + +#include + +#endif diff --git a/src/node/axis.cpp b/src/node/axis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36bc51b3df1a283ddab7fad4a62ab6ce2f493912 --- /dev/null +++ b/src/node/axis.cpp @@ -0,0 +1,87 @@ +#include "axis.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "message.hpp" +#include "type.hpp" +#include "xmlioserver_spl.hpp" + +namespace xios { + + /// ////////////////////// Définitions ////////////////////// /// + + CAxis::CAxis(void) + : CObjectTemplate() + , CAxisAttributes(), isChecked(false), relFiles() + { /* Ne rien faire de plus */ } + + CAxis::CAxis(const StdString & id) + : CObjectTemplate(id) + , CAxisAttributes(), isChecked(false), relFiles() + { /* Ne rien faire de plus */ } + + CAxis::~CAxis(void) + { /* Ne rien faire de plus */ } + + ///--------------------------------------------------------------- + + const std::set & CAxis::getRelFiles(void) const + { + return (this->relFiles); + } + + bool CAxis::IsWritten(const StdString & filename) const + { + return (this->relFiles.find(filename) != this->relFiles.end()); + } + + void CAxis::addRelFile(const StdString & filename) + { + this->relFiles.insert(filename); + } + + //---------------------------------------------------------------- + + StdString CAxis::GetName(void) { return (StdString("axis")); } + StdString CAxis::GetDefName(void){ return (CAxis::GetName()); } + ENodeType CAxis::GetType(void) { return (eAxis); } + + //---------------------------------------------------------------- + + void CAxis::checkAttributes(void) + { + if (this->isChecked) return; + if (this->size.isEmpty()) + ERROR("CAxis::checkAttributes(void)", + << "Attribute of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be specified"); + StdSize size = this->size.getValue(); + + StdSize zoom_begin,zoom_end, zoom_size; + + zoom_begin = (this->zoom_begin.isEmpty()) ? 1 : this->zoom_begin.getValue(); + zoom_end = (this->zoom_end.isEmpty()) ? size : this->zoom_end.getValue(); + zoom_size = (this->zoom_size.isEmpty()) ? size : this->zoom_size.getValue(); + + if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1; + if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1; + if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1; + + if ( (zoom_begin < 1) || (zoom_begin > size) || (zoom_end<1) || (zoom_end>size) || (zoom_size<1) || (zoom_size>size) || (zoom_begin>zoom_end)) + ERROR("CAxis::checkAttributes(void)", + << "One or more attributes among , , of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified"); + this->zoom_begin.setValue(zoom_begin); + this->zoom_end.setValue(zoom_end); + this->zoom_size.setValue(zoom_size); + + StdSize true_size = value.numElements(); + if (size != true_size) + ERROR("CAxis::checkAttributes(void)", + << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute"); + + this->isChecked = true; + } + + ///--------------------------------------------------------------- + +} // namespace xios diff --git a/src/node/axis.hpp b/src/node/axis.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8a3af62df7c2f1a991a3112cb4b122219c19f1e8 --- /dev/null +++ b/src/node/axis.hpp @@ -0,0 +1,87 @@ +#ifndef __XMLIO_CAxis__ +#define __XMLIO_CAxis__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "group_factory.hpp" + +#include "declare_group.hpp" +#include "attribute_array.hpp" +#include "attribute_enum.hpp" +#include "attribute_enum_impl.hpp" + +namespace xios { + + /// ////////////////////// Déclarations ////////////////////// /// + + class CAxisGroup; + class CAxisAttributes; + class CAxis; + + ///-------------------------------------------------------------- + + // Declare/Define CAxisAttribute + BEGIN_DECLARE_ATTRIBUTE_MAP(CAxis) +# include "axis_attribute.conf" + END_DECLARE_ATTRIBUTE_MAP(CAxis) + + ///-------------------------------------------------------------- + + class CAxis + : public CObjectTemplate + , public CAxisAttributes + { + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CAxisAttributes SuperClassAttribute; + + public : + + typedef CAxisAttributes RelAttributes; + typedef CAxisGroup RelGroup; + + /// Constructeurs /// + CAxis(void); + explicit CAxis(const StdString & id); + CAxis(const CAxis & axis); // Not implemented yet. + CAxis(const CAxis * const axis); // Not implemented yet. + + /// Accesseurs /// + const std::set & getRelFiles(void) const; + + /// Test /// + bool IsWritten(const StdString & filename) const; + + /// Mutateur /// + void addRelFile(const StdString & filename); + + /// Vérifications /// + void checkAttributes(void); + + /// Destructeur /// + virtual ~CAxis(void); + + /// Accesseurs statiques /// + static StdString GetName(void); + static StdString GetDefName(void); + + static ENodeType GetType(void); + + private : + + bool isChecked; + std::set relFiles; + + + }; // class CAxis + + ///-------------------------------------------------------------- + + // Declare/Define CAxisGroup and CAxisDefinition + DECLARE_GROUP(CAxis); + + ///-------------------------------------------------------------- + +} // namespace xios + +#endif // __XMLIO_CAxis__ diff --git a/src/node/context.cpp b/src/node/context.cpp new file mode 100644 index 0000000000000000000000000000000000000000..94142b59a2f46019a5570a569f86066ca50dd189 --- /dev/null +++ b/src/node/context.cpp @@ -0,0 +1,566 @@ +#include "context.hpp" +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "calendar_type.hpp" +#include "duration.hpp" + +#include "context_client.hpp" +#include "context_server.hpp" +#include "nc4_data_output.hpp" +#include "node_type.hpp" +#include "message.hpp" +#include "type.hpp" +#include "xmlioserver_spl.hpp" + +namespace xios { + + shared_ptr CContext::root ; + + /// ////////////////////// Définitions ////////////////////// /// + + CContext::CContext(void) + : CObjectTemplate(), CContextAttributes() + , calendar(),hasClient(false),hasServer(false) + { /* Ne rien faire de plus */ } + + CContext::CContext(const StdString & id) + : CObjectTemplate(id), CContextAttributes() + , calendar(),hasClient(false),hasServer(false) + { /* Ne rien faire de plus */ } + + CContext::~CContext(void) + { + if (hasClient) delete client ; + if (hasServer) delete server ; + } + + //---------------------------------------------------------------- + + StdString CContext::GetName(void) { return (StdString("context")); } + StdString CContext::GetDefName(void){ return (CContext::GetName()); } + ENodeType CContext::GetType(void) { return (eContext); } + + //---------------------------------------------------------------- + + CContextGroup* CContext::getRoot(void) + { + if (root.get()==NULL) root=shared_ptr(new CContextGroup(xml::CXMLNode::GetRootName())) ; + return root.get(); + } + + + //---------------------------------------------------------------- + + boost::shared_ptr CContext::getCalendar(void) const + { + return (this->calendar); + } + + //---------------------------------------------------------------- + + void CContext::setCalendar(boost::shared_ptr newCalendar) + { + this->calendar = newCalendar; + calendar_type.setValue(this->calendar->getId()); + start_date.setValue(this->calendar->getInitDate().toString()); + } + + //---------------------------------------------------------------- + + void CContext::solveCalendar(void) + { + if (this->calendar.get() != NULL) return; + if (calendar_type.isEmpty()) + ERROR(" CContext::solveCalendar(void)", + << "[ context id = " << this->getId() << " ] " + << "Impossible to define a calendar: the calendar type is missing."); + if (start_date.isEmpty()) + ERROR(" CContext::solveCalendar(void)", + << "[ context id = " << this->getId() << " ] " + << "Impossible to define a calendar: the start date is missing."); + if (timestep.isEmpty()) + ERROR(" CContext::solveCalendar(void)", + << "[ context id = " << this->getId() << " ] " + << "Impossible to define a calendar: the timestep is missing."); + +#define DECLARE_CALENDAR(MType , mtype) \ + if (calendar_type.getValue().compare(#mtype) == 0) \ + { \ + if (time_origin.isEmpty()) \ + this->calendar = boost::shared_ptr \ + (new C##MType##Calendar(start_date.getValue())); \ + else this->calendar = boost::shared_ptr \ + (new C##MType##Calendar(start_date.getValue(),time_origin.getValue())); \ + this->calendar->setTimeStep \ + (CDuration::FromString(this->timestep.getValue())); \ + return; \ + } +#include "calendar_type.conf" + + ERROR("CContext::solveCalendar(void)", + << "[ calendar_type = " << calendar_type.getValue() << " ] " + << "The calendar is not defined !"); + } + + //---------------------------------------------------------------- + + void CContext::parse(xml::CXMLNode & node) + { + CContext::SuperClass::parse(node); + + // PARSING POUR GESTION DES ENFANTS + xml::THashAttributes attributes = node.getAttributes(); + + if (attributes.end() != attributes.find("src")) + { + StdIFStream ifs ( attributes["src"].c_str() , StdIFStream::in ); + if ( (ifs.rdstate() & std::ifstream::failbit ) != 0 ) + ERROR("void CContext::parse(xml::CXMLNode & node)", + < file" ); + if (!ifs.good()) + ERROR("CContext::parse(xml::CXMLNode & node)", + << "[ filename = " << attributes["src"] << " ] Bad xml stream !"); + xml::CXMLParser::ParseInclude(ifs, attributes["src"], *this); + } + + if (node.getElementName().compare(CContext::GetName())) + DEBUG("Le noeud is wrong defined but will be considered as a context !"); + + if (!(node.goToChildElement())) + { + DEBUG("Le context ne contient pas d'enfant !"); + } + else + { + do { // Parcours des contextes pour traitement. + + StdString name = node.getElementName(); + attributes.clear(); + attributes = node.getAttributes(); + + if (attributes.end() != attributes.find("id")) + { DEBUG(<< "Definition node has an id," + << "it will not be taking account !"); } + +#define DECLARE_NODE(Name_, name_) \ + if (name.compare(C##Name_##Definition::GetDefName()) == 0) \ + { C##Name_##Definition::create(C##Name_##Definition::GetDefName()) -> parse(node) ; continue; } +#define DECLARE_NODE_PAR(Name_, name_) +#include "node_type.conf" + + DEBUG(<< "The element \'" << name + << "\' in the context \'" << CContext::getCurrent()->getId() + << "\' is not a definition !"); + + } while (node.goToNextElement()); + + node.goToParentElement(); // Retour au parent + } + } + + //---------------------------------------------------------------- + + void CContext::ShowTree(StdOStream & out) + { + StdString currentContextId = CContext::getCurrent() -> getId() ; + std::vector def_vector = + CContext::getRoot()->getChildList(); + std::vector::iterator + it = def_vector.begin(), end = def_vector.end(); + + out << "" << std::endl; + out << "<" << xml::CXMLNode::GetRootName() << " >" << std::endl; + + for (; it != end; it++) + { + CContext* context = *it; + CContext::setCurrent(context->getId()); + out << *context << std::endl; + } + + out << "" << std::endl; + CContext::setCurrent(currentContextId); + } + + + //---------------------------------------------------------------- + + StdString CContext::toString(void) const + { + StdOStringStream oss; + oss << "<" << CContext::GetName() + << " id=\"" << this->getId() << "\" " + << SuperClassAttribute::toString() << ">" << std::endl; + if (!this->hasChild()) + { + //oss << "" << std::endl; // fait planter l'incrémentation + } + else + { + +#define DECLARE_NODE(Name_, name_) \ + if (C##Name_##Definition::has(C##Name_##Definition::GetDefName())) \ + oss << * C##Name_##Definition::get(C##Name_##Definition::GetDefName()) << std::endl; +#define DECLARE_NODE_PAR(Name_, name_) +#include "node_type.conf" + + } + + oss << ""; + + return (oss.str()); + } + + //---------------------------------------------------------------- + + void CContext::solveDescInheritance(bool apply, const CAttributeMap * const UNUSED(parent)) + { +#define DECLARE_NODE(Name_, name_) \ + if (C##Name_##Definition::has(C##Name_##Definition::GetDefName())) \ + C##Name_##Definition::get(C##Name_##Definition::GetDefName())->solveDescInheritance(apply); +#define DECLARE_NODE_PAR(Name_, name_) +#include "node_type.conf" + } + + //---------------------------------------------------------------- + + bool CContext::hasChild(void) const + { + return ( +#define DECLARE_NODE(Name_, name_) \ + C##Name_##Definition::has(C##Name_##Definition::GetDefName()) || +#define DECLARE_NODE_PAR(Name_, name_) +#include "node_type.conf" + false); +} + + //---------------------------------------------------------------- + + void CContext::solveFieldRefInheritance(bool apply) + { + if (!this->hasId()) return; + vector allField = CField::getAll() ; +// = CObjectTemplate::GetAllVectobject(this->getId()); + std::vector::iterator + it = allField.begin(), end = allField.end(); + + for (; it != end; it++) + { + CField* field = *it; + field->solveRefInheritance(apply); + } + } + + //---------------------------------------------------------------- + + void CContext::CleanTree(void) + { +#define DECLARE_NODE(Name_, name_) C##Name_##Group::ClearAllAttributes(); +#define DECLARE_NODE_PAR(Name_, name_) +#include "node_type.conf" + } + ///--------------------------------------------------------------- + + void CContext::initClient(MPI_Comm intraComm, MPI_Comm interComm) + { + hasClient=true ; + client = new CContextClient(this,intraComm, interComm) ; + } + + bool CContext::isInitialized(void) + { + return hasClient ; + } + + void CContext::initServer(MPI_Comm intraComm,MPI_Comm interComm) + { + hasServer=true ; + server = new CContextServer(this,intraComm,interComm) ; + } + + bool CContext::eventLoop(void) + { + return server->eventLoop() ; + } + + void CContext::finalize(void) + { + if (hasClient && !hasServer) + { + client->finalize() ; + } + if (hasServer) + { + closeAllFile() ; + } + } + + + + + void CContext::closeDefinition(void) + { + if (hasClient && !hasServer) sendCloseDefinition() ; + + solveCalendar(); + + // Résolution des héritages pour le context actuel. + this->solveAllInheritance(); + + //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers à sortir. + this->findEnabledFiles(); + + + this->processEnabledFiles() ; + +/* + //Recherche des champs à sortir (enable à true + niveau de sortie correct) + // pour chaque fichier précédemment listé. + this->findAllEnabledFields(); + + // Résolution des références de grilles pour chacun des champs. + this->solveAllGridRef(); + + // Traitement des opérations. + this->solveAllOperation(); + + // Traitement des expressions. + this->solveAllExpression(); +*/ + // Nettoyage de l'arborescence + CleanTree(); + if (hasClient) sendCreateFileHeader() ; + } + + void CContext::findAllEnabledFields(void) + { + for (unsigned int i = 0; i < this->enabledFiles.size(); i++) + (void)this->enabledFiles[i]->getEnabledFields(); + } + + void CContext::processEnabledFiles(void) + { + for (unsigned int i = 0; i < this->enabledFiles.size(); i++) + this->enabledFiles[i]->processEnabledFile(); + } + + + void CContext::solveAllGridRef(void) + { + for (unsigned int i = 0; i < this->enabledFiles.size(); i++) + this->enabledFiles[i]->solveEFGridRef(); + } + + void CContext::solveAllOperation(void) + { + for (unsigned int i = 0; i < this->enabledFiles.size(); i++) + this->enabledFiles[i]->solveEFOperation(); + } + + void CContext::solveAllExpression(void) + { + for (unsigned int i = 0; i < this->enabledFiles.size(); i++) + this->enabledFiles[i]->solveEFExpression(); + } + + void CContext::solveAllInheritance(bool apply) + { + // Résolution des héritages descendants (càd des héritages de groupes) + // pour chacun des contextes. + solveDescInheritance(apply); + + // Résolution des héritages par référence au niveau des fichiers. + const vector allFiles=CFile::getAll() ; + + for (unsigned int i = 0; i < allFiles.size(); i++) + allFiles[i]->solveFieldRefInheritance(apply); + } + + void CContext::findEnabledFiles(void) + { + const std::vector allFiles = CFile::getAll(); + + for (unsigned int i = 0; i < allFiles.size(); i++) + if (!allFiles[i]->enabled.isEmpty()) // Si l'attribut 'enabled' est défini. + { + if (allFiles[i]->enabled.getValue()) // Si l'attribut 'enabled' est fixé à vrai. + enabledFiles.push_back(allFiles[i]); + } + else enabledFiles.push_back(allFiles[i]); // otherwise true by default + + + if (enabledFiles.size() == 0) + DEBUG(<<"Aucun fichier ne va être sorti dans le contexte nommé \"" + << getId() << "\" !"); + } + + void CContext::closeAllFile(void) + { + std::vector::const_iterator + it = this->enabledFiles.begin(), end = this->enabledFiles.end(); + + for (; it != end; it++) + { + info(30)<<"Closing File : "<<(*it)->getId()<close(); + } + } + + bool CContext::dispatchEvent(CEventServer& event) + { + + if (SuperClass::dispatchEvent(event)) return true ; + else + { + switch(event.type) + { + case EVENT_ID_CLOSE_DEFINITION : + recvCloseDefinition(event) ; + return true ; + break ; + case EVENT_ID_UPDATE_CALENDAR : + recvUpdateCalendar(event) ; + return true ; + break ; + case EVENT_ID_CREATE_FILE_HEADER : + recvCreateFileHeader(event) ; + return true ; + break ; + default : + ERROR("bool CContext::dispatchEvent(CEventServer& event)", + <<"Unknown Event") ; + return false ; + } + } + } + + void CContext::sendCloseDefinition(void) + { + + CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + event.push(client->getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + void CContext::recvCloseDefinition(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + get(id)->closeDefinition() ; + } + + void CContext::sendUpdateCalendar(int step) + { + if (!hasServer) + { + CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId()<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + } + + void CContext::recvUpdateCalendar(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + get(id)->recvUpdateCalendar(*buffer) ; + } + + void CContext::recvUpdateCalendar(CBufferIn& buffer) + { + int step ; + buffer>>step ; + updateCalendar(step) ; + } + + void CContext::sendCreateFileHeader(void) + { + + CEventClient event(getType(),EVENT_ID_CREATE_FILE_HEADER) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + event.push(client->getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + void CContext::recvCreateFileHeader(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + get(id)->recvCreateFileHeader(*buffer) ; + } + + void CContext::recvCreateFileHeader(CBufferIn& buffer) + { + createFileHeader() ; + } + + void CContext::updateCalendar(int step) + { + info(50)<<"updateCalendar : before : "<getCurrentDate()<update(step) ; + info(50)<<"updateCalendar : after : "<getCurrentDate()<::const_iterator it ; + + for (it=enabledFiles.begin(); it != enabledFiles.end(); it++) + { + (*it)->initFile(); + } + } + + CContext* CContext::getCurrent(void) + { + return CObjectFactory::GetObject(CObjectFactory::GetCurrentContextId()).get() ; + } + + void CContext::setCurrent(const string& id) + { + CObjectFactory::SetCurrentContextId(id); + CGroupFactory::SetCurrentContextId(id); + } + + CContext* CContext::create(const StdString& id) + { + CContext::setCurrent(id) ; + + bool hasctxt = CContext::has(id); + CContext* context = CObjectFactory::CreateObject(id).get(); + getRoot() ; + if (!hasctxt) CGroupFactory::AddChild(root, context->getShared()); + +#define DECLARE_NODE(Name_, name_) \ + C##Name_##Definition::create(C##Name_##Definition::GetDefName()); +#define DECLARE_NODE_PAR(Name_, name_) +#include "node_type.conf" + + return (context); + } +} // namespace xios diff --git a/src/node/context.hpp b/src/node/context.hpp new file mode 100644 index 0000000000000000000000000000000000000000..726012a04d121fb33c0aeff0e1bc4aca88361964 --- /dev/null +++ b/src/node/context.hpp @@ -0,0 +1,165 @@ +#ifndef __XMLIO_CContext__ +#define __XMLIO_CContext__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +//#include "node_type.hpp" +#include "calendar.hpp" + +#include "declare_group.hpp" +//#include "context_client.hpp" +//#include "context_server.hpp" +#include "data_output.hpp" + +#include "mpi.hpp" + + +namespace xios { + class CContextClient ; + class CContextServer ; + + + /// ////////////////////// Déclarations ////////////////////// /// + class CContextGroup; + class CContextAttributes; + class CContext; + class CFile; + ///-------------------------------------------------------------- + + // Declare/Define CFileAttribute + BEGIN_DECLARE_ATTRIBUTE_MAP(CContext) +# include "context_attribute.conf" + END_DECLARE_ATTRIBUTE_MAP(CContext) + + ///-------------------------------------------------------------- + + class CContext + : public CObjectTemplate + , public CContextAttributes + { + public : + enum EEventId + { + EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR, + EVENT_ID_CREATE_FILE_HEADER,EVENT_ID_CONTEXT_FINALIZE + } ; + + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CContextAttributes SuperClassAttribute; + + public : + + typedef CContextAttributes RelAttributes; + typedef CContext RelGroup; + + //--------------------------------------------------------- + + public : + + /// Constructeurs /// + CContext(void); + explicit CContext(const StdString & id); + CContext(const CContext & context); // Not implemented yet. + CContext(const CContext * const context); // Not implemented yet. + + /// Destructeur /// + virtual ~CContext(void); + + //--------------------------------------------------------- + + public : + + /// Mutateurs /// + void setCalendar(boost::shared_ptr newCalendar); + + /// Accesseurs /// + boost::shared_ptr getCalendar(void) const; + + /// Accesseurs statiques /// + static StdString GetName(void); + static StdString GetDefName(void); + static ENodeType GetType(void); + + static CContextGroup* GetContextGroup(void); + + public : + + /// Traitements /// + virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0); + void solveFieldRefInheritance(bool apply); + void solveCalendar(void); + + /// Autres méthodes statiques /// + static void ShowTree(StdOStream & out = std::clog); + static void CleanTree(void); + + /// Test /// + virtual bool hasChild(void) const; + + bool eventLoop(void) ; + bool serverLoop(void) ; + void clientLoop(void) ; + void initServer(MPI_Comm intraComm, MPI_Comm interComm) ; + void initClient(MPI_Comm intraComm, MPI_Comm interComm) ; + bool isInitialized(void) ; + CContextServer* server ; + CContextClient* client ; + bool hasClient ; + bool hasServer ; + void finalize(void) ; + void closeDefinition(void) ; + void findAllEnabledFields(void); + void processEnabledFiles(void) ; + void solveAllGridRef(void); + void solveAllOperation(void); + void solveAllExpression(void); + void solveAllInheritance(bool apply=true) ; + void findEnabledFiles(void); + void closeAllFile(void) ; + void updateCalendar(int step) ; + void createFileHeader(void ) ; + // dispatch event + static bool dispatchEvent(CEventServer& event) ; + void sendCloseDefinition(void) ; + void sendUpdateCalendar(int step) ; + void sendCreateFileHeader(void) ; + static void recvUpdateCalendar(CEventServer& event) ; + void recvUpdateCalendar(CBufferIn& buffer) ; + static void recvCloseDefinition(CEventServer& event) ; + static void recvCreateFileHeader(CEventServer& event) ; + void recvCreateFileHeader(CBufferIn& buffer) ; + static CContext* getCurrent(void) ; + static CContextGroup* getRoot(void) ; + static void setCurrent(const string& id) ; + static CContext* create(const string& id = "") ; + + public : + + /// Autres /// + virtual void parse(xml::CXMLNode & node); + + virtual StdString toString(void) const; +// virtual void toBinary (StdOStream & os) const; +// virtual void fromBinary(StdIStream & is); + + public : + + boost::shared_ptr calendar; + + std::vector enabledFiles; + static shared_ptr root ; + + + }; // class CContext + + ///-------------------------------------------------------------- + + // Declare/Define CContextGroup and CContextDefinition + DECLARE_GROUP(CContext); + + ///-------------------------------------------------------------- + +} // namespace xios + +#endif // __XMLIO_CContext__ diff --git a/src/node/domain.cpp b/src/node/domain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f37ab229651ab41486443b4d718633eab6b2017f --- /dev/null +++ b/src/node/domain.cpp @@ -0,0 +1,890 @@ +#include "domain.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "xmlioserver_spl.hpp" +#include "event_client.hpp" +#include "event_server.hpp" +#include "buffer_in.hpp" +#include "message.hpp" +#include "type.hpp" +#include "context.hpp" +#include "context_client.hpp" +#include "array_new.hpp" + +namespace xios { + + /// ////////////////////// Définitions ////////////////////// /// + + CDomain::CDomain(void) + : CObjectTemplate(), CDomainAttributes() + , isChecked(false), relFiles() + { /* Ne rien faire de plus */ } + + CDomain::CDomain(const StdString & id) + : CObjectTemplate(id), CDomainAttributes() + , isChecked(false), relFiles() + { /* Ne rien faire de plus */ } + + CDomain::~CDomain(void) + { + } + + ///--------------------------------------------------------------- + + const std::set & CDomain::getRelFiles(void) const + { + return (this->relFiles); + } + + //---------------------------------------------------------------- + + bool CDomain::hasZoom(void) const + { + return ((this->zoom_ni.getValue() != this->ni_glo.getValue()) && + (this->zoom_nj.getValue() != this->nj_glo.getValue())); + } + + //---------------------------------------------------------------- + + bool CDomain::isEmpty(void) const + { + return ((this->zoom_ni_srv == 0) || + (this->zoom_nj_srv == 0)); + } + + //---------------------------------------------------------------- + + bool CDomain::IsWritten(const StdString & filename) const + { + return (this->relFiles.find(filename) != this->relFiles.end()); + } + + //---------------------------------------------------------------- + + void CDomain::addRelFile(const StdString & filename) + { + this->relFiles.insert(filename); + } + + + StdString CDomain::GetName(void) { return (StdString("domain")); } + StdString CDomain::GetDefName(void){ return (CDomain::GetName()); } + ENodeType CDomain::GetType(void) { return (eDomain); } + + //---------------------------------------------------------------- + + void CDomain::checkDomain(void) + { + if (!type.isEmpty() && type==type_attr::unstructured) + { + if (ni_glo.isEmpty() || ni_glo <= 0 ) + { + ERROR("CDomain::checkAttributes(void)", + << "[ Id = " << this->getId() << " ] " + << "The global domain is badly defined," + << " check the \'ni_glo\' value !") + } + nj_glo=ni_glo ; + ni_glo=1 ; + if (!ni.isEmpty()) nj=ni ; + if (!ibegin.isEmpty()) jbegin=ibegin ; + if (!iend.isEmpty()) jend=iend ; + if (!i_index.isEmpty()) + { + j_index.resize(1,nj) ; + for(int i=0;i mask_tmp(nj,1) ; + mask_tmp = mask ; + mask.resize(1,nj) ; + for(int j=0;j iend.getValue() || + ibegin.getValue() < 1 || iend.getValue() > ni_glo.getValue()) + { + + ERROR("CDomain::checkAttributes(void)", + << "[ Id = " << this->getId() << " ] " + << "Local domain is wrong defined," + << " Check the value : ni, ni_glo, ibegin, iend") ; + } + } + + //---------------------------------------------------------------- + + void CDomain::checkLocalJDomain(void) + { + if (!nj.isEmpty() && !jbegin.isEmpty() && jend.isEmpty()) + jend.setValue(jbegin.getValue() + nj.getValue() - 1) ; + + else if (!nj.isEmpty() && !jend.isEmpty() && jbegin.isEmpty()) + jbegin.setValue( - nj.getValue() + jend.getValue() + 1) ; + + else if (!jbegin.isEmpty() && !jend.isEmpty() && nj.isEmpty()) + nj.setValue(jend.getValue() - jbegin.getValue() + 1) ; + + else if (!jbegin.isEmpty() && !jend.isEmpty() && !nj.isEmpty() ) + { + if (jend.getValue() != jbegin.getValue() + nj.getValue() - 1) + ERROR("CDomain::checkAttributes(void)", + << "The domain is wrong defined," + << " iend is different of (jbegin + nj - 1) !") ; + } + else + { + ERROR("CDomain::checkAttributes(void)", + << "The domain is wrong defined," + << " 2 values from jend, jbegin, nj must be defined !") ; + } + + if (nj.getValue() < 0 || jbegin.getValue() > jend.getValue() || + jbegin.getValue() < 1 || jend.getValue() > nj_glo.getValue()) + ERROR("CDomain::checkAttributes(void)", + << "Domain is wrong defined," + << " Check the values : nj, nj_glo, jbegin, jend") ; + + ibegin_client=ibegin ; iend_client=iend ; ni_client=ni ; + jbegin_client=jbegin ; jend_client=jend ; nj_client=nj ; + } + + //---------------------------------------------------------------- + + void CDomain::checkMask(void) + { + using namespace std; + + int ibegin_mask = 0, + jbegin_mask = 0, + iend_mask = iend.getValue() - ibegin.getValue(), + jend_mask = jend.getValue() - jbegin.getValue(); + + if (!zoom_ibegin.isEmpty()) + { + int zoom_iend = zoom_ibegin.getValue() + zoom_ni.getValue() - 1; + int zoom_jend = zoom_jbegin.getValue() + zoom_nj.getValue() - 1; + + ibegin_mask = max (ibegin.getValue(), zoom_ibegin.getValue()); + jbegin_mask = max (jbegin.getValue(), zoom_jbegin.getValue()); + iend_mask = min (iend.getValue(), zoom_iend); + jend_mask = min (jend.getValue(), zoom_jend); + + ibegin_mask -= ibegin.getValue(); + jbegin_mask -= jbegin.getValue(); + iend_mask -= ibegin.getValue(); + jend_mask -= jbegin.getValue(); + } + + + if (!mask.isEmpty()) + { + if ((mask.extent(0) != ni) || + (mask.extent(1) != nj)) + ERROR("CDomain::checkAttributes(void)", + <<"the mask has not the same size than the local domain"< iend_mask && + j < jbegin_mask && j > jend_mask ) + mask(i,j) = false; + } + } + } + else // (!mask.hasValue()) + { // Si aucun masque n'est défini, + // on en crée un nouveau qui valide l'intégralité du domaine. + mask.resize(ni,nj) ; + for (int i = 0; i < ni.getValue(); i++) + { + for (int j = 0; j < nj.getValue(); j++) + { + if (i >= ibegin_mask && i <= iend_mask && + j >= jbegin_mask && j <= jend_mask ) + mask(i,j) = true; + else mask(i,j) = false; + } + } + } + } + + + //---------------------------------------------------------------- + + void CDomain::checkDomainData(void) + { + if (!data_dim.isEmpty() && + !(data_dim.getValue() == 1 || data_dim.getValue() == 2)) + { + ERROR("CDomain::checkAttributes(void)", + << "Data dimension incompatible (must be 1 or 2) !") ; + } + else if (data_dim.isEmpty()) + { + ERROR("CDomain::checkAttributes(void)", + << "Data dimension undefined !") ; + } + + if (data_ibegin.isEmpty()) + data_ibegin.setValue(0) ; + if (data_jbegin.isEmpty() && (data_dim.getValue() == 2)) + data_jbegin.setValue(0) ; + + if (!data_ni.isEmpty() && (data_ni.getValue() <= 0)) + { + ERROR("CDomain::checkAttributes(void)", + << "Data dimension is negative (data_ni).") ; + } + else if (data_ni.isEmpty()) + { + data_ni.setValue((data_dim.getValue() == 1) + ? (ni.getValue() * nj.getValue()) + : ni.getValue()); + } + + if (data_dim.getValue() == 2) + { + if (!data_nj.isEmpty() && (data_nj.getValue() <= 0) ) + { + ERROR("CDomain::checkAttributes(void)", + << "Data dimension is negative (data_nj).") ; + } + else if (data_nj.isEmpty()) + data_nj.setValue(nj.getValue()) ; + } + + } + + //---------------------------------------------------------------- + + void CDomain::checkCompression(void) + { + if (!data_i_index.isEmpty()) + { + int ssize = data_i_index.numElements(); + if (!data_n_index.isEmpty() && + (data_n_index.getValue() != ssize)) + { + ERROR("CDomain::checkAttributes(void)", + <<"Dimension data_i_index incompatible with data_n_index.") ; + } + else if (data_n_index.isEmpty()) + data_n_index.setValue(ssize) ; + + if (data_dim.getValue() == 2) + { + if (!data_j_index.isEmpty() && + (data_j_index.numElements() != data_i_index.numElements())) + { + ERROR("CDomain::checkAttributes(void)", + <<"Dimension data_j_index incompatible with data_i_index.") ; + } + else if (data_j_index.isEmpty()) + { + ERROR("CDomain::checkAttributes(void)", + <<"data_j_index must be defined !") ; + } + } + } + else + { + if (!data_n_index.isEmpty() || + ((data_dim.getValue() == 2) && (!data_j_index.isEmpty()))) + ERROR("CDomain::checkAttributes(void)", << "data_i_index undefined") ; + } + + if (data_n_index.isEmpty()) + { // -> bloc re-vérifié OK + if (data_dim.getValue() == 1) + { + const int dni = data_ni.getValue(); + data_i_index.resize(dni) ; + data_n_index.setValue(dni); + for (int i = 0; i < dni; i++) data_i_index(i) = i+1 ; + } + else // (data_dim == 2) + { + const int dni = data_ni.getValue() * data_nj.getValue(); + data_i_index.resize(dni) ; + data_j_index.resize(dni) ; + + data_n_index.setValue(dni); + + for(int count = 0, j = 0; j < data_nj.getValue(); j++) + { + for(int i = 0; i < data_ni.getValue(); i++, count++) + { + data_i_index(count) = i+1 ; + data_j_index(count) = j+1 ; + } + } + } + } + } + + //---------------------------------------------------------------- + + void CDomain::completeLonLatClient(void) + { + int i,j,k ; + CArray lonvalue_temp(ni*nj) ; + CArray latvalue_temp(ni*nj) ; + CArray bounds_lon_temp(nvertex,ni*nj) ; + CArray bounds_lat_temp(nvertex,ni*nj) ; + + if (type.isEmpty()) + { + if ( lonvalue.numElements() == ni*nj && latvalue.numElements() == ni*nj ) + { + type.setValue(type_attr::curvilinear) ; + isCurvilinear=true ; + } + else if ( lonvalue.numElements() == ni && latvalue.numElements() == nj ) + { + type.setValue(type_attr::regular) ; + isCurvilinear=false ; + } + else ERROR("void CDomain::completeLonLatClient(void)",<<"the grid is nor curvilinear, nor cartesian, because the size of longitude and latitude array is not coherent with the domain size"<zoom_ni.isEmpty() || !this->zoom_nj.isEmpty() || + !this->zoom_ibegin.isEmpty() || !this->zoom_jbegin.isEmpty()) + { + if (this->zoom_ni.isEmpty() || this->zoom_nj.isEmpty() || + this->zoom_ibegin.isEmpty() || this->zoom_jbegin.isEmpty()) + { + ERROR("CDomain::checkZoom(void)", + <<"if one of zoom attributes is defined then all zoom attributes must be defined") ; + } + else + { + int zoom_iend = zoom_ibegin + zoom_ni - 1; + int zoom_jend = zoom_jbegin + zoom_nj - 1; + + if (zoom_ibegin < 1 || zoom_jbegin < 1 || zoom_iend > ni_glo || zoom_jend > nj_glo) + ERROR("CDomain::checkZoom(void)", + << "Zoom is wrong defined," + << " Check the values : zoom_ni, zoom_nj, zoom_ibegin, zoom_jbegin") ; + } + } + else + { + zoom_ni = ni_glo; + zoom_nj = nj_glo; + zoom_ibegin = 1; + zoom_jbegin = 1; + } + + // compute client zoom indices + + int zoom_iend=zoom_ibegin+zoom_ni-1 ; + zoom_ibegin_client = ibegin_client > zoom_ibegin ? ibegin_client : zoom_ibegin ; + zoom_iend_client = iend_client < zoom_iend ? iend_client : zoom_iend ; + zoom_ni_client=zoom_iend_client-zoom_ibegin_client+1 ; + if (zoom_ni_client<0) zoom_ni_client=0 ; + + + int zoom_jend=zoom_jbegin+zoom_nj-1 ; + zoom_jbegin_client = jbegin_client > zoom_jbegin ? jbegin_client : zoom_jbegin ; + zoom_jend_client = jend_client < zoom_jend ? jend_client : zoom_jend ; + zoom_nj_client=zoom_jend_client-zoom_jbegin_client+1 ; + if (zoom_nj_client<0) zoom_nj_client=0 ; + + } + + void CDomain::checkBounds(void) + { + if (!nvertex.isEmpty() && !bounds_lon.isEmpty() && !bounds_lat.isEmpty()) + { + hasBounds=true ; + + } + else + { + hasBounds=false; + nvertex=0 ; + } + } + + //---------------------------------------------------------------- + + void CDomain::checkAttributes(void) + { + if (this->isChecked) return; + CContext* context=CContext::getCurrent() ; + + this->checkDomain(); + this->checkZoom(); + this->checkBounds(); + + if (context->hasClient) + { // Côté client uniquement + this->checkMask(); + this->checkDomainData(); + this->checkCompression(); + this->completeLonLatClient(); + } + else + { // Côté serveur uniquement +// if (!this->isEmpty()) +// ne sert plus // this->completeLonLatServer(); + } + + if (context->hasClient) + { + computeConnectedServer() ; + sendServerAttribut() ; + sendLonLat() ; + } + + this->isChecked = true; + } + + void CDomain::sendServerAttribut(void) + { + int ni_srv=ni_glo.getValue() ; + int ibegin_srv=1 ; + int iend_srv=ni_glo.getValue() ; + + int nj_srv ; + int jbegin_srv ; + int jend_srv ; + + CContext* context=CContext::getCurrent() ; + CContextClient* client=context->client ; + int nbServer=client->serverSize ; + int serverRank=client->getServerLeader() ; + + jend_srv=0 ; + for(int i=0;i<=serverRank;i++) + { + jbegin_srv=jend_srv+1 ; + nj_srv=nj_glo.getValue()/nbServer ; + if (iisServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + void CDomain::computeConnectedServer(void) + { + int i,j,i_ind,j_ind ; + + ibegin_client=ibegin ; iend_client=iend ; ni_client=ni ; + jbegin_client=jbegin ; jend_client=jend ; nj_client=nj ; + + CContext* context = CContext::getCurrent() ; + CContextClient* client=context->client ; + int nbServer=client->serverSize ; + + // find how much client are connected to a server + int zoom_iend=zoom_ibegin+zoom_ni-1 ; + int zoom_jend=zoom_jbegin+zoom_nj-1 ; + + int blockSize=nj_glo/nbServer ; + int ns=nj_glo%nbServer ; + int pos=ns*(blockSize+1) ; + int serverNum ; + + mapConnectedServer.resize(ni,nj) ; + vector nbData(nbServer,0) ; + vector indServer(nbServer,-1) ; + vector IsConnected(nbServer,false) ; + + for(j=0;j= zoom_ibegin-1 && i_ind <= zoom_iend-1 && j_ind >= zoom_jbegin-1 && j_ind <= zoom_jend-1) + { + mapConnectedServer(i,j)=serverNum ; + nbData[serverNum]++ ; + } + else mapConnectedServer(i,j)=-1 ; + } + + + for(serverNum=0 ; serverNum=0) + { + ns=indServer[mapConnectedServer(i,j)] ; + mapConnectedServer(i,j)= ns ; + i_indSrv[ns].push_back(i+ibegin-1) ; + j_indSrv[ns].push_back(j+jbegin-1) ; + } + } + + int nbConnectedServer=connectedServer.size() ; + + int* recvCount=new int[client->clientSize] ; + int* displ=new int[client->clientSize] ; + int* sendBuff=new int[nbConnectedServer] ; + valarray nbClient(0,client->serverSize) ; + + for(int n=0;nintraComm) ; + + displ[0]=0 ; + for(int n=1;nclientSize;n++) displ[n]=displ[n-1]+recvCount[n-1] ; + int recvSize=displ[client->clientSize-1]+recvCount[client->clientSize-1] ; + int* recvBuff=new int[recvSize] ; + + + MPI_Allgatherv(sendBuff,nbConnectedServer,MPI_INT,recvBuff,recvCount,displ,MPI_INT,client->intraComm) ; + for(int n=0;nclient ; + // send lon lat for each connected server + CEventClient event(getType(),EVENT_ID_LON_LAT) ; + + list > list_msg ; + list< CArray* > list_indi,list_indj ; + list< CArray* >list_lon,list_lat ; + list< CArray* >list_boundslon,list_boundslat ; + + for(int ns=0;ns indi(nbData) ; + CArray indj(nbData) ; + CArray lon(nbData) ; + CArray lat(nbData) ; + CArray boundslon(nvertex,nbData) ; + CArray boundslat(nvertex,nbData) ; + + for(n=0;n(indi.copy())) ; + list_indj.push_back(new CArray(indj.copy())) ; + list_lon.push_back(new CArray(lon.copy())) ; + list_lat.push_back(new CArray(lat.copy())) ; + if (hasBounds) list_boundslon.push_back(new CArray(boundslon.copy())) ; + if (hasBounds) list_boundslat.push_back(new CArray(boundslat.copy())) ; + + list_msg.push_back(shared_ptr(new CMessage)) ; + + *list_msg.back()<getId()<<(int)type ; // enum ne fonctionne pour les message => ToFix + *list_msg.back()<sendEvent(event) ; + + + for(list* >::iterator it=list_indi.begin();it!=list_indi.end();it++) delete *it; + for(list* >::iterator it=list_indj.begin();it!=list_indj.end();it++) delete *it; + for(list* >::iterator it=list_lon.begin();it!=list_lon.end();it++) delete *it; + for(list* >::iterator it=list_lat.begin();it!=list_lat.end();it++) delete *it; + if (hasBounds) for(list* >::iterator it=list_boundslon.begin();it!=list_boundslon.end();it++) delete *it; + if (hasBounds) for(list* >::iterator it=list_boundslat.begin();it!=list_boundslat.end();it++) delete *it; + + } + + + bool CDomain::dispatchEvent(CEventServer& event) + { + + if (SuperClass::dispatchEvent(event)) return true ; + else + { + switch(event.type) + { + case EVENT_ID_SERVER_ATTRIBUT : + recvServerAttribut(event) ; + return true ; + break ; + case EVENT_ID_LON_LAT : + recvLonLat(event) ; + return true ; + break ; + default : + ERROR("bool CContext::dispatchEvent(CEventServer& event)", + <<"Unknown Event") ; + return false ; + } + } + } + + void CDomain::recvServerAttribut(CEventServer& event) + { + CBufferIn* buffer=event.subEvents.begin()->buffer; + string domainId ; + *buffer>>domainId ; + get(domainId)->recvServerAttribut(*buffer) ; + } + + void CDomain::recvServerAttribut(CBufferIn& buffer) + { + int zoom_iend=zoom_ibegin.getValue()+zoom_ni.getValue()-1 ; + int zoom_jend=zoom_jbegin.getValue()+zoom_nj.getValue()-1 ; + + buffer>>ni_srv>>ibegin_srv>>iend_srv>>nj_srv>>jbegin_srv>>jend_srv; + + + zoom_ibegin_srv = zoom_ibegin.getValue() > ibegin_srv ? zoom_ibegin.getValue() : ibegin_srv ; + zoom_iend_srv = zoom_iend < iend_srv ? zoom_iend : iend_srv ; + zoom_ni_srv=zoom_iend_srv-zoom_ibegin_srv+1 ; + + zoom_jbegin_srv = zoom_jbegin.getValue() > jbegin_srv ? zoom_jbegin.getValue() : jbegin_srv ; + zoom_jend_srv = zoom_jend < jend_srv ? zoom_jend : jend_srv ; + zoom_nj_srv=zoom_jend_srv-zoom_jbegin_srv+1 ; + + if (zoom_ni_srv<=0 || zoom_nj_srv<=0) + { + zoom_ibegin_srv=1 ; zoom_iend_srv=0 ; zoom_ni_srv=0 ; + zoom_jbegin_srv=1 ; zoom_jend_srv=0 ; zoom_nj_srv=0 ; + } + lonvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ; + lonvalue_srv = 0. ; + latvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ; + latvalue_srv = 0. ; + if (hasBounds) + { + bounds_lon_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ; + bounds_lon_srv = 0. ; + bounds_lat_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ; + bounds_lat_srv = 0. ; + } + } + + void CDomain::recvLonLat(CEventServer& event) + { + list::iterator it ; + for (it=event.subEvents.begin();it!=event.subEvents.end();++it) + { + CBufferIn* buffer=it->buffer; + string domainId ; + *buffer>>domainId ; + get(domainId)->recvLonLat(*buffer) ; + } + } + + void CDomain::recvLonLat(CBufferIn& buffer) + { + CArray indi ; + CArray indj ; + CArray lon ; + CArray lat ; + CArray boundslon ; + CArray boundslat ; + + int type_int ; + buffer>>type_int>>isCurvilinear>>indi>>indj>>lon>>lat ; + if (hasBounds) buffer>>boundslon>>boundslat ; + type.setValue((type_attr::t_enum)type_int) ; // probleme des type enum avec les buffers : ToFix + + int i,j,ind_srv ; + for(int ind=0;ind + , public CDomainAttributes + { + enum EEventId + { + EVENT_ID_SERVER_ATTRIBUT, EVENT_ID_LON_LAT + } ; + + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CDomainAttributes SuperClassAttribute; + + public : + + typedef CDomainAttributes RelAttributes; + typedef CDomainGroup RelGroup; + + /// Constructeurs /// + CDomain(void); + explicit CDomain(const StdString & id); + CDomain(const CDomain & domain); // Not implemented yet. + CDomain(const CDomain * const domain); // Not implemented yet. + + /// Vérifications /// + void checkAttributes(void); + + private : + + void checkDomain(void); + + void checkLocalIDomain(void); + void checkLocalJDomain(void); + + void checkMask(void); + void checkDomainData(void); + void checkCompression(void); + + void checkZoom(void); + void checkBounds(void); + + + public : + + /// Autres /// + + const std::set & getRelFiles(void) const; + + + /// Test /// + bool IsWritten(const StdString & filename) const; + bool hasZoom(void) const; + bool isEmpty(void) const; + + + int ni_client,ibegin_client,iend_client ; + int zoom_ni_client,zoom_ibegin_client,zoom_iend_client ; + + int nj_client,jbegin_client,jend_client ; + int zoom_nj_client,zoom_jbegin_client,zoom_jend_client ; + + int ni_srv,ibegin_srv,iend_srv ; + int zoom_ni_srv,zoom_ibegin_srv,zoom_iend_srv ; + + int nj_srv,jbegin_srv,jend_srv ; + int zoom_nj_srv,zoom_jbegin_srv,zoom_jend_srv ; + + CArray lonvalue_srv, latvalue_srv ; + CArray bounds_lon_srv, bounds_lat_srv ; + + + vector connectedServer ; // list of connected server + vector nbSenders ; // for each communication with a server, number of communicating client + vector nbDataSrv ; // size of data to send to each server + vector< vector > i_indSrv ; // for each server, i global index to send + vector< vector > j_indSrv ; // for each server, j global index to send + + CArray mapConnectedServer ; // (ni,nj) => mapped to connected server number, -1 if no server is target + +// vector ib_srv, ie_srv, in_srv ; +// vector jb_srv, je_srv, jn_srv ; + + public : + + /// Mutateur /// + void addRelFile(const StdString & filename); + void completeLonLatClient(void); + void sendServerAttribut(void) ; + void sendLonLat(void) ; + void computeConnectedServer(void) ; + static bool dispatchEvent(CEventServer& event) ; + static void recvLonLat(CEventServer& event) ; + static void recvServerAttribut(CEventServer& event) ; + void recvLonLat(CBufferIn& buffer) ; + void recvServerAttribut(CBufferIn& buffer) ; + + /// Destructeur /// + virtual ~CDomain(void); + + /// Accesseurs statiques /// + static StdString GetName(void); + static StdString GetDefName(void); + + static ENodeType GetType(void); + + CArray local_mask; + bool isCurvilinear ; + bool hasBounds ; + private : + + /// Proriétés protégées /// + bool isChecked; + std::set relFiles; + + }; // class CDomain + + ///-------------------------------------------------------------- + + // Declare/Define CDomainGroup and CDomainDefinition + DECLARE_GROUP(CDomain); + + ///-------------------------------------------------------------- + +} // namespace xios + +#endif // __XMLIO_CDomain__ diff --git a/src/node/field.cpp b/src/node/field.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3d4f140530a0e9e68ab5c344311702d798acdc40 --- /dev/null +++ b/src/node/field.cpp @@ -0,0 +1,935 @@ +#include "field.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +#include "node_type.hpp" +#include "calendar_util.hpp" +#include "message.hpp" +#include "xmlioserver_spl.hpp" +#include "type.hpp" +#include "context_client.hpp" +#include + +namespace xios{ + + /// ////////////////////// Définitions ////////////////////// /// + + CField::CField(void) + : CObjectTemplate(), CFieldAttributes() + , refObject(), baseRefObject() + , grid(), file() + , freq_operation(), freq_write() + , nstep(0) + , last_Write(), last_operation() + , foperation(), hasInstantData(false), hasExpression(false) + , active(false) , hasOutputFile(false),hasFieldOut(false), slotUpdateDate(NULL) + , processed(false) + { setVirtualVariableGroup(); } + + CField::CField(const StdString& id) + : CObjectTemplate(id), CFieldAttributes() + , refObject(), baseRefObject() + , grid(), file() + , freq_operation(), freq_write() + , nstep(0) + , last_Write(), last_operation() + , foperation(), hasInstantData(false), hasExpression(false) + , active(false), hasOutputFile(false), hasFieldOut(false), slotUpdateDate(NULL) + , processed(false) + { setVirtualVariableGroup(); } + + CField::~CField(void) + { +// this->grid.reset(); +// this->file.reset(); + this->foperation.reset(); + if (hasExpression) delete expression; + if (slotUpdateDate != NULL) delete slotUpdateDate; + + } + + //---------------------------------------------------------------- + + void CField::setVirtualVariableGroup(CVariableGroup* newVVariableGroup) + { + this->vVariableGroup = newVVariableGroup; + } + + void CField::setVirtualVariableGroup(void) + { + this->setVirtualVariableGroup(CVariableGroup::create()); + } + + CVariableGroup* CField::getVirtualVariableGroup(void) const + { + return this->vVariableGroup; + } + + std::vector CField::getAllVariables(void) const + { + return this->vVariableGroup->getAllChildren(); + } + + void CField::solveDescInheritance(bool apply, const CAttributeMap* const parent) + { + SuperClassAttribute::setAttributes(parent,apply); + this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL); + } + + //---------------------------------------------------------------- + + bool CField::updateDataServer + (const CDate& currDate, + const std::deque< CArray* > storedClient) + { + const CDate opeDate = *last_operation + freq_operation; + const CDate writeDate = *last_Write + freq_write; + + if (opeDate <= currDate) + { + if (this->data.numElements() != this->grid->storeIndex[0]->numElements()) + { + this->data.resize(this->grid->storeIndex[0]->numElements()); + } + CArray input(data.numElements()); + this->grid->inputFieldServer(storedClient, input); + (*this->foperation)(input); + *last_operation = currDate; + } + if (writeDate < (currDate + freq_operation)) + { + this->foperation->final(); + this->incrementNStep(); + *last_Write = writeDate; + return true; + } + return false; + } + + bool CField::dispatchEvent(CEventServer& event) + { + + if (SuperClass::dispatchEvent(event)) return true; + else + { + switch(event.type) + { + case EVENT_ID_UPDATE_DATA : + recvUpdateData(event); + return true; + break; + + case EVENT_ID_ADD_VARIABLE : + recvAddVariable(event); + return true; + break; + + case EVENT_ID_ADD_VARIABLE_GROUP : + recvAddVariableGroup(event); + return true; + break; + + default : + ERROR("bool CField::dispatchEvent(CEventServer& event)", << "Unknown Event"); + return false; + } + } + } + + void CField::sendUpdateData(void) + { + CContext* context = CContext::getCurrent(); + CContextClient* client = context->client; + + CEventClient event(getType(),EVENT_ID_UPDATE_DATA); + + map* >::iterator it; + list > list_msg; + list< CArray* > list_data; + + for (it = grid->storeIndex_toSrv.begin(); it != grid->storeIndex_toSrv.end(); it++) + { + int rank = (*it).first; + CArray& index = *(it->second); + CArray data_tmp(index.numElements()); + + for (int n = 0; n < data_tmp.numElements(); n++) data_tmp(n) = data(index(n)); + list_msg.push_back(shared_ptr(new CMessage)); + list_data.push_back(new CArray(data_tmp)); + *list_msg.back() << getId() << *list_data.back(); + event.push(rank,grid->nbSenders[rank],*list_msg.back()); + } + client->sendEvent(event); + + for (list< CArray* >::iterator it = list_data.begin(); it != list_data.end(); it++) delete *it; + } + + void CField::recvUpdateData(CEventServer& event) + { + vector ranks; + vector buffers; + + list::iterator it; + string fieldId; + + for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) + { + int rank = it->rank; + CBufferIn* buffer = it->buffer; + *buffer >> fieldId; + ranks.push_back(rank); + buffers.push_back(buffer); + } + get(fieldId)->recvUpdateData(ranks,buffers); + } + + void CField::recvUpdateData(vector& ranks, vector& buffers) + { + + if (data_srv.empty()) + { + for (map* >::iterator it = grid->out_i_fromClient.begin(); it != grid->out_i_fromClient.end(); it++) + { + int rank = it->first; + CArray data_tmp(it->second->numElements()); + data_srv.insert( pair* >(rank, new CArray(data_tmp))); + foperation_srv.insert(pair >(rank,boost::shared_ptr(new func::CInstant(*data_srv[rank])))); + } + } + + CContext* context = CContext::getCurrent(); + const CDate& currDate = context->getCalendar()->getCurrentDate(); + const CDate opeDate = *last_operation_srv + freq_operation_srv; + const CDate writeDate = *last_Write_srv + freq_write_srv; + + if (opeDate <= currDate) + { + for (int n = 0; n < ranks.size(); n++) + { + CArray data_tmp; + *buffers[n] >> data_tmp; + (*foperation_srv[ranks[n]])(data_tmp); + } + *last_operation_srv = currDate; + } + + if (writeDate < (currDate + freq_operation_srv)) + { + for (int n = 0; n < ranks.size(); n++) + { + this->foperation_srv[ranks[n]]->final(); + } + + *last_Write_srv = writeDate; + writeField(); + *lastlast_Write_srv = *last_Write_srv; + } + } + + void CField::writeField(void) + { + if (!getRelFile()->allDomainEmpty) + if (!grid->domain->isEmpty() || getRelFile()->type == CFile::type_attr::one_file) + { + getRelFile()->checkFile(); + this->incrementNStep(); + getRelFile()->getDataOutput()->writeFieldData(CField::get(this)); + } + } + //---------------------------------------------------------------- + + void CField::setRelFile(CFile* _file) + { + this->file = _file; + hasOutputFile = true; + } + + //---------------------------------------------------------------- + + StdString CField::GetName(void) { return StdString("field"); } + StdString CField::GetDefName(void) { return CField::GetName(); } + ENodeType CField::GetType(void) { return eField; } + + //---------------------------------------------------------------- + + CGrid* CField::getRelGrid(void) const + { + return this->grid; + } + + //---------------------------------------------------------------- + + CFile* CField::getRelFile(void) const + { + return this->file; + } + + StdSize CField::getNStep(void) const + { + return this->nstep; + } + + void CField::incrementNStep(void) + { + this->nstep++; + } + + void CField::resetNStep(void) + { + this->nstep = 0; + } + + //---------------------------------------------------------------- + + CField* CField::getDirectFieldReference(void) const + { + if (this->field_ref.isEmpty()) + return this->getBaseFieldReference(); + + if (!CField::has(this->field_ref.getValue())) + ERROR("CField::getDirectFieldReference(void)", + << "[ ref_name = " << this->field_ref.getValue() << "]" + << " invalid field name !"); + + return CField::get(this->field_ref.getValue()); + } + + //---------------------------------------------------------------- + + CField* CField::getBaseFieldReference(void) const + { + return baseRefObject; + } + + //---------------------------------------------------------------- + + const std::vector& CField::getAllReference(void) const + { + return refObject; + } + + //---------------------------------------------------------------- + + const StdString& CField::getBaseFieldId(void) const + { + return this->getBaseFieldReference()->getId(); + } + + //---------------------------------------------------------------- + + const CDuration& CField::getFreqOperation(void) const + { + return this->freq_operation; + } + + //---------------------------------------------------------------- + const CDuration& CField::getFreqWrite(void) const + { + return this->freq_write; + } + + //---------------------------------------------------------------- + + boost::shared_ptr CField::getFieldOperation(void) const + { + return this->foperation; + } + + //---------------------------------------------------------------- + + bool CField::hasDirectFieldReference(void) const + { + return !this->field_ref.isEmpty(); + } + + bool CField::isActive(void) const + { + return !this->refObject.empty(); + } + //---------------------------------------------------------------- + + CArray CField::getData(void) const + { + return(this->data); + } + + //---------------------------------------------------------------- + + boost::shared_ptr CField::getLastWriteDate(void) const + { + return(this->last_Write); + } + + //---------------------------------------------------------------- + + boost::shared_ptr CField::getLastOperationDate(void) const + { + return(this->last_operation); + } + + //---------------------------------------------------------------- + + void CField::processEnabledField(void) + { + if (!processed) + { + processed = true; + solveRefInheritance(true); + solveBaseReference(); + solveOperation(); + solveGridReference(); + + if (hasDirectFieldReference()) baseRefObject->processEnabledField(); + buildExpression(); + active = true; + } + } + + void CField::solveRefInheritance(bool apply) + { + std::set sset; + CField* refer_sptr; + CField* refer_ptr = this; + + while (refer_ptr->hasDirectFieldReference()) + { + refer_sptr = refer_ptr->getDirectFieldReference(); + refer_ptr = refer_sptr; + + if(sset.end() != sset.find(refer_ptr)) + { + DEBUG (<< "Circular dependency stopped for field object on " + << "\"" + refer_ptr->getId() + "\" !"); + break; + } + + SuperClassAttribute::setAttributes(refer_ptr, apply); + sset.insert(refer_ptr); + } + } + + void CField::solveBaseReference(void) + { + std::set sset; + CField* refer_sptr; + CField* refer_ptr = this; + + if (this->hasDirectFieldReference()) baseRefObject = getDirectFieldReference(); + else baseRefObject = CField::get(this); + + while (refer_ptr->hasDirectFieldReference()) + { + refer_sptr = refer_ptr->getDirectFieldReference(); + refer_ptr = refer_sptr; + + if(sset.end() != sset.find(refer_ptr)) + { + DEBUG (<< "Circular dependency stopped for field object on " + << "\"" + refer_ptr->getId() + "\" !"); + break; + } + + sset.insert(refer_ptr); + } + + if (hasDirectFieldReference()) baseRefObject->addReference(this); + } + + //---------------------------------------------------------------- + + void CField::solveOperation(void) + { + using namespace func; + + if (!hasOutputFile && !hasFieldOut) return; + + StdString id; + if (hasId()) id = getId(); + else if (!name.isEmpty()) id = name; + else if (hasDirectFieldReference()) id = baseRefObject->getId(); + + CContext* context = CContext::getCurrent(); + + if (freq_op.isEmpty()) freq_op = string("1ts"); + + if (operation.isEmpty()) + { + ERROR("CField::solveOperation(void)", + << "[ id = " << id << "]" + << "Impossible to define an operation for this field !"); + } + + CDuration freq_offset_ = NoneDu; + if (!freq_offset.isEmpty()) + { + freq_offset_ = CDuration::FromString(freq_offset.getValue()); + } + else + { + freq_offset.setValue(NoneDu.toString()); + } + +// if (CXIOSManager::GetStatus() == CXIOSManager::LOC_SERVER) + if (context->hasServer) + { + if (hasOutputFile) + { + this->freq_operation_srv = CDuration::FromString(this->file->output_freq.getValue()); + this->freq_write_srv = CDuration::FromString(this->file->output_freq.getValue()); + } + this->lastlast_Write_srv = boost::shared_ptr + (new CDate(context->getCalendar()->getInitDate())); + this->last_Write_srv = boost::shared_ptr + (new CDate(context->getCalendar()->getInitDate())); + this->last_operation_srv = boost::shared_ptr + (new CDate(context->getCalendar()->getInitDate())); +// this->foperation_srv = +// boost::shared_ptr(new CInstant(this->data_srv)); + + if (hasOutputFile) + { + const CDuration toffset = this->freq_operation_srv - freq_offset_ - context->getCalendar()->getTimeStep(); + *this->last_operation_srv = *this->last_operation_srv - toffset; + } + } + +// if (context->hasClient) +// { + this->freq_operation = CDuration::FromString(freq_op.getValue()); + if (hasOutputFile) this->freq_write = CDuration::FromString(this->file->output_freq.getValue()); + if (hasFieldOut) + { + this->freq_write = CDuration::FromString(this->fieldOut->freq_op.getValue()); + } + this->last_Write = boost::shared_ptr + (new CDate(context->getCalendar()->getInitDate())); + this->last_operation = boost::shared_ptr + (new CDate(context->getCalendar()->getInitDate())); + + const CDuration toffset = this->freq_operation - freq_offset_ - context->getCalendar()->getTimeStep(); + *this->last_operation = *this->last_operation - toffset; + + if (operation.get() == "once") isOnceOperation = true; + else isOnceOperation = false; + isFirstOperation = true; + +#define DECLARE_FUNCTOR(MType, mtype) \ + if (operation.getValue().compare(#mtype) == 0) \ + { \ + if (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true) \ + { \ + boost::shared_ptr foperation_(new C##MType(this->data,default_value)); \ + this->foperation = foperation_; \ + } \ + else \ + { \ + boost::shared_ptr foperation_(new C##MType(this->data)); \ + this->foperation = foperation_; \ + } \ + return; \ + } + +#include "functor_type.conf" + + ERROR("CField::solveOperation(void)", + << "[ operation = " << operation.getValue() << "]" + << "The operation is not defined !"); +// } + } + + //---------------------------------------------------------------- +/* + void CField::fromBinary(StdIStream& is) + { + SuperClass::fromBinary(is); +#define CLEAR_ATT(name_)\ + SuperClassAttribute::operator[](#name_)->reset() + + CLEAR_ATT(domain_ref); + CLEAR_ATT(axis_ref); +#undef CLEAR_ATT + + } +*/ + //---------------------------------------------------------------- + + void CField::solveGridReference(void) + { + CDomain* domain; + CAxis* axis; + + if (!domain_ref.isEmpty()) + { + if (CDomain::has(domain_ref.getValue())) + domain = CDomain::get(domain_ref.getValue()); + else + ERROR("CField::solveGridReference(void)", + << "Reference to the domain \'" + << domain_ref.getValue() << "\' is wrong"); + } + + if (!axis_ref.isEmpty()) + { + if (CAxis::has(axis_ref.getValue())) + axis = CAxis::get(axis_ref.getValue()); + else + ERROR("CField::solveGridReference(void)", + << "Reference to the axis \'" + << axis_ref.getValue() <<"\' is wrong"); + } + + if (!grid_ref.isEmpty()) + { + if (CGrid::has(grid_ref.getValue())) + this->grid = CGrid::get(grid_ref.getValue()); + else + ERROR("CField::solveGridReference(void)", + << "Reference to the grid \'" + << grid_ref.getValue() << "\' is wrong"); + } + + if (grid_ref.isEmpty() && domain_ref.isEmpty()) + { + ERROR("CField::solveGridReference(void)", + << "The horizontal domain for this field is not defined"); + + } + + CType goodDomain; + CType goodAxis; + if (!grid_ref.isEmpty()) + { + if (!grid->domain_ref.isEmpty()) goodDomain = grid->domain_ref; + if (!grid->axis_ref.isEmpty()) goodAxis = grid->axis_ref; + } + if (!domain_ref.isEmpty()) goodDomain = domain_ref; + if (!axis_ref.isEmpty()) goodAxis = axis_ref; + + if (goodDomain.isEmpty()) + { + ERROR("CField::solveGridReference(void)", << "The horizontal domain for this field is not defined"); + } + else + { + if (CDomain::has(goodDomain)) domain = CDomain::get(goodDomain); + else ERROR("CField::solveGridReference(void)",<< "Reference to the domain \'" << goodDomain.get() << "\' is wrong"); + } + + if (!goodAxis.isEmpty()) + { + if (CAxis::has(goodAxis)) axis = CAxis::get(goodAxis); + else ERROR("CField::solveGridReference(void)", << "Reference to the axis \'" + << goodAxis.get() <<"\' is wrong"); + } + + bool nothingToDo = false; + + if (!grid_ref.isEmpty()) + { + if (!grid->domain_ref.isEmpty() && goodDomain.get() == grid->domain_ref.get()) + if (goodAxis.isEmpty()) nothingToDo = true; + else if (!grid->axis_ref.isEmpty()) + if (grid->axis_ref.get() == goodAxis.get()) nothingToDo = true; + } + + if (!nothingToDo) + { + if (!goodAxis.isEmpty()) + { + this->grid = CGrid::createGrid(domain, axis); + this->grid_ref.setValue(this->grid->getId()); + } + else + { + this->grid = CGrid::createGrid(domain); + this->grid_ref.setValue(this->grid->getId()); + } + } + + grid->solveReference(); + + } + + ///------------------------------------------------------------------- + + template <> + void CGroupTemplate::solveRefInheritance(void) + { + if (this->group_ref.isEmpty()) return; + StdString gref = this->group_ref.getValue(); + + if (!CFieldGroup::has(gref)) + ERROR("CGroupTemplate::solveRefInheritance(void)", + << "[ gref = " << gref << "]" + << " invalid group name !"); + + CFieldGroup* group = CFieldGroup::get(gref); + CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast(this)); + + std::vector allChildren = group->getAllChildren(); + std::vector::iterator it = allChildren.begin(), end = allChildren.end(); + + for (; it != end; it++) + { + CField* child = *it; + if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId()); + + } + } + + void CField::scaleFactorAddOffset(double scaleFactor, double addOffset) + { + map* >::iterator it; + for (it = data_srv.begin(); it != data_srv.end(); it++) *it->second = (*it->second - addOffset) / scaleFactor; + } + + void CField::outputField(CArray& fieldOut) + { + map* >::iterator it; + for (it = data_srv.begin(); it != data_srv.end(); it++) + grid->outputField(it->first,*it->second, fieldOut); + + } + + void CField::outputField(CArray& fieldOut) + { + map* >::iterator it; + + for (it = data_srv.begin(); it != data_srv.end(); it++) + { + grid->outputField(it->first,*it->second, fieldOut); + } + } + + ///------------------------------------------------------------------- + + void CField::parse(xml::CXMLNode& node) + { + SuperClass::parse(node); + if (!node.getContent(this->content)) + { + if (node.goToChildElement()) + { + do + { + if (node.getElementName() == "variable" || node.getElementName() == "variable_group") this->getVirtualVariableGroup()->parseChild(node); + } while (node.goToNextElement()); + node.goToParentElement(); + } + } + } + + CArray* CField::getInstantData(void) + { + if (!hasInstantData) + { + instantData.resize(grid->storeIndex_client.numElements()); + hasInstantData = true; + } + return &instantData; + } + + void CField::addReference(CField* field) + { + refObject.push_back(field); + } + + void CField::addDependency(CField* field, int slotId) + { + fieldDependency.push_back(pair(field,slotId)); + } + + void CField::buildExpression(void) + { + if (content.size() > 0) + { + CSimpleNodeExpr* simpleExpr = parseExpr(content+'\0'); + expression = CFieldNode::newNode(simpleExpr); + delete simpleExpr; + set instantFieldIds; + map associatedInstantFieldIds; + expression->getInstantFieldIds(instantFieldIds); + for (set::iterator it = instantFieldIds.begin(); it != instantFieldIds.end(); ++it) + { + if (*it != "this") + { + if (CField::has(*it)) + { + CField* field = CField::get(*it); + field->processEnabledField(); + associatedInstantFieldIds[*it] = field; + } + else ERROR("void CField::buildExpression(void)", << " Field " << *it << " does not exist"); + } + } + + set averageFieldIds; + map associatedAverageFieldIds; + + expression->getAverageFieldIds(averageFieldIds); + for (set::iterator it = averageFieldIds.begin(); it != averageFieldIds.end(); ++it) + { + if (CField::has(*it)) + { + CFieldGroup* root = CFieldGroup::get("field_definition"); + CField* averageField = root->createChild(); + CField* instantField = root->createChild(); + averageField->field_ref = *it; + averageField->hasFieldOut = true; + averageField->fieldOut = instantField; + instantField->freq_op = freq_op; + averageField-> processEnabledField(); + instantField->SuperClassAttribute::setAttributes(averageField, true); + instantField->field_ref.reset(); + instantField->operation.reset(); + + instantField-> processEnabledField(); + associatedAverageFieldIds[*it] = instantField; + } + else ERROR("void CField::buildExpression(void)", << " Field " << *it << " does not exist"); + } + + expression->reduce(this,associatedInstantFieldIds,associatedAverageFieldIds); + + slots.resize(instantFieldIds.size() + averageFieldIds.size()); + resetSlots(); + int slotId = 0; + set fields; + expression->getFields(fields); + for (set::iterator it = fields.begin(); it != fields.end(); ++it, ++slotId) (*it)->addDependency(this,slotId); + hasExpression = true; + } + } + + void CField::resetSlots(void) + { + for (vector::iterator it = slots.begin(); it != slots.end(); ++it) *it = false; + } + + bool CField::slotsFull(void) + { + bool ret = true; + for (vector::iterator it = slots.begin(); it != slots.end(); ++it) ret &= *it; + return ret; + } + + void CField::setSlot(int slotId) + { + CContext* context = CContext::getCurrent(); + const CDate& currDate = context->getCalendar()->getCurrentDate(); + if (slotUpdateDate == NULL || currDate != *slotUpdateDate) + { + resetSlots(); + if (slotUpdateDate == NULL) slotUpdateDate = new CDate(currDate); + else *slotUpdateDate = currDate; + } + slots[slotId] = true; + if (slotsFull()) + { + CArray expr(expression->compute()); + + if (hasInstantData) + { + instantData = expr; + for (list< pair >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it) + if (it->first != this) it->first->setSlot(it->second); + } + + if (hasOutputFile) updateDataFromExpression(expr); + + const std::vector& refField = getAllReference(); + for (std::vector::const_iterator it = refField.begin(); it != refField.end(); it++) + { + if (!(*it)->hasExpression) + (*it)->setDataFromExpression(expr); + } + } + } + + CVariable* CField::addVariable(const string& id) + { + return vVariableGroup->createChild(id); + } + + CVariableGroup* CField::addVariableGroup(const string& id) + { + return vVariableGroup->createChildGroup(id); + } + + void CField::sendAddVariable(const string& id) + { + CContext* context = CContext::getCurrent(); + + if (!context->hasServer) + { + CContextClient* client = context->client; + + CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE); + if (client->isServerLeader()) + { + CMessage msg; + msg << this->getId(); + msg << id; + event.push(client->getServerLeader(),1,msg); + client->sendEvent(event); + } + else client->sendEvent(event); + } + + } + + void CField::sendAddVariableGroup(const string& id) + { + CContext* context = CContext::getCurrent(); + if (!context->hasServer) + { + CContextClient* client = context->client; + + CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP); + if (client->isServerLeader()) + { + CMessage msg; + msg << this->getId(); + msg << id; + event.push(client->getServerLeader(),1,msg); + client->sendEvent(event); + } + else client->sendEvent(event); + } + + } + + void CField::recvAddVariable(CEventServer& event) + { + + CBufferIn* buffer = event.subEvents.begin()->buffer; + string id; + *buffer >> id; + get(id)->recvAddVariable(*buffer); + } + + void CField::recvAddVariable(CBufferIn& buffer) + { + string id; + buffer >> id; + addVariable(id); + } + + void CField::recvAddVariableGroup(CEventServer& event) + { + + CBufferIn* buffer = event.subEvents.begin()->buffer; + string id; + *buffer >> id; + get(id)->recvAddVariableGroup(*buffer); + } + + void CField::recvAddVariableGroup(CBufferIn& buffer) + { + string id; + buffer >> id; + addVariableGroup(id); + } +} // namespace xios diff --git a/src/node/field.hpp b/src/node/field.hpp new file mode 100644 index 0000000000000000000000000000000000000000..39b536a6c41e6b7d33da2efdea3d86202e7efa5a --- /dev/null +++ b/src/node/field.hpp @@ -0,0 +1,214 @@ +#ifndef __XMLIO_CField__ +#define __XMLIO_CField__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "group_factory.hpp" +#include "functor.hpp" +#include "functor_type.hpp" +#include "duration.hpp" +#include "date.hpp" +#include "declare_group.hpp" +#include "calendar_util.hpp" +#include "array_new.hpp" +#include "attribute_array.hpp" +#include "expr_node.hpp" +//#include "context.hpp" + + +namespace xios { + + /// ////////////////////// Déclarations ////////////////////// /// + + class CFieldGroup; + class CFieldAttributes; + class CField; + + class CFile; + class CGrid; + class CContext ; + ///-------------------------------------------------------------- + + // Declare/Define CFieldAttribute + BEGIN_DECLARE_ATTRIBUTE_MAP(CField) +# include "field_attribute.conf" + END_DECLARE_ATTRIBUTE_MAP(CField) + + ///-------------------------------------------------------------- + class CField + : public CObjectTemplate + , public CFieldAttributes + { + /// friend /// + friend class CFile; + + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CFieldAttributes SuperClassAttribute; + + public : + + typedef CFieldAttributes RelAttributes; + typedef CFieldGroup RelGroup; + + enum EEventId + { + EVENT_ID_UPDATE_DATA, EVENT_ID_ADD_VARIABLE, EVENT_ID_ADD_VARIABLE_GROUP + } ; + + /// Constructeurs /// + CField(void); + explicit CField(const StdString & id); + CField(const CField & field); // Not implemented yet. + CField(const CField * const field); // Not implemented yet. + + /// Accesseurs /// + CField* getDirectFieldReference(void) const; + CField* getBaseFieldReference(void) const; + void addReference(CField* field) ; + const std::vector & getAllReference(void) const; + + CGrid* getRelGrid(void) const ; + CFile* getRelFile(void) const ; + + public : + + StdSize getNStep(void) const; + + const CDuration & getFreqOperation(void) const; + const CDuration & getFreqWrite(void) const; + + boost::shared_ptr getLastWriteDate(void) const; + boost::shared_ptr getLastOperationDate(void) const; + + boost::shared_ptr getFieldOperation(void) const; + + CArray getData(void) const; + + const StdString & getBaseFieldId(void) const; + + /// Mutateur /// + void setRelFile(CFile* _file); + void incrementNStep(void); + void resetNStep() ; + + template bool updateData(const CArray& data); + bool updateDataFromExpression(const CArray& data); + void setDataFromExpression(const CArray& _data) ; + + bool updateDataServer + (const CDate & currDate, + const std::deque< CArray* > storedClient); + + public : + + /// Test /// + bool hasDirectFieldReference(void) const; + bool isActive(void) const; + bool active ; + bool hasOutputFile ; + bool hasFieldOut ; + + /// Traitements /// + void processEnabledField(void) ; + void solveRefInheritance(bool apply); + void solveBaseReference(void); + void solveGridReference(void); + void solveOperation(void); + +// virtual void fromBinary(StdIStream & is); + + /// Destructeur /// + virtual ~CField(void); + + /// Accesseurs statiques /// + static StdString GetName(void); + static StdString GetDefName(void); + + static ENodeType GetType(void); + + template void setData(const CArray& _data) ; + static bool dispatchEvent(CEventServer& event) ; + void sendUpdateData(void) ; + static void recvUpdateData(CEventServer& event) ; + void recvUpdateData(vector& ranks, vector& buffers) ; + void writeField(void) ; + void outputField(CArray& fieldOut) ; + void outputField(CArray& fieldOut) ; + void scaleFactorAddOffset(double scaleFactor, double addOffset) ; + void parse(xml::CXMLNode & node) ; + CArray* getInstantData(void) ; + + void setVirtualVariableGroup(CVariableGroup* newVVariableGroup); + void setVirtualVariableGroup(void); + CVariableGroup* getVirtualVariableGroup(void) const; + vector getAllVariables(void) const; + virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0); + + CVariable* addVariable(const string& id="") ; + CVariableGroup* addVariableGroup(const string& id="") ; + void sendAddVariable(const string& id="") ; + void sendAddVariableGroup(const string& id="") ; + static void recvAddVariable(CEventServer& event) ; + void recvAddVariable(CBufferIn& buffer) ; + static void recvAddVariableGroup(CEventServer& event) ; + void recvAddVariableGroup(CBufferIn& buffer) ; + + public : + + /// Propriétés privées /// + CVariableGroup* vVariableGroup ; + + std::vector refObject; + CField* baseRefObject; + CGrid* grid ; + CFile* file; + CField* fieldOut ; + + CDuration freq_operation, freq_write; + CDuration freq_operation_srv, freq_write_srv; + + StdSize nstep; + boost::shared_ptr last_Write, last_operation; + boost::shared_ptr lastlast_Write_srv,last_Write_srv, last_operation_srv; + + boost::shared_ptr foperation; + map > foperation_srv; + + CArray data; + CArray instantData; + bool hasInstantData ; + map* > data_srv ; + bool isOnceOperation ; + bool isFirstOperation ; + string content ; + + list< pair > fieldDependency ; + void buildExpression(void) ; + void addDependency(CField* field, int slotId) ; + void resetSlots(void) ; + vector slots ; + CDate* slotUpdateDate ; + CFieldNode * expression ; + bool hasExpression ; + bool slotsFull(void) ; + void setSlot(int slotId); + bool processed ; + + }; // class CField + + ///-------------------------------------------------------------- + + // Declare/Define CFieldGroup and CFieldDefinition + DECLARE_GROUP(CField); + + ///----------------------------------------------------------------- + + template <> + void CGroupTemplate::solveRefInheritance(void); + + ///----------------------------------------------------------------- +} // namespace xios + + +#endif // __XMLIO_CField__ diff --git a/src/node/field_decl.cpp b/src/node/field_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bd0b072d25f46f7870b770bb64140c7ad21f6c08 --- /dev/null +++ b/src/node/field_decl.cpp @@ -0,0 +1,9 @@ +#include "field_impl.hpp" + +namespace xios +{ + template void CField::setData<1>(const CArray& _data) ; + template void CField::setData<2>(const CArray& _data) ; + template void CField::setData<3>(const CArray& _data) ; + +} diff --git a/src/node/field_impl.hpp b/src/node/field_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c378ce723f4f875eac5e0d3859e3aa0c266b170a --- /dev/null +++ b/src/node/field_impl.hpp @@ -0,0 +1,183 @@ + +#ifndef __FIELD_IMPL_HPP__ +#define __FIELD_IMPL_HPP__ + +#include "xmlioserver_spl.hpp" +#include "field.hpp" +#include "context.hpp" +#include "grid.hpp" +#include "timer.hpp" +#include "array_new.hpp" + + +namespace xios { + + template + void CField::setData(const CArray& _data) + { + if (hasInstantData) + { + grid->inputField(_data, instantData); + for(list< pair >::iterator it=fieldDependency.begin(); it!=fieldDependency.end(); ++it) it->first->setSlot(it->second); + } + + if (!hasExpression) + { + const std::vector& refField=getAllReference(); + std::vector::const_iterator it = refField.begin(), end = refField.end(); + + for (; it != end; it++) (*it)->setData(_data); + if (hasOutputFile || hasFieldOut) updateData(_data); + } + } + + void CField::setDataFromExpression(const CArray& _data) + { + if (hasInstantData) + { + instantData=_data; + for(list< pair >::iterator it=fieldDependency.begin(); it!=fieldDependency.end(); ++it) it->first->setSlot(it->second); + } + + if (!hasExpression) + { + const std::vector& refField=getAllReference(); + std::vector::const_iterator it = refField.begin(), end = refField.end(); + + for (; it != end; it++) (*it)->setDataFromExpression(_data); + if (hasOutputFile || hasFieldOut) updateDataFromExpression(_data); + } + } + + template + bool CField::updateData(const CArray& _data) + { + CContext* context=CContext::getCurrent(); + const CDate & currDate = context->getCalendar()->getCurrentDate(); + const CDate opeDate = *last_operation + freq_operation; + const CDate writeDate = *last_Write + freq_write; + bool doOperation, doWrite; + + + info(50) << "CField::updateData " << currDate << " : send data to " << this->getBaseFieldId() << std::endl; + info(50) << "Next operation " << opeDate<data.numElements() != this->grid->storeIndex_client.numElements()) + { + this->data.resize(this->grid->storeIndex_client.numElements()); + } + + CArray input(data.numElements()); + this->grid->inputField(_data, input); + (*this->foperation)(input); + + *last_operation = currDate; + info(50) << "(*last_operation = currDate) : " << *last_operation << " = " << currDate << std::endl; + } + + doWrite = (writeDate < (currDate + freq_operation)); + if (isOnceOperation) + { + if(isFirstOperation) + { + doWrite=true; + isFirstOperation=false; + } + else doWrite=false; + } + + if (doWrite) + { + this->foperation->final(); + *last_Write = writeDate; + if (hasOutputFile) + { + info(50) << "(*last_Write = currDate) : " << *last_Write << " = " << currDate << std::endl; + CTimer::get("XIOS Send Data").resume(); + sendUpdateData(); + CTimer::get("XIOS Send Data").suspend(); + } + + if (hasFieldOut) + { + fieldOut->setDataFromExpression(data); + } + return (true); + } + + return (false); + } + + bool CField::updateDataFromExpression(const CArray& _data) + { + CContext* context=CContext::getCurrent(); + const CDate & currDate = context->getCalendar()->getCurrentDate(); + const CDate opeDate = *last_operation + freq_operation; + const CDate writeDate = *last_Write + freq_write; + bool doOperation, doWrite; + + + info(50) << "CField::updateData " << currDate << " : send data to " << this->getBaseFieldId() << std::endl; + info(50) << "Next operation " << opeDate<data.numElements() != this->grid->storeIndex_client.numElements()) + { + this->data.resize(this->grid->storeIndex_client.numElements()); + } + + (*this->foperation)(_data); + + *last_operation = currDate; + info(50) << "(*last_operation = currDate) : " << *last_operation << " = " << currDate << std::endl; + } + + doWrite = (writeDate < (currDate + freq_operation)); + if (isOnceOperation) + { + if(isFirstOperation) + { + doWrite=true; + isFirstOperation=false; + } + else doWrite=false; + } + + if (doWrite) + { + this->foperation->final(); + *last_Write = writeDate; + if (hasOutputFile) + { + info(50) << "(*last_Write = currDate) : " << *last_Write << " = " << currDate << std::endl; + CTimer::get("XIOS Send Data").resume(); + sendUpdateData(); + CTimer::get("XIOS Send Data").suspend(); + } + + if (hasFieldOut) + { + fieldOut->setDataFromExpression(data); + } + return (true); + } + + return (false); + } + +} // namespace xios + +#endif diff --git a/src/node/file.cpp b/src/node/file.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a3ac45779f4fc5a19b10319f462da0368fdac228 --- /dev/null +++ b/src/node/file.cpp @@ -0,0 +1,678 @@ +#include "file.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "object_factory.hpp" +#include "data_output.hpp" +#include "context.hpp" +#include "context_server.hpp" +#include "nc4_data_output.hpp" +#include "calendar_util.hpp" +#include "date.hpp" +#include "message.hpp" +#include "type.hpp" +#include "xmlioserver_spl.hpp" +#include "context_client.hpp" +#include "mpi.hpp" + +namespace xios { + + /// ////////////////////// Définitions ////////////////////// /// + + CFile::CFile(void) + : CObjectTemplate(), CFileAttributes() + , vFieldGroup(), data_out(), enabledFields(), fileComm(MPI_COMM_NULL) + { + setVirtualFieldGroup() ; + setVirtualVariableGroup() ; + } + + CFile::CFile(const StdString & id) + : CObjectTemplate(id), CFileAttributes() + , vFieldGroup(), data_out(), enabledFields(), fileComm(MPI_COMM_NULL) + { + setVirtualFieldGroup() ; + setVirtualVariableGroup() ; + } + + CFile::~CFile(void) + { /* Ne rien faire de plus */ } + + ///--------------------------------------------------------------- + + StdString CFile::GetName(void) { return (StdString("file")); } + StdString CFile::GetDefName(void){ return (CFile::GetName()); } + ENodeType CFile::GetType(void) { return (eFile); } + + //---------------------------------------------------------------- + + boost::shared_ptr CFile::getDataOutput(void) const + { + return (data_out); + } + + CFieldGroup* CFile::getVirtualFieldGroup(void) const + { + return (this->vFieldGroup); + } + + CVariableGroup* CFile::getVirtualVariableGroup(void) const + { + return (this->vVariableGroup); + } + + std::vector CFile::getAllFields(void) const + { + return (this->vFieldGroup->getAllChildren()); + } + + std::vector CFile::getAllVariables(void) const + { + return (this->vVariableGroup->getAllChildren()); + } + + //---------------------------------------------------------------- + + std::vector CFile::getEnabledFields(int default_outputlevel, + int default_level, + bool default_enabled) + { + if (!this->enabledFields.empty()) + return (this->enabledFields); + + const int _outputlevel = + (!output_level.isEmpty()) ? output_level.getValue() : default_outputlevel; + std::vector::iterator it; + this->enabledFields = this->getAllFields(); + + std::vector newEnabledFields; + + for ( it = this->enabledFields.begin() ; it != this->enabledFields.end(); it++ ) + { + if (!(*it)->enabled.isEmpty()) // Si l'attribut 'enabled' est défini ... + { + if (! (*it)->enabled.getValue()) continue; +// { it--; this->enabledFields.erase(it+1); continue; } + } + else // Si l'attribut 'enabled' n'est pas défini ... + { + if (!default_enabled) continue ; +// { it--; this->enabledFields.erase(it+1); continue; } + } + + if (!(*it)->level.isEmpty()) // Si l'attribut 'level' est défini ... + { + if ((*it)->level.getValue() > _outputlevel) continue ; +// { it--; this->enabledFields.erase(it+1); continue; } + } + else // Si l'attribut 'level' n'est pas défini ... + { + if (default_level > _outputlevel) continue ; +// { it--; this->enabledFields.erase(it+1); continue; } + } + +// CField* field_tmp=(*it).get() ; +// shared_ptr sptfield=*it ; +// field_tmp->refObject.push_back(sptfield) ; + newEnabledFields.push_back(*it) ; + // Le champ est finalement actif, on y ajoute sa propre reference. +// (*it)->refObject.push_back(*it); + // Le champ est finalement actif, on y ajoute la référence au champ de base. + (*it)->setRelFile(CFile::get(this)); +// (*it)->baseRefObject->refObject.push_back(*it); + // A faire, ajouter les references intermediaires... + } + enabledFields=newEnabledFields ; + + return (this->enabledFields); + } + + //---------------------------------------------------------------- + + void CFile::setVirtualFieldGroup(CFieldGroup* newVFieldGroup) + { + this->vFieldGroup = newVFieldGroup; + } + + void CFile::setVirtualVariableGroup(CVariableGroup* newVVariableGroup) + { + this->vVariableGroup = newVVariableGroup; + } + + //---------------------------------------------------------------- + + void CFile::setVirtualFieldGroup(void) + { + this->setVirtualFieldGroup(CFieldGroup::create()); + } + + void CFile::setVirtualVariableGroup(void) + { + this->setVirtualVariableGroup(CVariableGroup::create()); + } + + //---------------------------------------------------------------- + bool CFile::isSyncTime(void) + { + CContext* context = CContext::getCurrent() ; + CDate& currentDate=context->calendar->getCurrentDate() ; + if (! sync_freq.isEmpty()) + { + if (*lastSync+syncFreq < currentDate) + { + *lastSync=currentDate ; + return true ; + } + } + return false ; + } + + void CFile::initFile(void) + { + CContext* context = CContext::getCurrent() ; + CDate& currentDate=context->calendar->getCurrentDate() ; + CContextServer* server=context->server ; + + if (! sync_freq.isEmpty()) syncFreq = CDuration::FromString(sync_freq.getValue()); + if (! split_freq.isEmpty()) splitFreq = CDuration::FromString(split_freq.getValue()); + if (! output_freq.isEmpty()) outputFreq = CDuration::FromString(output_freq.getValue()); + lastSync=new CDate(currentDate) ; + lastSplit=new CDate(currentDate) ; + isOpen=false ; + + allDomainEmpty=true ; + set setDomain ; + + std::vector::iterator it, end = this->enabledFields.end(); + for (it = this->enabledFields.begin() ;it != end; it++) + { + CField* field = *it; + allDomainEmpty&=field->grid->domain->isEmpty() ; + setDomain.insert(field->grid->domain) ; + } + nbDomain=setDomain.size() ; + + // create sub communicator for file + int color=allDomainEmpty?0:1 ; + MPI_Comm_split(server->intraComm,color,server->intraCommRank,&fileComm) ; + if (allDomainEmpty) MPI_Comm_free(&fileComm) ; + // + + } + + void CFile::checkFile(void) + { + if (!isOpen) createHeader() ; + checkSync() ; + checkSplit() ; + } + + + bool CFile::checkSync(void) + { + CContext* context = CContext::getCurrent() ; + CDate& currentDate=context->calendar->getCurrentDate() ; + if (! sync_freq.isEmpty()) + { + if (*lastSync+syncFreq <= currentDate) + { + *lastSync=currentDate ; + data_out->syncFile() ; + return true ; + } + } + return false ; + } + + + bool CFile::checkSplit(void) + { + CContext* context = CContext::getCurrent() ; + CDate& currentDate=context->calendar->getCurrentDate() ; + if (! split_freq.isEmpty()) + { + if (currentDate > *lastSplit+splitFreq) + { + *lastSplit=*lastSplit+splitFreq ; + std::vector::iterator it, end = this->enabledFields.end(); + for (it = this->enabledFields.begin() ;it != end; it++) (*it)->resetNStep() ; + createHeader() ; + return true ; + } + } + return false ; + } + + void CFile::createHeader(void) + { + CContext* context = CContext::getCurrent() ; + CContextServer* server=context->server ; + + if (!allDomainEmpty) + { + StdString filename = (!name.isEmpty()) ? name.getValue() : getId(); + StdOStringStream oss; + oss << filename; + if (!name_suffix.isEmpty()) oss << name_suffix.getValue(); +// if (!split_freq.isEmpty()) oss<<"_"<getStryyyymmdd()<<"-"<< (*lastSplit+(splitFreq-1*Second)).getStryyyymmdd(); +// if (!split_freq.isEmpty()) oss<<"_"<getStr("%y_%mo_%d")<<"-"<< (*lastSplit+(splitFreq-1*Second)).getStr("%y_%mo_%d"); + if (!split_freq.isEmpty()) + { + string splitFormat ; + if (split_freq_format.isEmpty()) + { + if (splitFreq.second!=0) splitFormat="%y%mo%d%h%mi%s"; + else if (splitFreq.minute!=0) splitFormat="%y%mo%d%h%mi"; + else if (splitFreq.hour!=0) splitFormat="%y%mo%d%h"; + else if (splitFreq.day!=0) splitFormat="%y%mo%d"; + else if (splitFreq.month!=0) splitFormat="%y%mo"; + else splitFormat="%y"; + } + else splitFormat=split_freq_format ; + oss<<"_"<getStr(splitFormat)<<"-"<< (*lastSplit + splitFreq - 1 * Second).getStr(splitFormat); + } + + bool multifile=true ; + if (!type.isEmpty()) + { + if (type==type_attr::one_file) multifile=false ; + else if (type==type_attr::multiple_file) multifile=true ; + + } +#ifndef USING_NETCDF_PAR + if (!multifile) + { + info(0)<<"!!! Warning -> Using non parallel version of netcdf, switching in multiple_file mode for file : "<intraCommSize > 1) + { + oss << "_" ; + int width=0 ; int n=commSize-1 ; + while(n != 0) { n=n/10 ; width++ ;} + if (!min_digits.isEmpty()) + if (widthcloseFile() ; + bool isCollective=true ; + if (!par_access.isEmpty()) + { + if (par_access.getValue()=="independent") isCollective=false ; + else if (par_access.getValue()=="collective") isCollective=true ; + else + { + ERROR("void Context::createDataOutput(void)", + "incorrect file attribut : must be or , " + <<"having : <"<") ; + } + } + data_out=shared_ptr(new CNc4DataOutput(oss.str(), false, fileComm, multifile, isCollective)); + isOpen=true ; + + data_out->writeFile(CFile::get(this)); + std::vector::iterator it, end = this->enabledFields.end(); + for (it = this->enabledFields.begin() ;it != end; it++) + { + CField* field = *it; + this->data_out->writeFieldGrid(field); + } + this->data_out->writeTimeDimension(); + + for (it = this->enabledFields.begin() ;it != end; it++) + { + CField* field = *it; + this->data_out->writeField(field); + } + + vector listVars = getAllVariables() ; + for (vector::iterator it = listVars.begin() ;it != listVars.end(); it++) this-> data_out-> writeAttribute(*it) ; + + this->data_out->definition_end(); + } + } + + void CFile::close(void) + { + delete lastSync ; + delete lastSplit ; + if (!allDomainEmpty) + if (isOpen) + { + this->data_out->closeFile(); + } + if (fileComm != MPI_COMM_NULL) MPI_Comm_free(&fileComm) ; + } + //---------------------------------------------------------------- + + void CFile::parse(xml::CXMLNode & node) + { + SuperClass::parse(node); + + if (node.goToChildElement()) + { + do + { + if (node.getElementName()=="field" || node.getElementName()=="field_group") this->getVirtualFieldGroup()->parseChild(node); + else if (node.getElementName()=="variable" || node.getElementName()=="variable_group") this->getVirtualVariableGroup()->parseChild(node); + } while (node.goToNextElement()) ; + node.goToParentElement(); + } + + } + //---------------------------------------------------------------- + + StdString CFile::toString(void) const + { + StdOStringStream oss; + + oss << "<" << CFile::GetName() << " "; + if (this->hasId()) + oss << " id=\"" << this->getId() << "\" "; + oss << SuperClassAttribute::toString() << ">" << std::endl; + if (this->getVirtualFieldGroup() != NULL) + oss << *this->getVirtualFieldGroup() << std::endl; + oss << ""; + return (oss.str()); + } + + //---------------------------------------------------------------- + + void CFile::solveDescInheritance(bool apply, const CAttributeMap * const parent) + { + SuperClassAttribute::setAttributes(parent,apply); + this->getVirtualFieldGroup()->solveDescInheritance(apply, NULL); + this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL); + } + + //---------------------------------------------------------------- + + void CFile::processEnabledFile(void) + { + if (output_freq.isEmpty()) ERROR("void CFile::processEnabledFile(void)", + <<"File attribute <> is undefined"); + solveFieldRefInheritance(true) ; + getEnabledFields() ; + processEnabledFields() ; + } + + void CFile::processEnabledFields(void) + { + for (unsigned int i = 0; i < this->enabledFields.size(); i++) + { + this->enabledFields[i]->processEnabledField() ; + } + } + + void CFile::solveFieldRefInheritance(bool apply) + { + // Résolution des héritages par référence de chacun des champs contenus dans le fichier. + std::vector allF = this->getAllFields(); + for (unsigned int i = 0; i < allF.size(); i++) + allF[i]->solveRefInheritance(apply); + } + + //---------------------------------------------------------------- + + void CFile::solveEFGridRef(void) + { + for (unsigned int i = 0; i < this->enabledFields.size(); i++) + this->enabledFields[i]->solveGridReference(); + } + + //---------------------------------------------------------------- + + void CFile::solveEFOperation(void) + { + for (unsigned int i = 0; i < this->enabledFields.size(); i++) + this->enabledFields[i]->solveOperation(); + } + + void CFile::solveEFExpression(void) + { + for (unsigned int i = 0; i < this->enabledFields.size(); i++) + this->enabledFields[i]->buildExpression(); + } + + + CField* CFile::addField(const string& id) + { + return vFieldGroup->createChild(id) ; + } + + CFieldGroup* CFile::addFieldGroup(const string& id) + { + return vFieldGroup->createChildGroup(id) ; + } + + CVariable* CFile::addVariable(const string& id) + { + return vVariableGroup->createChild(id) ; + } + + CVariableGroup* CFile::addVariableGroup(const string& id) + { + return vVariableGroup->createChildGroup(id) ; + } + + + void CFile::sendAddField(const string& id) + { + CContext* context=CContext::getCurrent() ; + + if (! context->hasServer ) + { + CContextClient* client=context->client ; + + CEventClient event(this->getType(),EVENT_ID_ADD_FIELD) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + } + + void CFile::sendAddFieldGroup(const string& id) + { + CContext* context=CContext::getCurrent() ; + if (! context->hasServer ) + { + CContextClient* client=context->client ; + + CEventClient event(this->getType(),EVENT_ID_ADD_FIELD_GROUP) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + } + + void CFile::recvAddField(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + get(id)->recvAddField(*buffer) ; + } + + + void CFile::recvAddField(CBufferIn& buffer) + { + string id ; + buffer>>id ; + addField(id) ; + } + + void CFile::recvAddFieldGroup(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + get(id)->recvAddFieldGroup(*buffer) ; + } + + + void CFile::recvAddFieldGroup(CBufferIn& buffer) + { + string id ; + buffer>>id ; + addFieldGroup(id) ; + } + + + + + + + + + + + + void CFile::sendAddVariable(const string& id) + { + CContext* context=CContext::getCurrent() ; + + if (! context->hasServer ) + { + CContextClient* client=context->client ; + + CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + } + + void CFile::sendAddVariableGroup(const string& id) + { + CContext* context=CContext::getCurrent() ; + if (! context->hasServer ) + { + CContextClient* client=context->client ; + + CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + } + + void CFile::recvAddVariable(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + get(id)->recvAddVariable(*buffer) ; + } + + + void CFile::recvAddVariable(CBufferIn& buffer) + { + string id ; + buffer>>id ; + addVariable(id) ; + } + + void CFile::recvAddVariableGroup(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + get(id)->recvAddVariableGroup(*buffer) ; + } + + + void CFile::recvAddVariableGroup(CBufferIn& buffer) + { + string id ; + buffer>>id ; + addVariableGroup(id) ; + } + + + + + + bool CFile::dispatchEvent(CEventServer& event) + { + if (SuperClass::dispatchEvent(event)) return true ; + else + { + switch(event.type) + { + case EVENT_ID_ADD_FIELD : + recvAddField(event) ; + return true ; + break ; + + case EVENT_ID_ADD_FIELD_GROUP : + recvAddFieldGroup(event) ; + return true ; + break ; + + case EVENT_ID_ADD_VARIABLE : + recvAddVariable(event) ; + return true ; + break ; + + case EVENT_ID_ADD_VARIABLE_GROUP : + recvAddVariableGroup(event) ; + return true ; + break ; + default : + ERROR("bool CFile::dispatchEvent(CEventServer& event)", <<"Unknown Event") ; + return false ; + } + } + } + + + + + ///--------------------------------------------------------------- + +} // namespace xios diff --git a/src/node/file.hpp b/src/node/file.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a9fc3d249d1961efd5d98d942e8530729caa9671 --- /dev/null +++ b/src/node/file.hpp @@ -0,0 +1,154 @@ +#ifndef __XMLIO_CFile__ +#define __XMLIO_CFile__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "field.hpp" +#include "data_output.hpp" +#include "declare_group.hpp" +#include "date.hpp" +#include "attribute_enum.hpp" +#include "attribute_enum_impl.hpp" +#include "mpi.hpp" + + + +namespace xios { + + /// ////////////////////// Déclarations ////////////////////// /// + + class CFileGroup; + class CFileAttributes; + class CFile; + + ///-------------------------------------------------------------- + + // Declare/Define CFileAttribute + BEGIN_DECLARE_ATTRIBUTE_MAP(CFile) +# include "file_attribute.conf" + END_DECLARE_ATTRIBUTE_MAP(CFile) + + ///-------------------------------------------------------------- + + class CFile + : public CObjectTemplate + , public CFileAttributes + { + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CFileAttributes SuperClassAttribute; + + public : + enum EEventId + { + EVENT_ID_ADD_FIELD=0,EVENT_ID_ADD_FIELD_GROUP, EVENT_ID_ADD_VARIABLE,EVENT_ID_ADD_VARIABLE_GROUP + } ; + + typedef CFileAttributes RelAttributes; + typedef CFileGroup RelGroup; + + /// Constructeurs /// + CFile(void); + explicit CFile(const StdString & id); + CFile(const CFile & file); // Not implemented yet. + CFile(const CFile * const file); // Not implemented yet. + + /// Accesseurs /// + boost::shared_ptr getDataOutput(void) const; + CFieldGroup* getVirtualFieldGroup(void) const; + CVariableGroup* getVirtualVariableGroup(void) const; + std::vector getAllFields(void) const; + std::vector getAllVariables(void) const; + + std::vector getEnabledFields(int default_outputlevel = 5, + int default_level = 1, + bool default_enabled = true); + + public : + + /// Mutateurs /// + void setVirtualFieldGroup(CFieldGroup* newVFieldGroup); + void setVirtualFieldGroup(void); + void setVirtualVariableGroup(CVariableGroup* newVVariableGroup); + void setVirtualVariableGroup(void); + void processEnabledFile(void) ; + void processEnabledFields(void) ; + void createHeader(void); + void close(void) ; + + /// Traitements /// + virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0); + void solveFieldRefInheritance(bool apply); + void solveEFGridRef(void); + void solveEFOperation(void); + void solveEFExpression(void); + + /// Destructeur /// + virtual ~CFile(void); + + /// Autres /// + virtual void parse(xml::CXMLNode & node); + virtual StdString toString(void) const; + +// virtual void toBinary (StdOStream & os) const; +// virtual void fromBinary(StdIStream & is); + + /// Accesseurs statiques /// + static StdString GetName(void); + static StdString GetDefName(void); + + static ENodeType GetType(void); + + bool allDomainEmpty ; + CField* addField(const string& id="") ; + CFieldGroup* addFieldGroup(const string& id="") ; + CVariable* addVariable(const string& id="") ; + CVariableGroup* addVariableGroup(const string& id="") ; + void sendAddField(const string& id="") ; + void sendAddFieldGroup(const string& id="") ; + static void recvAddField(CEventServer& event) ; + void recvAddField(CBufferIn& buffer) ; + static void recvAddFieldGroup(CEventServer& event) ; + void recvAddFieldGroup(CBufferIn& buffer) ; + + void sendAddVariable(const string& id="") ; + void sendAddVariableGroup(const string& id="") ; + static void recvAddVariable(CEventServer& event) ; + void recvAddVariable(CBufferIn& buffer) ; + static void recvAddVariableGroup(CEventServer& event) ; + void recvAddVariableGroup(CBufferIn& buffer) ; + static bool dispatchEvent(CEventServer& event) ; + + bool isSyncTime(void) ; + bool checkSplit(void) ; + bool checkSync(void) ; + void checkFile(void) ; + void initFile(void) ; + CDate* lastSync ; + CDate* lastSplit ; + CDuration syncFreq ; + CDuration splitFreq ; + CDuration outputFreq ; + int nbDomain ; + bool isOpen ; + MPI_Comm fileComm ; + private : + + /// Propriétés privées /// + CFieldGroup* vFieldGroup; + CVariableGroup* vVariableGroup ; + boost::shared_ptr data_out; + std::vector enabledFields; + + }; // class CFile + + ///-------------------------------------------------------------- + + // Declare/Define CFileGroup and CFileDefinition + DECLARE_GROUP(CFile); + + ///-------------------------------------------------------------- + +} // namespace xios + +#endif // __XMLIO_CFile__ diff --git a/src/node/grid.cpp b/src/node/grid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8777a6569817858b8bcee4ed45a0c543806e28a8 --- /dev/null +++ b/src/node/grid.cpp @@ -0,0 +1,550 @@ + +#include "grid.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "message.hpp" +#include +#include "xmlioserver_spl.hpp" +#include "type.hpp" +#include "context.hpp" +#include "context_client.hpp" +#include "array_new.hpp" + +namespace xios { + + /// ////////////////////// Définitions ////////////////////// /// + + CGrid::CGrid(void) + : CObjectTemplate(), CGridAttributes() + , withAxis(false), isChecked(false), axis(), domain() + , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1) + { /* Ne rien faire de plus */ } + + CGrid::CGrid(const StdString & id) + : CObjectTemplate(id), CGridAttributes() + , withAxis(false), isChecked(false), axis(), domain() + , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1) + { /* Ne rien faire de plus */ } + + CGrid::~CGrid(void) + { + // this->axis.reset() ; +// this->domain.reset() ; + deque< CArray* >::iterator it ; + + for(deque< CArray* >::iterator it=storeIndex.begin(); it!=storeIndex.end();it++) delete *it ; + for(deque< CArray* >::iterator it=out_i_index.begin();it!=out_i_index.end();it++) delete *it ; + for(deque< CArray* >::iterator it=out_j_index.begin();it!=out_j_index.end();it++) delete *it ; + for(deque< CArray* >::iterator it=out_l_index.begin();it!=out_l_index.end();it++) delete *it ; + + for(map* >::iterator it=out_i_fromClient.begin();it!=out_i_fromClient.end();it++) delete it->second ; + for(map* >::iterator it=out_j_fromClient.begin();it!=out_j_fromClient.end();it++) delete it->second ; + for(map* >::iterator it=out_l_fromClient.begin();it!=out_l_fromClient.end();it++) delete it->second ; + + } + + ///--------------------------------------------------------------- + + StdString CGrid::GetName(void) { return (StdString("grid")); } + StdString CGrid::GetDefName(void) { return (CGrid::GetName()); } + ENodeType CGrid::GetType(void) { return (eGrid); } + + //---------------------------------------------------------------- + + const std::deque< CArray* > & CGrid::getStoreIndex(void) const + { + return (this->storeIndex ); + } + + //--------------------------------------------------------------- + + const std::deque< CArray* > & CGrid::getOutIIndex(void) const + { + return (this->out_i_index ); + } + + //--------------------------------------------------------------- + + const std::deque< CArray* > & CGrid::getOutJIndex(void) const + { + return (this->out_j_index ); + } + + //--------------------------------------------------------------- + + const std::deque< CArray* > & CGrid::getOutLIndex(void) const + { + return (this->out_l_index ); + } + + //--------------------------------------------------------------- + + const CAxis* CGrid::getRelAxis (void) const + { + return (this->axis ); + } + + //--------------------------------------------------------------- + + const CDomain* CGrid::getRelDomain(void) const + { + return (this->domain ); + } + + //--------------------------------------------------------------- + + bool CGrid::hasAxis(void) const + { + return (this->withAxis); + } + + //--------------------------------------------------------------- + + StdSize CGrid::getDimension(void) const + { + return ((this->withAxis)?3:2); + } + + //--------------------------------------------------------------- + +/* + std::vector CGrid::getLocalShape(void) const + { + std::vector retvalue; + retvalue.push_back(domain->zoom_ni_loc.getValue()); + retvalue.push_back(domain->zoom_nj_loc.getValue()); + if (this->withAxis) + retvalue.push_back(this->axis->zoom_size.getValue()); + return (retvalue); + } +*/ + //--------------------------------------------------------------- + +/* + StdSize CGrid::getLocalSize(void) const + { + StdSize retvalue = 1; + std::vector shape_ = this->getLocalShape(); + for (StdSize s = 0; s < shape_.size(); s++) + retvalue *= shape_[s]; + return (retvalue); + } +*/ + //--------------------------------------------------------------- +/* + std::vector CGrid::getGlobalShape(void) const + { + std::vector retvalue; + retvalue.push_back(domain->ni.getValue()); + retvalue.push_back(domain->nj.getValue()); + if (this->withAxis) + retvalue.push_back(this->axis->size.getValue()); + return (retvalue); + } +*/ + //--------------------------------------------------------------- + +/* + StdSize CGrid::getGlobalSize(void) const + { + StdSize retvalue = 1; + std::vector shape_ = this->getGlobalShape(); + for (StdSize s = 0; s < shape_.size(); s++) + retvalue *= shape_[s]; + return (retvalue); + } +*/ + StdSize CGrid::getDataSize(void) const + { + StdSize retvalue=domain->data_ni.getValue() ; + if (domain->data_dim.getValue()==2) retvalue*=domain->data_nj.getValue() ; + if (this->withAxis) retvalue*=this->axis->size.getValue() ; + + return (retvalue); + } + + //--------------------------------------------------------------- + + void CGrid::solveReference(void) + { + if (this->isChecked) return; + CContext* context = CContext::getCurrent() ; + CContextClient* client=context->client ; + + this->solveDomainRef() ; + this->solveAxisRef() ; + + if (context->hasClient) + { + checkMask() ; + this->computeIndex() ; + + this->storeIndex.push_front(new CArray() ); + this->out_i_index.push_front(new CArray()); + this->out_j_index.push_front(new CArray()); + this->out_l_index.push_front(new CArray()); + } +// this->computeIndexServer(); + this->isChecked = true; + } + + + void CGrid::checkMask(void) + { + using namespace std; + + unsigned int niu = domain->ni, nju = domain->nj; + unsigned int nlu = 1 ; + if (hasAxis()) nlu=axis->size ; + + if (!mask.isEmpty()) + { + if ((mask.extent(0) != niu) || + (mask.extent(1) != nju) || + (mask.extent(2) != nlu)) + ERROR("CGrid::checkAttributes(void)", + <<"The mask has not the same size than the local grid"<& domainMask = domain->mask ; + for (int l=0; l < nlu ; l++) + for (int j=0; j < nju ; j++) + for(int i=0; idomain = CDomain::get(domain_ref.getValue()) ; + domain->checkAttributes() ; + } + else ERROR("CGrid::solveDomainRef(void)", + << "Wrong domain reference") ; + } + else ERROR("CGrid::solveDomainRef(void)", + << "Domain reference is not defined") ; + } + + //--------------------------------------------------------------- + + void CGrid::solveAxisRef(void) + { + if (!axis_ref.isEmpty()) + { + this->withAxis = true ; + if (CAxis::get(axis_ref.getValue())) + { + this->axis = CAxis::get(axis_ref.getValue()) ; + axis->checkAttributes() ; + } + else ERROR("CGrid::solveAxisRef(void)", + << "Wrong axis reference") ; + } + else withAxis = false ; + } + + //--------------------------------------------------------------- + + void CGrid::computeIndex(void) + { + + const int ni = domain->ni.getValue() , + nj = domain->nj.getValue() , + size = (this->hasAxis()) ? axis->size.getValue() : 1 , + lbegin = (this->hasAxis()) ? axis->zoom_begin.getValue()-1 : 0 , + lend = (this->hasAxis()) ? axis->zoom_end.getValue()-1 : 0 ; + + + const int data_dim = domain->data_dim.getValue() , + data_n_index = domain->data_n_index.getValue() , + data_ibegin = domain->data_ibegin.getValue() , + data_jbegin = (data_dim == 2) + ? domain->data_jbegin.getValue() : -1; + + CArray data_i_index = domain->data_i_index ; + CArray data_j_index = domain->data_j_index ; + + + int indexCount = 0; + + for(int l = 0; l < size ; l++) + { + for(int n = 0, i = 0, j = 0; n < data_n_index; n++) + { + int temp_i = data_i_index(n) + data_ibegin, + temp_j = (data_dim == 1) ? -1 + : data_j_index(n) + data_jbegin; + i = (data_dim == 1) ? (temp_i - 1) % ni + : (temp_i - 1) ; + j = (data_dim == 1) ? (temp_i - 1) / ni + : (temp_j - 1) ; + + if ((l >=lbegin && l<= lend) && + (i >= 0 && i < ni) && + (j >= 0 && j < nj) && mask(i,j,l)) + indexCount++ ; + } + } + + storeIndex[0] = new CArray(indexCount) ; + out_i_index[0] = new CArray(indexCount) ; + out_j_index[0] = new CArray(indexCount) ; + out_l_index[0] = new CArray(indexCount) ; + + storeIndex_client.resize(indexCount) ; + out_i_client.resize(indexCount) ; + out_j_client.resize(indexCount) ; + out_l_client.resize(indexCount) ; + + + for(int count = 0, indexCount = 0, l = 0; l < size; l++) + { + for(int n = 0, i = 0, j = 0; n < data_n_index; n++, count++) + { + int temp_i = data_i_index(n) + data_ibegin, + temp_j = (data_dim == 1) ? -1 + : data_j_index(n) + data_jbegin; + i = (data_dim == 1) ? (temp_i - 1) % ni + : (temp_i - 1) ; + j = (data_dim == 1) ? (temp_i - 1) / ni + : (temp_j - 1) ; + + if ((l >= lbegin && l <= lend) && + (i >= 0 && i < ni) && + (j >= 0 && j < nj) && mask(i,j,l)) + { + (*storeIndex[0])(indexCount) = count ; + (*out_l_index[0])(indexCount) = l ; + (*out_i_index[0])(indexCount) = i ; + (*out_j_index[0])(indexCount) = j ; + + storeIndex_client(indexCount) = count ; + out_i_client(indexCount)=i+domain->ibegin_client-1 ; + out_j_client(indexCount)=j+domain->jbegin_client-1 ; + out_l_client(indexCount)=l-lbegin ; + indexCount++ ; + } + } + } + sendIndex() ; + + + } + + //---------------------------------------------------------------- + + CGrid* CGrid::createGrid(CDomain* domain) + { + StdString new_id = StdString("__") + domain->getId() + StdString("__") ; + CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ; + grid->domain_ref.setValue(domain->getId()); + return (grid); + } + + CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis) + { + StdString new_id = StdString("__") + domain->getId() + + StdString("_") + axis->getId() + StdString("__") ; + CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ; + grid->domain_ref.setValue(domain->getId()); + grid->axis_ref.setValue(axis->getId()); + return (grid); + } + + //---------------------------------------------------------------- + + void CGrid::outputField(int rank, const CArray& stored, CArray& field) + { + CArray& out_i=*out_i_fromClient[rank] ; + CArray& out_j=*out_j_fromClient[rank] ; + CArray& out_l=*out_l_fromClient[rank] ; + + for(StdSize n = 0; n < stored.numElements(); n++) + field(out_i(n), out_j(n), out_l(n)) = stored(n) ; + } + + void CGrid::outputField(int rank, const CArray& stored, CArray& field) + { + CArray& out_i=*out_i_fromClient[rank] ; + CArray& out_j=*out_j_fromClient[rank] ; + + for(StdSize n = 0; n < stored.numElements(); n++) + field(out_i(n), out_j(n)) = stored(n) ; } + + //--------------------------------------------------------------- + + void CGrid::outputField(int rank,const CArray& stored, CArray& field) + { + CArray& out_i=*out_i_fromClient[rank] ; + + for(StdSize n = 0; n < stored.numElements(); n++) + field(out_i(n)) = stored(n) ; + } + + //---------------------------------------------------------------- + + + void CGrid::storeField_arr + (const double * const data, CArray& stored) const + { + const StdSize size = storeIndex_client.numElements() ; + + stored.resize(size) ; + for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)] ; + } + + //--------------------------------------------------------------- + + void CGrid::sendIndex(void) + { + CContext* context = CContext::getCurrent() ; + CContextClient* client=context->client ; + + CEventClient event(getType(),EVENT_ID_INDEX) ; + int rank ; + list > list_msg ; + list< CArray* > list_out_i,list_out_j,list_out_l ; + + for(int ns=0;nsconnectedServer.size();ns++) + { + rank=domain->connectedServer[ns] ; + + int i,j ; + int nb=0 ; + for(int k=0;kibegin +1; + j=out_j_client(k)- domain->jbegin +1; + if (domain->mapConnectedServer(i,j)==ns) nb++ ; + } + + CArray storeIndex(nb) ; + CArray out_i(nb) ; + CArray out_j(nb) ; + CArray out_l(nb) ; + + + nb=0 ; + for(int k=0;kibegin +1 ; + j=out_j_client(k)- domain->jbegin +1 ; + if (domain->mapConnectedServer(i,j)==ns) + { + storeIndex(nb)=k ; + out_i(nb)=domain->i_index(i,j) + domain->ibegin-1; + out_j(nb)=domain->j_index(i,j) + domain->jbegin-1; + out_l(nb)=out_l_client(k) ; + nb++ ; + } + } + + storeIndex_toSrv.insert( pair* >(rank,new CArray(storeIndex) )) ; + nbSenders.insert(pair(rank,domain->nbSenders[ns])) ; + list_msg.push_back(shared_ptr(new CMessage)) ; + list_out_i.push_back(new CArray(out_i)) ; + list_out_j.push_back(new CArray(out_j)) ; + list_out_l.push_back(new CArray(out_l)) ; + + *list_msg.back()<nbSenders[ns],*list_msg.back()) ; + } + client->sendEvent(event) ; + + for(list* >::iterator it=list_out_i.begin();it!=list_out_i.end();it++) delete *it ; + for(list* >::iterator it=list_out_j.begin();it!=list_out_j.end();it++) delete *it ; + for(list* >::iterator it=list_out_l.begin();it!=list_out_l.end();it++) delete *it ; + + } + + void CGrid::recvIndex(CEventServer& event) + { + list::iterator it ; + for (it=event.subEvents.begin();it!=event.subEvents.end();++it) + { + int rank=it->rank; + CBufferIn* buffer=it->buffer; + string domainId ; + *buffer>>domainId ; + get(domainId)->recvIndex(rank,*buffer) ; + } + } + + void CGrid::recvIndex(int rank, CBufferIn& buffer) + { + CArray out_i ; + CArray out_j ; + CArray out_l ; + + buffer>>out_i>>out_j>>out_l ; + + out_i -= domain->zoom_ibegin_srv-1 ; + out_j -= domain->zoom_jbegin_srv-1 ; + + out_i_fromClient.insert(pair< int,CArray* >(rank,new CArray(out_i) )) ; + out_j_fromClient.insert(pair< int,CArray* >(rank,new CArray(out_j) )) ; + out_l_fromClient.insert(pair< int,CArray* >(rank,new CArray(out_l) )) ; + } + + bool CGrid::dispatchEvent(CEventServer& event) + { + + if (SuperClass::dispatchEvent(event)) return true ; + else + { + switch(event.type) + { + case EVENT_ID_INDEX : + recvIndex(event) ; + return true ; + break ; + + default : + ERROR("bool CDomain::dispatchEvent(CEventServer& event)", + <<"Unknown Event") ; + return false ; + } + } + } + + void CGrid::inputFieldServer(const std::deque< CArray* > storedClient, CArray& storedServer) const + { + if ((this->storeIndex.size()-1 ) != storedClient.size()) + ERROR("void CGrid::inputFieldServer(const std::deque< CArray* > storedClient, CArray& storedServer) const", + << "[ Expected received field = " << (this->storeIndex.size()-1) << ", " + << "[ received fiedl = " << storedClient.size() << "] " + << "Data from clients are missing!") ; + storedServer.resize(storeIndex[0]->numElements()); + + for (StdSize i = 0, n = 0; i < storedClient.size(); i++) + for (StdSize j = 0; j < storedClient[i]->numElements(); j++) + storedServer(n++) = (*storedClient[i])(j); + } + + void CGrid::outputFieldToServer(CArray& fieldIn, int rank, CArray& fieldOut) + { + CArray& index = *storeIndex_toSrv[rank] ; + int nb=index.numElements() ; + fieldOut.resize(nb) ; + + for(int k=0;k + , public CGridAttributes + { + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CGridAttributes SuperClassAttribute; + + public : + + typedef CGridAttributes RelAttributes; + typedef CGridGroup RelGroup; + + enum EEventId + { + EVENT_ID_INDEX + } ; + + /// Constructeurs /// + CGrid(void); + explicit CGrid(const StdString & id); + CGrid(const CGrid & grid); // Not implemented yet. + CGrid(const CGrid * const grid); // Not implemented yet. + + /// Traitements /// + void solveReference(void); + + // virtual void toBinary (StdOStream & os) const; +// virtual void fromBinary(StdIStream & is); + + /// Tests /// + bool hasAxis(void) const; + + public : + + /// Accesseurs /// + const std::deque< CArray* > & getStoreIndex(void) const; + const std::deque< CArray* > & getOutIIndex(void) const; + const std::deque< CArray* > & getOutJIndex(void) const; + const std::deque< CArray* > & getOutLIndex(void) const; + + const CAxis* getRelAxis (void) const; + const CDomain* getRelDomain(void) const; + + StdSize getDimension(void) const; + +// StdSize getLocalSize(void) const; +// StdSize getGlobalSize(void) const; + StdSize getDataSize(void) const; +// std::vector getLocalShape(void) const; +// std::vector getGlobalShape(void) const; + + /// Entrées-sorties de champs /// + template + void inputField(const CArray& field, CArray& stored) const; + + void inputFieldServer(const std::deque< CArray* > storedClient, + CArray& storedServer) const; + + void outputField(int rank, const CArray& stored, CArray& field) ; + void outputField(int rank, const CArray& stored, CArray& field) ; + void outputField(int rank, const CArray& stored, CArray& field) ; + + /// Destructeur /// + virtual ~CGrid(void); + + public : + + /// Accesseurs statiques /// + static StdString GetName(void); + static StdString GetDefName(void); + + static ENodeType GetType(void); + + /// Instanciateurs Statiques /// + static CGrid* createGrid(CDomain* domain); + static CGrid* createGrid(CDomain* domain, CAxis* axis); + + public : + + /// Entrées-sorties de champs (interne) /// + void storeField_arr(const double * const data, CArray& stored) const; + + /// Traitements protégés /// + void computeIndexServer(void); + void computeIndex(void); + void solveDomainRef(void); + void solveAxisRef(void); + + static bool dispatchEvent(CEventServer& event) ; + void outputFieldToServer(CArray& fieldIn, int rank, CArray& fieldOut) ; + static void recvIndex(CEventServer& event) ; + void recvIndex(int rank, CBufferIn& buffer) ; + void sendIndex(void) ; + + public: + + /// Propriétés privées /// + bool withAxis ; + bool isChecked; + + CAxis* axis ; + CDomain* domain ; + + std::deque< CArray* > storeIndex ; + std::deque< CArray* > out_i_index ; + std::deque< CArray* > out_j_index ; + std::deque< CArray* > out_l_index ; + + CArray storeIndex_client ; + CArray out_i_client ; + CArray out_j_client ; + CArray out_l_client ; + + map* > storeIndex_toSrv ; + map nbSenders ; +// std::deque out_i_toSrv ; +// std::deque out_j_toSrv ; +// std::deque out_l_toSrv ; + + map* > out_i_fromClient ; + map* > out_j_fromClient ; + map* > out_l_fromClient ; + void checkMask(void) ; + }; // class CGrid + + ///-------------------------------------------------------------- + + template + void CGrid::inputField(const CArray& field, CArray& stored) const + { + if (this->getDataSize() != field.numElements()) + ERROR("void CGrid::inputField(const CArray& field, CArray& stored) const", + << "[ Awaiting size of the data = " << this->getDataSize() << ", " + << "Received data size = " << field.numElements() << " ] " + << "The array of data has not the good size !") + this->storeField_arr(field.dataFirst(), stored) ; + } + + ///-------------------------------------------------------------- + + // Declare/Define CGridGroup and CGridDefinition + DECLARE_GROUP(CGrid); + + ///-------------------------------------------------------------- + +} // namespace xios + +#endif // __XMLIO_CGrid__ diff --git a/src/node/method.hpp b/src/node/method.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f34109a39744e32e975273bb2a9adf1346fa1ad6 --- /dev/null +++ b/src/node/method.hpp @@ -0,0 +1,99 @@ +#ifndef __XMLIO_CMethod__ +#define __XMLIO_CMethod__ + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + + class CMethodGroup; + class CMethodAttributes; + class CBaseMethod; + class CMethod; + + ///-------------------------------------------------------------- + + // Declare/Define CMethodAttribute + BEGIN_DECLARE_ATTRIBUTE_MAP(CMethod) +#include "method_attribute.conf" + END_DECLARE_ATTRIBUTE_MAP(CMethod) + + ///-------------------------------------------------------------- + + class CBaseMethod + { // Declare CMethod functionalities + public : + + /// Constructeur et Destructeur /// + CBaseMethod(void); + ~CBaseMethod(void); + + }; // class CBaseMethod + + ///-------------------------------------------------------------- + + class CMethod + : public CObjectTemplate + , public CMethodAttributes + , public CBaseMethod + { + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CMethodAttributes SuperClassAttribute; + typedef CBaseMethod SuperClassBase; + + public : + + typedef CMethodAttributes RelAttributes; + typedef CMethodGroup RelGroup; + + /// Constructeurs /// + CMethod(void); + explicit CMethod(const StdString & id); + CMethod(const CMethod & method); // Not implemented yet. + CMethod(const CMethod * const method); // Not implemented yet. + + /// Destructeur /// + virtual ~CMethod(void); + + /// Accesseurs statiques /// + static inline StdString GetName(void); + static inline StdString GetDefName(void); + + }; // class CMethod + + ///-------------------------------------------------------------- + + // Declare/Define CMethodGroup and CMethodDefinition + DECLARE_GROUP(CMethod); + + /// ////////////////////// Définitions ////////////////////// /// + + CBaseMethod::CBaseMethod(void) + { /* Ne rien faire de plus */ } + + CBaseMethod::~CBaseMethod(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + CMethod::CMethod(void) + : CObjectTemplate() + , CMethodAttributes() + , CBaseMethod() + { /* Ne rien faire de plus */ } + + CMethod::CMethod(const StdString & id) + : CObjectTemplate(id) + , CMethodAttributes() + , CBaseMethod() + { /* Ne rien faire de plus */ } + + CMethod::~CMethod(void) + { /* Ne rien faire de plus */ } + + StdString CMethod::GetName(void) { return (StdString("method")); } + StdString CMethod::GetDefName(void){ return (CMethod::GetName()); } + +} // namespace xios + +#endif // __XMLIO_CMethod__ diff --git a/src/node/node_enum.hpp b/src/node/node_enum.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b86959289b125de0536cf68281a408dd54119daa --- /dev/null +++ b/src/node/node_enum.hpp @@ -0,0 +1,27 @@ +#ifndef __XMLIO_NODE_ENUM__ +#define __XMLIO_NODE_ENUM__ + +//#define DECLARE_NODE(Name_, name_) ,e##Name_, g##Name_ +//#define DECLARE_NODE_PAR(Name_, name_) ,e##Name_, g##Name_ + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + typedef enum _node_type + { + Unknown = 0, + eAxis,gAxis, + eDomain,gDomain, + eField,gField, + eFile,gFile, + eGrid,gGrid, + eVariable,gVariable, + eContext,gContext + +//#include "node_type.conf" + + } ENodeType; + +} // namespace xios + +#endif // __XMLIO_NODE_ENUM__ diff --git a/src/node/node_type.hpp b/src/node/node_type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6804c629ba63be3407b72fccaf98aff52c0a5cd5 --- /dev/null +++ b/src/node/node_type.hpp @@ -0,0 +1,12 @@ +#ifndef __XMLIO_NODE_TYPE__ +#define __XMLIO_NODE_TYPE__ + +#include "axis.hpp" +#include "domain.hpp" +#include "field.hpp" +#include "file.hpp" +#include "grid.hpp" +#include "variable.hpp" +#include "context.hpp" + +#endif // __XMLIO_NODE_TYPE__ diff --git a/src/node/var.hpp b/src/node/var.hpp new file mode 100644 index 0000000000000000000000000000000000000000..95b3f8f0bcc3f056e8c08b60f02090f4f2699a42 --- /dev/null +++ b/src/node/var.hpp @@ -0,0 +1,99 @@ +#ifndef __XMLIO_CVar__ +#define __XMLIO_CVar__ + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + + class CVarGroup; + class CVarAttributes; + class CBaseVar; + class CVar; + + ///-------------------------------------------------------------- + + // Declare/Define CVarAttribute + BEGIN_DECLARE_ATTRIBUTE_MAP(CVar) +#include "var_attribute.conf" + END_DECLARE_ATTRIBUTE_MAP(CVar) + + ///-------------------------------------------------------------- + + class CBaseVar + { // Declare CVar functionalities + public : + + /// Constructeur et Destructeur /// + CBaseVar(void); + ~CBaseVar(void); + + }; // class CBaseVar + + ///-------------------------------------------------------------- + + class CVar + : public CObjectTemplate + , public CVarAttributes + , public CBaseVar + { + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CVarAttributes SuperClassAttribute; + typedef CBaseVar SuperClassBase; + + public : + + typedef CVarAttributes RelAttributes; + typedef CVarGroup RelGroup; + + /// Constructeurs /// + CVar(void); + explicit CVar(const StdString & id); + CVar(const CVar & var); // Not implemented yet. + CVar(const CVar * const var); // Not implemented yet. + + /// Destructeur /// + virtual ~CVar(void); + + /// Accesseurs statiques /// + static inline StdString GetName(void); + static inline StdString GetDefName(void); + + }; // class CVar + + ///-------------------------------------------------------------- + + // Declare/Define CVarGroup and CVarDefinition + DECLARE_GROUP(CVar); + + /// ////////////////////// Définitions ////////////////////// /// + + CBaseVar::CBaseVar(void) + { /* Ne rien faire de plus */ } + + CBaseVar::~CBaseVar(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + CVar::CVar(void) + : CObjectTemplate() + , CVarAttributes() + , CBaseVar() + { /* Ne rien faire de plus */ } + + CVar::CVar(const StdString & id) + : CObjectTemplate(id) + , CVarAttributes() + , CBaseVar() + { /* Ne rien faire de plus */ } + + CVar::~CVar(void) + { /* Ne rien faire de plus */ } + + StdString CVar::GetName(void) { return (StdString("var")); } + StdString CVar::GetDefName(void){ return (CVar::GetName()); } + +} // namespace xios + +#endif // __XMLIO_CVar__ diff --git a/src/node/variable.cpp b/src/node/variable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72f2245c5fef0759e160f9e7d5b34458d58a19ac --- /dev/null +++ b/src/node/variable.cpp @@ -0,0 +1,212 @@ +#include "variable.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" +#include "object_factory.hpp" +#include "xmlioserver_spl.hpp" +#include "type.hpp" +#include "context.hpp" +#include "context_client.hpp" +#include + +namespace xios { + + /// ////////////////////// Définitions ////////////////////// /// + + CVariable::CVariable(void) + : CObjectTemplate() + , CVariableAttributes() + , content() + { /* Ne rien faire de plus */ } + + CVariable::CVariable(const StdString & id) + : CObjectTemplate(id) + , CVariableAttributes() + , content() + { /* Ne rien faire de plus */ } + + CVariable::~CVariable(void) + { /* Ne rien faire de plus */ } + + StdString CVariable::GetName(void) { return (StdString("variable")); } + StdString CVariable::GetDefName(void){ return (CVariable::GetName()); } + ENodeType CVariable::GetType(void) { return (eVariable); } + + void CVariable::parse(xml::CXMLNode & node) + { + SuperClass::parse(node); + StdString id = (this->hasId()) ? this->getId() : StdString("undefined"); + if (!node.getContent(this->content)) + { + ERROR("CVariable::parse(xml::CXMLNode & node)", + << "[ variable id = " << id + << " ] variable is not defined !"); + } + content = boost::trim_copy(content) ; + } + + const StdString & CVariable::getContent (void) const + { + return (this->content); + } + + void CVariable::setContent(const StdString& contentStr) + { + this->content = contentStr; + } + + StdString CVariable::toString(void) const + { + StdOStringStream oss; + + oss << "<" << CVariable::GetName() << " "; + if (this->hasId()) + oss << " id=\"" << this->getId() << "\" "; + oss << SuperClassAttribute::toString() << ">" << std::endl + << this->content /*<< std::endl*/; + oss << ""; + return (oss.str()); + } + + CVariable::EVarType CVariable::getVarType(void) const + { + EVarType ret ; + + if (type.isEmpty()) ret=t_undefined ; + else + { + string varType=boost::to_lower_copy(boost::trim_copy(type.getValue())) ; + if (varType=="int") ret=t_int ; + else if (varType=="short int" || varType=="short") ret=t_short_int ; + else if (varType=="long int" || varType=="long") ret=t_long_int ; + else if (varType=="float") ret=t_float ; + else if (varType=="double") ret=t_double ; + else if (varType=="long double") ret=t_long_double ; + else if (varType=="bool") ret=t_bool ; + else if (varType=="long double") ret=t_long_double ; + else if (varType=="string") ret=t_string ; + } + return ret ; + } + + /* + *\brief Sending value of a variable with its id from client to server + * + */ + void CVariable::sendValue() + { + CContext* context=CContext::getCurrent() ; + if (!context->hasServer) + { + CContextClient* client=context->client ; + + CEventClient event(this->getType(),EVENT_ID_VARIABLE_VALUE) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + } + + /* + *\brief Receive value of a variable with its id from client to server + * + */ + void CVariable::recvValue(CEventServer& event) + { + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id; + *buffer>>id ; + get(id)->recvValue(*buffer); + } + + + /* + *\brief Receive value of a variable with its id from client to server + * + */ + void CVariable::recvValue(CBufferIn& buffer) + { + string str ; + buffer>>str; + setContent(str); + } + + bool CVariable::dispatchEvent(CEventServer& event) + { + if (SuperClass::dispatchEvent(event)) return true ; + else + { + switch(event.type) + { + case EVENT_ID_VARIABLE_VALUE : + recvValue(event) ; + return true ; + break ; + + default : + ERROR("bool CVariable::dispatchEvent(CEventServer& event)",<<"Unknown Event") ; + return false ; + } + } + } + +/* + void CVariable::toBinary(StdOStream & os) const + { + const StdString & content = this->content; + const StdSize size = content.size(); + SuperClass::toBinary(os); + + os.write (reinterpret_cast(&size), sizeof(StdSize)); + os.write (content.data(), size * sizeof(char)); + } + + void CVariable::fromBinary(StdIStream & is) + { + SuperClass::fromBinary(is); + StdSize size = 0; + is.read (reinterpret_cast(&size), sizeof(StdSize)); + this->content.assign(size, ' '); + is.read (const_cast(this->content.data()), size * sizeof(char)); + } +*/ + void CVariableGroup::parse(xml::CXMLNode & node, bool withAttr) + { + CVariableGroup* group_ptr = (this->hasId()) + ? CVariableGroup::get(this->getId()) : CVariableGroup::get(this); + + StdString content; + if (this->getId().compare(CVariableGroup::GetDefName()) != 0 && node.getContent(content)) + { + StdSize beginid = 0, endid = 0, begindata = 0, enddata = 0; + StdString subdata, subid; + + while ((beginid = content.find_first_not_of ( " \r\n\t;", enddata)) != StdString::npos) + { + endid = content.find_first_of ( " \r\n\t=", beginid ); + subid = content.substr ( beginid, endid-beginid); + subid = boost::to_lower_copy(boost::trim_copy(subid)) ; + + begindata = content.find_first_of ( "=", endid ) + 1; + enddata = content.find_first_of ( ";", begindata ); + subdata = content.substr ( begindata, enddata-begindata); + subdata = boost::trim_copy(subdata) ; + group_ptr->createChild(subid)->content = subdata ; + } + } + else + { + SuperClass::parse(node, withAttr); + } + //SuperClass::parse(node, withAttr); + + } + +} // namespace xios diff --git a/src/node/variable.hpp b/src/node/variable.hpp new file mode 100644 index 0000000000000000000000000000000000000000..be3fddb2c8fa8ff5bed6361d8c4a6d5289bd4e2c --- /dev/null +++ b/src/node/variable.hpp @@ -0,0 +1,150 @@ +#ifndef __XMLIO_CVariable__ +#define __XMLIO_CVariable__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "declare_group.hpp" +#include "group_template.hpp" +#include "array_new.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + + class CVariableGroup; + class CVariableAttributes; + class CVariable; + class CContext; + ///-------------------------------------------------------------- + + // Declare/Define CVarAttribute + BEGIN_DECLARE_ATTRIBUTE_MAP(CVariable) +#include "var_attribute.conf" + END_DECLARE_ATTRIBUTE_MAP(CVariable) + + ///-------------------------------------------------------------- + + class CVariable + : public CObjectTemplate + , public CVariableAttributes + { + enum EEventId + { + EVENT_ID_VARIABLE_VALUE + }; + + /// typedef /// + typedef CObjectTemplate SuperClass; + typedef CVariableAttributes SuperClassAttribute; + + friend class CVariableGroup; + + public : + + typedef CVariableAttributes RelAttributes; + typedef CVariableGroup RelGroup; + + /// Constructeurs /// + CVariable(void); + explicit CVariable(const StdString & id); + CVariable(const CVariable & var); // Not implemented yet. + CVariable(const CVariable * const var); // Not implemented yet. + + /// Destructeur /// + virtual ~CVariable(void); + + public : + enum EVarType + { t_int, t_short_int, t_long_int, t_float, t_double, t_long_double, t_bool, t_string, t_undefined } ; + + + /// Autres /// + virtual void parse(xml::CXMLNode & node); + virtual StdString toString(void) const; + + /// Accesseur /// + const StdString & getContent (void) const; + + void setContent(const StdString& content); + + + template inline T getData(void) const; + template inline void setData(T data); + + template + inline void getData(CArray& _data_array) const; + + EVarType getVarType(void) const ; + + static bool dispatchEvent(CEventServer& event) ; + + //! Sending a request to set up variable data + void sendValue(); + + static void recvValue(CEventServer& event) ; + void recvValue(CBufferIn& buffer) ; + + public : + + /// Accesseurs statiques /// + static StdString GetName(void); + static StdString GetDefName(void); + static ENodeType GetType(void); + + private : + + StdString content; + + }; // class CVar + + template + inline T CVariable::getData(void) const + { + T retval ; + std::stringstream sstr(std::stringstream::in | std::stringstream::out); + sstr<>retval ; + if (sstr.fail()) ERROR("CVariable::getdata()", + << "Cannot convert string <" << content << "> into type required" ); + return retval ; + } + + template<> + inline bool CVariable::getData(void) const + { + if (content.compare("true")==0 || content.compare(".true.")==0 || content.compare(".TRUE.")==0) return true ; + else if (content.compare("false")==0 || content.compare(".false.")==0 || content.compare(".FALSE.")==0) return false ; + else ERROR("CVariable::getdata()", + << "Cannot convert string <" << content << "> into type required" ); + return false ; + } + + template<> + inline std::string CVariable::getData(void) const + { return content; } + + template<> + inline void CVariable::setData(bool data) + { + if (true == data) content.assign("true"); + else content.assign("false"); + } + + template + inline void CVariable::setData(T data) + { + std::stringstream sstr; + sstr<id); + } + + bool CObject::hasId(void) const + { + return (this->IdDefined); + } + + void CObject::resetId(void) + { + this->IdDefined = false ; + } + + void CObject::setId(const StdString & id) + { + this->id = id ; + this->IdDefined = true ; + } +/* + bool CObject::operator==(const CObject & other) const + { + if(!this->hasId() || !other.hasId()) + return (false); + return (this->id.compare(other.id) == 0); + } + + bool CObject::operator!=(const CObject & other) const + { + return (!(*this == other)); + } +*/ + StdOStream & operator << (StdOStream & os, const CObject & object) + { + os << object.toString(); + return (os); + } + +} // namespace xios diff --git a/src/object.hpp b/src/object.hpp new file mode 100644 index 0000000000000000000000000000000000000000..377b80e6c95693492aa44ba529c530042c33a50d --- /dev/null +++ b/src/object.hpp @@ -0,0 +1,58 @@ +#ifndef __XMLIO_CObject__ +#define __XMLIO_CObject__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + + class CObject + { + public : + + /// Destructeur /// + virtual ~CObject(void); + + /// Accesseurs /// + const StdString & getId(void) const; + + /// Mutateurs /// + void resetId(void); + void setId(const StdString & id); + + /// Tests /// + bool hasId(void) const; + + /// Opérateurs /// +// bool operator==(const CObject & other) const; +// bool operator!=(const CObject & other) const; + + /// Flux /// + friend StdOStream & operator << (StdOStream & os, const CObject & object); + + /// Autres /// + virtual StdString toString(void) const = 0; + virtual void fromString(const StdString & str) = 0; + + protected : + + /// Constructeurs /// + CObject(void); + explicit CObject(const StdString & id); + CObject(const CObject & object); + CObject(const CObject * const object); // Not implemented. + + private : + + /// Propriétés /// + StdString id ; // identifiant de l'Object + bool IdDefined ; // true si l'object est identifié, false sinon. + + }; // class CObject + +} // namespace xios + +#endif // __XMLIO_CObject__ + diff --git a/src/object_factory.cpp b/src/object_factory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3427b3761aceedb91d901ccbb1cd33d9dee99a59 --- /dev/null +++ b/src/object_factory.cpp @@ -0,0 +1,15 @@ +#include "object_factory.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + StdString CObjectFactory::CurrContext(""); + + void CObjectFactory::SetCurrentContextId(const StdString & context) + { CObjectFactory::CurrContext = context; } + + StdString & CObjectFactory::GetCurrentContextId(void) + { return (CObjectFactory::CurrContext); } + +} // namespace xios diff --git a/src/object_factory.hpp b/src/object_factory.hpp new file mode 100644 index 0000000000000000000000000000000000000000..707c318d96a97636e8b4ab6d9be733307d8cf064 --- /dev/null +++ b/src/object_factory.hpp @@ -0,0 +1,66 @@ +#ifndef __XMLIO_CObjectFactory__ +#define __XMLIO_CObjectFactory__ + +/// boost headers /// +#include + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "object_template.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CObjectFactory + { + public : + + /// Mutateurs /// + static void SetCurrentContextId(const StdString & context); + + /// Accesseurs /// + static StdString & GetCurrentContextId(void); + + template + static boost::shared_ptr GetObject(const StdString & id); + + template + static boost::shared_ptr GetObject(const StdString& context,const StdString & id); + + template + static boost::shared_ptr GetObject(const U * const object); + + template + static int GetObjectNum(void); + template + static int GetObjectIdNum(void); + + template + static const std::vector > & + GetObjectVector(const StdString & context = CObjectFactory::GetCurrentContextId()); + + /// Tests /// + template + static bool HasObject(const StdString & id); + + template + static bool HasObject(const StdString& context,const StdString & id); + + /// Instanciateur /// + template + static boost::shared_ptr CreateObject(const StdString & id = StdString("")); + + template static StdString GenUId(void) ; + + private : + + /// Propriétés statiques /// + static StdString CurrContext; + + }; // class CObjectFactory +} // namespace xios + +//#include "object_factory_impl.hpp" + +#endif // __XMLIO_CObjectFactory__ diff --git a/src/object_factory_decl.cpp b/src/object_factory_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..571d568ec879bdf609511abe63a4dd8ab118dc57 --- /dev/null +++ b/src/object_factory_decl.cpp @@ -0,0 +1,33 @@ +#include "object_factory_impl.hpp" +#include "node_type.hpp" + +namespace xios +{ +#define macro(U) \ + template shared_ptr CObjectFactory::GetObject(const StdString & id); \ + template shared_ptr CObjectFactory::GetObject(const StdString& context,const StdString & id); \ + template shared_ptr CObjectFactory::GetObject(const U * const object); \ + template int CObjectFactory::GetObjectNum(void); \ + template int CObjectFactory::GetObjectIdNum(void); \ + template const std::vector >& CObjectFactory::GetObjectVector(const StdString & context ); \ + template bool CObjectFactory::HasObject(const StdString & id); \ + template bool CObjectFactory::HasObject(const StdString& context,const StdString & id); \ + template boost::shared_ptr CObjectFactory::CreateObject(const StdString & id ); \ + template StdString CObjectFactory::GenUId(void) ; + + macro(CField) + macro(CFile) + macro(CGrid) + macro(CAxis) + macro(CDomain) + macro(CContext) + macro(CVariable) + + macro(CFieldGroup) + macro(CFileGroup) + macro(CGridGroup) + macro(CAxisGroup) + macro(CDomainGroup) + macro(CContextGroup) + macro(CVariableGroup) +} diff --git a/src/object_factory_impl.hpp b/src/object_factory_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c3bfc106f25c72a8d8add2dbe6b01b3db04e94c5 --- /dev/null +++ b/src/object_factory_impl.hpp @@ -0,0 +1,154 @@ +#ifndef __XMLIO_CObjectFactory_impl__ +#define __XMLIO_CObjectFactory_impl__ + +#include "object_factory.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + template + int CObjectFactory::GetObjectNum(void) + { + if (CurrContext.size() == 0) + ERROR("CObjectFactory::GetObjectNum(void)", + << "please define current context id !"); + return (U::AllVectObj[CObjectFactory::CurrContext].size()); + } + + template + int CObjectFactory::GetObjectIdNum(void) + { + if (CurrContext.size() == 0) + ERROR("CObjectFactory::GetObjectIdNum(void)", + << "please define current context id !"); + return (U::AllMapObj[CObjectFactory::CurrContext].size()); + } + + template + bool CObjectFactory::HasObject(const StdString & id) + { + if (CurrContext.size() == 0) + ERROR("CObjectFactory::HasObject(const StdString & id)", + << "[ id = " << id << " ] please define current context id !"); + return (U::AllMapObj[CObjectFactory::CurrContext].find(id) != + U::AllMapObj[CObjectFactory::CurrContext].end()); + } + + template + bool CObjectFactory::HasObject(const StdString & context, const StdString & id) + { + if (U::AllMapObj.find(context) == U::AllMapObj.end()) return false ; + else return (U::AllMapObj[context].find(id) != U::AllMapObj[context].end()); + } + + template + boost::shared_ptr CObjectFactory::GetObject(const U * const object) + { + if (CurrContext.size() == 0) + ERROR("CObjectFactory::GetObject(const U * const object)", + << "please define current context id !"); + std::vector > & vect = + U::AllVectObj[CObjectFactory::CurrContext]; + + typename std::vector >::const_iterator + it = vect.begin(), end = vect.end(); + + for (; it != end; it++) + { + boost::shared_ptr ptr = *it; + if (ptr.get() == object) + return (ptr); + } + + ERROR("CObjectFactory::GetObject(const U * const object)", + << "[type = " << U::GetName() << ", " + << "adress = " << object << "]" + << " object was not found !"); + return (boost::shared_ptr()); // jamais atteint + } + + template + boost::shared_ptr CObjectFactory::GetObject(const StdString & id) + { + if (CurrContext.size() == 0) + ERROR("CObjectFactory::GetObject(const StdString & id)", + << "[ id = " << id << " ] please define current context id !"); + if (!CObjectFactory::HasObject(id)) + ERROR("CObjectFactory::GetObject(const StdString & id)", + << "[ id = " << id << ", U = " << U::GetName() << " ] " + << " object is not referenced !"); + return (U::AllMapObj[CObjectFactory::CurrContext][id]); + } + + template + boost::shared_ptr CObjectFactory::GetObject(const StdString & context, const StdString & id) + { + if (!CObjectFactory::HasObject(context,id)) + ERROR("CObjectFactory::GetObject(const StdString & id)", + << "[ id = " << id << ", U = " << U::GetName() <<", context = "< + boost::shared_ptr CObjectFactory::CreateObject(const StdString & id) + { + if (CurrContext.size() == 0) + ERROR("CObjectFactory::CreateObject(const StdString & id)", + << "[ id = " << id << " ] please define current context id !"); + if (id.size() == 0) + { + boost::shared_ptr value(new U(CObjectFactory::GenUId())); + U::AllVectObj[CObjectFactory::CurrContext].insert + (U::AllVectObj[CObjectFactory::CurrContext].end(), value); + U::AllMapObj[CObjectFactory::CurrContext].insert(std::make_pair(value->getId(), value)); + return (value); + } + else if (CObjectFactory::HasObject(id)) + { + return (CObjectFactory::GetObject(id)); + } + else + { + boost::shared_ptr value(new U(id)); + U::AllVectObj[CObjectFactory::CurrContext].insert + (U::AllVectObj[CObjectFactory::CurrContext].end(), value); + U::AllMapObj[CObjectFactory::CurrContext].insert(std::make_pair(id, value)); + return (value); + } + } + + template + const std::vector > & + CObjectFactory::GetObjectVector(const StdString & context) + { + return (U::AllVectObj[context]); + } + + template + StdString CObjectFactory::GenUId(void) + { + long int seed ; + + xios_map::iterator it ; + it=U::GenId.find(CObjectFactory::CurrContext); + if (it==U::GenId.end()) + { + seed=0 ; + U::GenId[CObjectFactory::CurrContext]=seed ; + } + else + { + seed=it->second ; + seed++ ; + it->second=seed ; + } + + StdOStringStream oss ; + oss<<"__"< + class CObjectTemplate + : public CObject + , public virtual CAttributeMap + { + + /// Friend /// + friend class CObjectFactory; + + /// Typedef /// + typedef CAttributeMap SuperClassMap; + typedef CObject SuperClass; + typedef T DerivedType; + + enum EEventId + { + EVENT_ID_SEND_ATTRIBUTE=100 + } ; + + public : + + /// Autres /// + virtual StdString toString(void) const; + virtual void fromString(const StdString & str); + +// virtual void toBinary (StdOStream & os) const; +// virtual void fromBinary(StdIStream & is); + virtual string getName(void) const ; + virtual void parse(xml::CXMLNode & node); + + /// Accesseurs /// + ENodeType getType(void) const; + + /// Test /// + virtual bool hasChild(void) const; + + /// Traitements /// + virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0); + + /// Traitement statique /// + static void ClearAllAttributes(void); + void sendAttributToServer(const string& id); + void sendAttributToServer(CAttribute& attr) ; + static void recvAttributFromClient(CEventServer& event) ; + static bool dispatchEvent(CEventServer& event) ; + + /// Accesseur statique /// + static std::vector > & + GetAllVectobject(const StdString & contextId); + + /// Destructeur /// + virtual ~CObjectTemplate(void); + + static bool has(const string& id) ; + static bool has(const string& contextId, const string& id) ; + static T* get(const string& id) ; + static T* get(const T* ptr) ; + static T* get(const string& contextId, const string& id) ; + T* get(void) ; + shared_ptr getShared(void) ; + static shared_ptr getShared(const T* ptr) ; + + static T* create(const string& id=string("")) ; + static const vector getAll() ; + static const vector getAll(const string& contextId) ; + + void generateCInterface(ostream& oss) ; + void generateFortran2003Interface(ostream& oss) ; + void generateFortranInterface(ostream& oss) ; + + protected : + + /// Constructeurs /// + CObjectTemplate(void); + explicit CObjectTemplate(const StdString & id); + CObjectTemplate(const CObjectTemplate & object, + bool withAttrList = true, bool withId = true); + CObjectTemplate(const CObjectTemplate * const object); // Not implemented. + + private : + + /// Propriétés statiques /// + static xios_map > > AllMapObj; + static xios_map > > AllVectObj; + + static xios_map< StdString, long int > GenId ; + + }; // class CObjectTemplate +} // namespace xios + +//#include "object_template_impl.hpp" + +#endif // __XMLIO_CObjectTemplate__ diff --git a/src/object_template_decl.cpp b/src/object_template_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f349621a56743bd2531e635b1f554a20964e24bb --- /dev/null +++ b/src/object_template_decl.cpp @@ -0,0 +1,29 @@ +#include "object_template_impl.hpp" +#include "xmlioserver_spl.hpp" +#include "field.hpp" +#include "context.hpp" +#include "file.hpp" +#include "domain.hpp" +#include "grid.hpp" +#include "axis.hpp" +#include "variable.hpp" + + +namespace xios +{ + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + template class CObjectTemplate ; + } diff --git a/src/object_template_impl.hpp b/src/object_template_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e22d598c64efd686414717a8ab6f23594a980c51 --- /dev/null +++ b/src/object_template_impl.hpp @@ -0,0 +1,408 @@ +#ifndef __XMLIO_CObjectTemplate_impl__ +#define __XMLIO_CObjectTemplate_impl__ + +#include "xmlioserver_spl.hpp" +#include "context_client.hpp" +#include "object_factory.hpp" +#include "context.hpp" +#include "buffer_in.hpp" +#include "attribute.hpp" +#include "event_client.hpp" +#include "object_template.hpp" +#include "context_client.hpp" +#include "indent.hpp" +#include "type_util.hpp" +#include "message.hpp" +#include "type.hpp" +#include "type_util.hpp" +#include "group_template.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + template + xios_map > > CObjectTemplate::AllMapObj; + + template + xios_map > > CObjectTemplate::AllVectObj; + + template + xios_map CObjectTemplate::GenId; + + template + CObjectTemplate::CObjectTemplate(void) + : CAttributeMap() + , CObject() + { /* Ne rien faire de plus */ } + + template + CObjectTemplate::CObjectTemplate(const StdString & id) + : CAttributeMap() + , CObject(id) + { /* Ne rien faire de plus */ } + + template + CObjectTemplate::CObjectTemplate + (const CObjectTemplate & object, bool withAttrList, bool withId) + : CAttributeMap() + , CObject() + { + if (object.hasId() && withId) + this->setId(object.getId()); + ERROR("CObjectTemplate construtor 3", << "Not completly implemented yet !"); + } + + template + CObjectTemplate::~CObjectTemplate(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + template + std::vector > & + CObjectTemplate::GetAllVectobject(const StdString & contextId) + { + return (CObjectTemplate::AllVectObj[contextId]); + } + + //--------------------------------------------------------------- + + template + StdString CObjectTemplate::toString(void) const + { + StdOStringStream oss; + oss << "<" << T::GetName(); + if (this->hasId()) + oss << " id=\"" << this->getId() << "\""; + oss << " " << SuperClassMap::toString() << "/>"; + return (oss.str()); + } + + template + void CObjectTemplate::fromString(const StdString & str) + { + ERROR("CObjectTemplate::fromString(str)", + << "[ str = " << str << "] Not implemented yet !"); + } + + //--------------------------------------------------------------- + +/* + template + void CObjectTemplate::toBinary(StdOStream & os) const + { + SuperClassMap::toBinary(os); + } + + template + void CObjectTemplate::fromBinary(StdIStream & is) + { + SuperClassMap::fromBinary(is); + } +*/ + + //--------------------------------------------------------------- + + template + void CObjectTemplate::parse(xml::CXMLNode & node) + { + xml::THashAttributes attributes = node.getAttributes(); + CAttributeMap::setAttributes(attributes); + } + + //--------------------------------------------------------------- + + template + ENodeType CObjectTemplate::getType(void) const + { + return (T::GetType()); + } + + template + string CObjectTemplate::getName(void) const + { + return (T::GetName()); + } + + //--------------------------------------------------------------- + + template + bool CObjectTemplate::hasChild(void) const + { + return (false); + } + + //--------------------------------------------------------------- + + template + void CObjectTemplate::solveDescInheritance(bool apply, const CAttributeMap * const parent) + { + SuperClassMap::setAttributes(parent, apply); + } + + //--------------------------------------------------------------- + + template + void CObjectTemplate::ClearAllAttributes(void) + { + vector avect = CObjectTemplate::getAll() ; + typename vector::iterator + it = avect.begin(), end = avect.end(); + + for (;it != end; it++) + { + CAttributeMap & amap = **it; + amap.clearAllAttributes(); + } + } + + template + void CObjectTemplate::sendAttributToServer(const string& id) + { + CAttributeMap & attrMap = *this; + CAttribute* attr=attrMap[id] ; + sendAttributToServer(*attr) ; + } + + template + void CObjectTemplate::sendAttributToServer(CAttribute& attr) + { + CContext* context=CContext::getCurrent() ; + + if (!context->hasServer) + { + CContextClient* client=context->client ; + + CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE) ; + if (client->isServerLeader()) + { + CMessage msg ; + msg<getId() ; + msg<getServerLeader(),1,msg) ; + client->sendEvent(event) ; + } + else client->sendEvent(event) ; + } + + } + + template + void CObjectTemplate::recvAttributFromClient(CEventServer& event) + { + + CBufferIn* buffer=event.subEvents.begin()->buffer; + string id,attrId; + *buffer>>id ; + CAttributeMap & attrMap = *get(id); + *buffer>>attrId ; + CAttribute* attr=attrMap[attrId] ; + info(50)<<"attribut recu "<isEmpty()) info(50)<<"--> empty"<getValue()*/<>*attr ; + info(50)<<"attribut recu "<isEmpty()) info(50)<<"--> empty"<getValue()*/< + bool CObjectTemplate::dispatchEvent(CEventServer& event) + { + switch(event.type) + { + case EVENT_ID_SEND_ATTRIBUTE : + recvAttributFromClient(event) ; + return true ; + break ; + + default : + return false ; +// ERROR("void CObjectTemplate::recvEvent(CEventServer& event)", +// <<"Unknown Event") ; + } + } + + template + bool CObjectTemplate::has(const string & id) + { + return CObjectFactory::HasObject(id) ; + } + + template + bool CObjectTemplate::has(const string& contextId, const string & id) + { + return CObjectFactory::HasObject(contextId,id) ; + } + + template + T* CObjectTemplate::get(const string & id) + { + return CObjectFactory::GetObject(id).get() ; + } + + template + T* CObjectTemplate::get(const T* ptr) + { + return CObjectFactory::GetObject(ptr).get() ; + } + + template + shared_ptr CObjectTemplate::getShared(const T* ptr) + { + return CObjectFactory::GetObject(ptr) ; + } + + template + shared_ptr CObjectTemplate::getShared(void) + { + return CObjectFactory::GetObject((T*)this) ; + } + + template + const vector CObjectTemplate::getAll() + { + const vector< shared_ptr >& shared_vect= CObjectFactory::GetObjectVector(); + vector vect ; + + typename vector >::const_iterator it; + for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get()) ; + return vect ; + } + + template + const vector CObjectTemplate::getAll(const string & id) + { + const vector< shared_ptr >& shared_vect= CObjectFactory::GetObjectVector(id); + vector vect ; + + typename vector >::const_iterator it; + for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get()) ; + return vect ; + } + + template + T* CObjectTemplate::get(const string& contextId, const string & id) + { + return CObjectFactory::GetObject(contextId,id).get() ; + } + + template + T* CObjectTemplate::create(const string & id) + { + return CObjectFactory::CreateObject(id).get() ; + } ///-------------------------------------------------------------- + + template + T* CObjectTemplate::get(void) + { + return CObjectFactory::GetObject((T*)this).get() ; + } + + template + void CObjectTemplate::generateCInterface(ostream& oss) + { + string className=getName() ; + int found=className.find_first_of("_") ; + if (found!=string::npos) className.replace(found,1,0,'x') ; + + oss<<"/* ************************************************************************** *"<"<"<()<<"* "< + void CObjectTemplate::generateFortran2003Interface(ostream& oss) + { + string className=getName() ; + int found=className.find_first_of("_") ; + if (found!=string::npos) className.replace(found,1,0,'x') ; + + oss<<"! * ************************************************************************** *"< C99"< + void CObjectTemplate::generateFortranInterface(ostream& oss) + { + string className=getName() ; + int found=className.find_first_of('_') ; + if (found!=string::npos) className.erase(found,1) ; + string superClassName=getName(); + found=superClassName.find("_group") ; + if (found!=string::npos) superClassName.erase(found,6) ; + + oss<<"! * ************************************************************************** *"< +#include "attribute_template.hpp" +#include "group_template.hpp" + +#include "file.hpp" +#include "calendar.hpp" +#include "context.hpp" +#include "context_server.hpp" +#include "netCdfException.hpp" +#include "exception.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + CNc4DataOutput::CNc4DataOutput + (const StdString & filename, bool exist) + : SuperClass() + , SuperClassWriter(filename, exist) + , filename(filename) + { + StdString timeid = StdString("time_counter"); + SuperClass::type = MULTI_FILE; +// if (!exist) +// SuperClassWriter::addDimension(timeid); + } + + CNc4DataOutput::CNc4DataOutput + (const StdString & filename, bool exist, MPI_Comm comm_file,bool multifile, bool isCollective) + : SuperClass() + , SuperClassWriter(filename, exist, &comm_file,multifile) + , comm_file(comm_file) + , filename(filename) + , isCollective(isCollective) + { + StdString timeid = StdString("time_counter"); + + SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE; + + // if (!exist) +// SuperClassWriter::addDimension(timeid); + } + + + CNc4DataOutput::~CNc4DataOutput(void) + { /* Ne rien faire de plus */ } + + ///-------------------------------------------------------------- + + const StdString & CNc4DataOutput::getFileName(void) const + { + return (this->filename); + } + + //--------------------------------------------------------------- + + void CNc4DataOutput::writeDomain_(CDomain* domain) + { + if (domain->type == CDomain::type_attr::unstructured) + { + writeUnstructuredDomain(domain) ; + return ; + } + + CContext* context = CContext::getCurrent() ; + CContextServer* server=context->server ; + + if (domain->IsWritten(this->filename)) return; + domain->checkAttributes(); + + if (domain->isEmpty()) + if (SuperClass::type==MULTI_FILE) return ; + + std::vector dim0, dim1; + StdString domid = (!domain->name.isEmpty()) + ? domain->name.getValue() : domain->getId(); + StdString appendDomid = (singleDomain) ? "" : "_"+domid ; + + + StdString dimXid, dimYid ; + + switch (domain->type) + { + case CDomain::type_attr::curvilinear : + dimXid = StdString("x").append(appendDomid); + dimYid = StdString("y").append(appendDomid); + break ; + case CDomain::type_attr::regular : + dimXid = StdString("lon").append(appendDomid); + dimYid = StdString("lat").append(appendDomid); + break; + case CDomain::type_attr::unstructured : + dimXid = StdString("cell").append(appendDomid); + break; + } + + string lonid,latid,bounds_lonid,bounds_latid ; +/* + StdString lonid_loc = (server->intraCommSize > 1) + ? StdString("lon").append(appendDomid).append("_local") + : lonid; + StdString latid_loc = (server->intraCommSize > 1) + ? StdString("lat").append(appendDomid).append("_local") + : latid; +*/ + + try + { + switch (SuperClass::type) + { + case (MULTI_FILE) : + { + // if (domain->isEmpty()) return; + + if (server->intraCommSize > 1) + { + // SuperClassWriter::addDimension(lonid, domain->zoom_ni.getValue()); + // SuperClassWriter::addDimension(latid, domain->zoom_nj.getValue()); + } + + switch (domain->type) + { + case CDomain::type_attr::curvilinear : + dim0.push_back(dimYid); dim0.push_back(dimXid); + lonid = StdString("nav_lon").append(appendDomid); + latid = StdString("nav_lat").append(appendDomid); + break ; + case CDomain::type_attr::regular : + lonid = StdString("lon").append(appendDomid); + latid = StdString("lat").append(appendDomid); + dim0.push_back(dimYid); + dim1.push_back(dimXid); + break; + case CDomain::type_attr::unstructured : + lonid = StdString("lon").append(appendDomid); + latid = StdString("lat").append(appendDomid); + bounds_lonid=string("bounds_lon").append(appendDomid); + bounds_latid=string("bounds_lat").append(appendDomid); + dim0.push_back(dimXid); + break; + } + + if (domain->type == CDomain::type_attr::unstructured) + { + SuperClassWriter::addDimension(dimXid, domain->nj_glo); + } + else + { + SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv); + SuperClassWriter::addDimension(dimYid, domain->zoom_nj_srv); + } + + if (server->intraCommSize > 1) + { + if (domain->type != CDomain::type_attr::unstructured) + { + this->writeLocalAttributes(domain->zoom_ibegin_srv, + domain->zoom_ni_srv, + domain->zoom_jbegin_srv, + domain->zoom_nj_srv, + appendDomid); + + if (singleDomain) this->writeLocalAttributes_IOIPSL(domain->zoom_ibegin_srv, + domain->zoom_ni_srv, + domain->zoom_jbegin_srv, + domain->zoom_nj_srv, + domain->ni_glo,domain->nj_glo, + server->intraCommRank,server->intraCommSize); + } + } + + switch (domain->type) + { + case CDomain::type_attr::curvilinear : + SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); + break ; + case CDomain::type_attr::regular : + SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1); + break ; + case CDomain::type_attr::unstructured : + SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); + } + + this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid); + this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid); + + dim0.clear(); + if (domain->type != CDomain::type_attr::unstructured) dim0.push_back(dimYid); + dim0.push_back(dimXid); + + + // supress mask if (server->intraCommSize > 1) + // supress mask { + // supress mask SuperClassWriter::addVariable(maskid, NC_INT, dim0); + // supress mask + // supress mask this->writeMaskAttributes(maskid, + // supress mask domain->data_dim.getValue()/*, + // supress mask domain->data_ni.getValue(), + // supress mask domain->data_nj.getValue(), + // supress mask domain->data_ibegin.getValue(), + // supress mask domain->data_jbegin.getValue()*/); + // supress mask } + + //SuperClassWriter::setDefaultValue(maskid, &dvm); + + SuperClassWriter::definition_end(); + + switch (domain->type) + { + case CDomain::type_attr::curvilinear : + SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0); + SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0); + break; + case CDomain::type_attr::regular : + CArray lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ; + SuperClassWriter::writeData(CArray(lat.copy()), latid, isCollective, 0); + CArray lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ; + SuperClassWriter::writeData(CArray(lon.copy()), lonid, isCollective, 0); + break; + } + SuperClassWriter::definition_start(); + + break; + } + case (ONE_FILE) : + { + SuperClassWriter::addDimension(dimXid, domain->zoom_ni.getValue()); + SuperClassWriter::addDimension(dimYid, domain->zoom_nj.getValue()); + + + switch (domain->type) + { + case CDomain::type_attr::curvilinear : + dim0.push_back(dimYid); dim0.push_back(dimXid); + lonid = StdString("nav_lon").append(appendDomid); + latid = StdString("nav_lat").append(appendDomid); + SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); + break; + + case CDomain::type_attr::regular : + dim0.push_back(dimYid); + dim1.push_back(dimXid); + lonid = StdString("lon").append(appendDomid); + latid = StdString("lat").append(appendDomid); + SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1); + break; + } + this->writeAxisAttributes + (lonid, "X", "longitude", "Longitude", "degrees_east", domid); + this->writeAxisAttributes + (latid, "Y", "latitude", "Latitude", "degrees_north", domid); + + + SuperClassWriter::definition_end(); + switch (domain->type) + { + case CDomain::type_attr::curvilinear : + { + std::vector start(2) ; + std::vector count(2) ; + if (domain->isEmpty()) + { + start[0]=0 ; start [1]=0 ; + count[0]=0 ; count[1]=0 ; + } + else + { + start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; + count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ; + } + + SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count); + SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count); + break; + } + case CDomain::type_attr::regular : + { + std::vector start(1) ; + std::vector count(1) ; + if (domain->isEmpty()) + { + start[0]=0 ; + count[0]=0 ; + SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count); + SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count); } + else + { + start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; + count[0]=domain->zoom_nj_srv ; + CArray lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ; + SuperClassWriter::writeData(CArray(lat.copy()), latid, isCollective, 0,&start,&count); + + start[0]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; + count[0]=domain->zoom_ni_srv ; + CArray lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ; + SuperClassWriter::writeData(CArray(lon.copy()), lonid, isCollective, 0,&start,&count); + } + break; + } + } + SuperClassWriter::definition_start(); + break; + } + default : + ERROR("CNc4DataOutput::writeDomain(domain)", + << "[ type = " << SuperClass::type << "]" + << " not implemented yet !"); + } + } + catch (CNetCdfException& e) + { + StdString msg("On writing the domain : "); + msg.append(domid); msg.append("\n"); + msg.append("In the context : "); + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeDomain_(CDomain* domain)", << msg); + } + + domain->addRelFile(this->filename); + } + + void CNc4DataOutput::writeUnstructuredDomain(CDomain* domain) + { + CContext* context = CContext::getCurrent() ; + CContextServer* server=context->server ; + + if (domain->IsWritten(this->filename)) return; + domain->checkAttributes(); + + if (domain->isEmpty()) + if (SuperClass::type==MULTI_FILE) return ; + + std::vector dim0, dim1; + StdString domid = (!domain->name.isEmpty()) + ? domain->name.getValue() : domain->getId(); + StdString appendDomid = (singleDomain) ? "" : "_"+domid ; + + + StdString dimXid = StdString("cell").append(appendDomid); + StdString dimVertId = StdString("nvertex").append(appendDomid); + + string lonid,latid,bounds_lonid,bounds_latid ; + + try + { + switch (SuperClass::type) + { + case (MULTI_FILE) : + { + lonid = StdString("lon").append(appendDomid); + latid = StdString("lat").append(appendDomid); + dim0.push_back(dimXid); + + SuperClassWriter::addDimension(dimXid, domain->zoom_nj_srv); + SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); + + bounds_lonid = StdString("bounds_lon").append(appendDomid); + bounds_latid = StdString("bounds_lat").append(appendDomid); + + + this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid); + if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid); + this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid); + if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid); + if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex); + dim0.clear(); + if (domain->hasBounds) + { + dim0.push_back(dimXid); + dim0.push_back(dimVertId); + SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0); + } + + dim0.clear(); + dim0.push_back(dimXid); + + SuperClassWriter::definition_end(); + + SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0); + SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0); + + if (domain->hasBounds) + { + SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0); + SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0); + } + SuperClassWriter::definition_start(); + break ; + } + + case (ONE_FILE) : + { + lonid = StdString("lon").append(appendDomid); + latid = StdString("lat").append(appendDomid); + bounds_lonid = StdString("bounds_lon").append(appendDomid); + bounds_latid = StdString("bounds_lat").append(appendDomid); + dim0.push_back(dimXid); + SuperClassWriter::addDimension(dimXid, domain->nj_glo); + SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); + this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid); + if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid); + this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid); + if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid); + if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex); + dim0.clear(); + + if (domain->hasBounds) + { + dim0.push_back(dimXid); + dim0.push_back(dimVertId); + SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0); + SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0); + } + + SuperClassWriter::definition_end(); + + std::vector start(1), startBounds(2) ; + std::vector count(1), countBounds(2) ; + if (domain->isEmpty()) + { + start[0]=0 ; + count[0]=0 ; + startBounds[1]=0 ; + countBounds[1]=domain->nvertex ; + startBounds[0]=0 ; + countBounds[0]=0 ; + } + else + { + start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ; + count[0]=domain->zoom_nj_srv ; + startBounds[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ; + startBounds[1]=0 ; + countBounds[0]=domain->zoom_nj_srv ; + countBounds[1]=domain->nvertex ; + } + SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count); + SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count); + if (domain->hasBounds) + { + SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0,&startBounds,&countBounds); + SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0,&startBounds,&countBounds); + } + + + SuperClassWriter::definition_start(); + + break; + } + default : + ERROR("CNc4DataOutput::writeDomain(domain)", + << "[ type = " << SuperClass::type << "]" + << " not implemented yet !"); + } + } + catch (CNetCdfException& e) + { + StdString msg("On writing the domain : "); + msg.append(domid); msg.append("\n"); + msg.append("In the context : "); + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)", << msg); + } + domain->addRelFile(this->filename); + } + //-------------------------------------------------------------- + + void CNc4DataOutput::writeAxis_(CAxis* axis) + { + if (axis->IsWritten(this->filename)) return; + axis->checkAttributes(); + StdSize zoom_size=axis->zoom_size.getValue() ; + StdSize zoom_begin=axis->zoom_begin.getValue()-1 ; + + + std::vector dims; + StdString axisid = (!axis->name.isEmpty()) + ? axis->name.getValue() : axis->getId(); + try + { + SuperClassWriter::addDimension(axisid, zoom_size); + dims.push_back(axisid); + + switch (SuperClass::type) + { + case (MULTI_FILE ) : + {} + case (ONE_FILE) : + { + SuperClassWriter::addVariable(axisid, NC_FLOAT, dims); + + SuperClassWriter::addAttribute("axis", StdString("Z"), &axisid); + + if (!axis->standard_name.isEmpty()) + SuperClassWriter::addAttribute + ("standard_name", axis->standard_name.getValue(), &axisid); + + if (!axis->long_name.isEmpty()) + SuperClassWriter::addAttribute + ("long_name", axis->long_name.getValue(), &axisid); + + if (!axis->unit.isEmpty()) + SuperClassWriter::addAttribute + ("units", axis->unit.getValue(), &axisid); + + if (!axis->positive.isEmpty()) + if (axis->positive==CAxis::positive_attr::up) SuperClassWriter::addAttribute("positive", string("up"), &axisid); + else SuperClassWriter::addAttribute("positive", string("down"), &axisid); + + SuperClassWriter::definition_end(); + + CArray axis_value(zoom_size) ; + for(StdSize i = 0 ; i < zoom_size ; i++) axis_value(i)=axis->value(i+zoom_begin) ; + SuperClassWriter::writeData(axis_value, axisid, isCollective, 0); + + SuperClassWriter::definition_start(); + + break; + } + default : + ERROR("CNc4DataOutput::writeDomain(domain)", + << "[ type = " << SuperClass::type << "]" + << " not implemented yet !"); + } + } + catch (CNetCdfException& e) + { + StdString msg("On writing the axis : "); + msg.append(axisid); msg.append("\n"); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeAxis_(CAxis* axis)", << msg); + } + axis->addRelFile(this->filename); + } + + void CNc4DataOutput::writeTimeDimension_(void) + { + try + { + SuperClassWriter::addDimension("time_counter"); + SuperClassWriter::addDimension("time_bounds", 2); + } + catch (CNetCdfException& e) + { + StdString msg("On writing time dimension : time_couter, time_bounds \n"); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeTimeDimension_(void)", << msg); + } + } + //-------------------------------------------------------------- + + void CNc4DataOutput::writeField_(CField* field) + { + CContext* context = CContext::getCurrent() ; + CContextServer* server=context->server ; + + std::vector dims, coodinates; + CGrid* grid = field->grid; + CDomain* domain = grid->domain; + + if (domain->isEmpty()) + if (SuperClass::type==MULTI_FILE) return ; + + StdString timeid = StdString("time_counter"); + StdString domid = (!domain->name.isEmpty()) + ? domain->name.getValue() : domain->getId(); + StdString appendDomid = (singleDomain) ? "" : "_"+domid ; + +// bool isCurvilinear = domain->isCurvilinear ; +// bool isCurvilinear = (domain->type == CDomain::type_attr::curvilinear) ; + + StdString dimXid,dimYid ; + + switch (domain->type) + { + case CDomain::type_attr::curvilinear : + dimXid = StdString("x").append(appendDomid); + dimYid = StdString("y").append(appendDomid); + break ; + case CDomain::type_attr::regular : + dimXid = StdString("lon").append(appendDomid); + dimYid = StdString("lat").append(appendDomid); + break ; + case CDomain::type_attr::unstructured : + dimXid = StdString("cell").append(appendDomid); + break ; + } + +/* + StdString lonid_loc = (server->intraCommSize > 1) + ? StdString("lon").append(appendDomid).append("_local") + : lonid; + StdString latid_loc = (server->intraCommSize > 1) + ? StdString("lat").append(appendDomid).append("_local") + : latid; +*/ + StdString fieldid = (!field->name.isEmpty()) + ? field->name.getValue() : field->getBaseFieldReference()->getId(); + +// unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue(); +// bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize); +// bool isCurvilinear = domain->isCurvilinear ; + + nc_type type ; + if (field->prec.isEmpty()) type = NC_FLOAT ; + else + { + if (field->prec==2) type = NC_SHORT ; + else if (field->prec==4) type = NC_FLOAT ; + else if (field->prec==8) type = NC_DOUBLE ; + } + + bool wtime = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once); + + if (wtime) + { + + //StdOStringStream oss; + // oss << "time_" << field->operation.getValue() + // << "_" << field->getRelFile()->output_freq.getValue(); + //oss + if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant")); + else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered")); + dims.push_back(timeid); + } + + if (!grid->axis_ref.isEmpty()) + { + CAxis* axis = grid->axis ; + StdString axisid = (!axis->name.isEmpty()) ? axis->name.getValue() : axis->getId(); + dims.push_back(axisid); + coodinates.push_back(axisid); + } + + switch (domain->type) + { + case CDomain::type_attr::curvilinear : + coodinates.push_back(StdString("nav_lon").append(appendDomid)); + coodinates.push_back(StdString("nav_lat").append(appendDomid)); + break; + case CDomain::type_attr::regular : + case CDomain::type_attr::unstructured : + coodinates.push_back(StdString("lon").append(appendDomid)); + coodinates.push_back(StdString("lat").append(appendDomid)); + break; + } + + if ( domain->type == CDomain::type_attr::curvilinear || domain->type == CDomain::type_attr::regular)dims.push_back(dimYid); + dims.push_back(dimXid); + + try + { + SuperClassWriter::addVariable(fieldid, type, dims); + + if (!field->standard_name.isEmpty()) + SuperClassWriter::addAttribute + ("standard_name", field->standard_name.getValue(), &fieldid); + + if (!field->long_name.isEmpty()) + SuperClassWriter::addAttribute + ("long_name", field->long_name.getValue(), &fieldid); + + if (!field->unit.isEmpty()) + SuperClassWriter::addAttribute + ("units", field->unit.getValue(), &fieldid); + + if (!field->valid_min.isEmpty()) + SuperClassWriter::addAttribute + ("valid_min", field->valid_min.getValue(), &fieldid); + + if (!field->valid_max.isEmpty()) + SuperClassWriter::addAttribute + ("valid_max", field->valid_max.getValue(), &fieldid); + + if (!field->scale_factor.isEmpty()) + SuperClassWriter::addAttribute + ("scale_factor", field->scale_factor.getValue(), &fieldid); + + if (!field->add_offset.isEmpty()) + SuperClassWriter::addAttribute + ("add_offset", field->add_offset.getValue(), &fieldid); + + SuperClassWriter::addAttribute + ("online_operation", field->operation.getValue(), &fieldid); + + // write child variables as attributes + + + vector listVars = field->getAllVariables() ; + for (vector::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ; + + + if (wtime) + { + CDuration duration ; + + duration=CDuration::FromString(field->freq_op) ; + duration.solveTimeStep(*(context->calendar)); + SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid); + + duration=CDuration::FromString(field->getRelFile()->output_freq) ; + duration.solveTimeStep(*(context->calendar)); + SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid); + } + + if (!field->default_value.isEmpty()) + { + double default_value = field->default_value.getValue(); + float fdefault_value = (float)default_value; + if (type == NC_DOUBLE) + SuperClassWriter::setDefaultValue(fieldid, &default_value); + else + SuperClassWriter::setDefaultValue(fieldid, &fdefault_value); + } + else + { + double * default_value = NULL; + SuperClassWriter::setDefaultValue(fieldid, default_value); + } + + { // Ecriture des coordonnées + + StdString coordstr; //boost::algorithm::join(coodinates, " ") + std::vector::iterator + itc = coodinates.begin(), endc = coodinates.end(); + + for (; itc!= endc; itc++) + { + StdString & coord = *itc; + if (itc+1 != endc) + coordstr.append(coord).append(" "); + else coordstr.append(coord); + } + + SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid); + + } + } + catch (CNetCdfException& e) + { + StdString msg("On writing field : "); + msg.append(fieldid); msg.append("\n"); + msg.append("In the context : "); + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeField_(CField* field)", << msg); + } + } + + //-------------------------------------------------------------- + + void CNc4DataOutput::writeFile_ (CFile* file) + { + StdString filename = (!file->name.isEmpty()) + ? file->name.getValue() : file->getId(); + StdString description = (!file->description.isEmpty()) + ? file->description.getValue() + : StdString("Created by xios"); + try + { + this->writeFileAttributes(filename, description, + StdString ("CF-1.1"), + StdString("An IPSL model"), + this->getTimeStamp()); + } + catch (CNetCdfException& e) + { + StdString msg("On writing file : "); + msg.append(filename); msg.append("\n"); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeFile_ (CFile* file)", << msg); + } + if (file->nbDomain==1) singleDomain=true ; + else singleDomain=false ; + } + + void CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId) + { + string name ; + if (!var->name.isEmpty()) name=var->name ; + else if (var->hasId()) name=var->getId() ; + else return ; + + try + { + if (var->getVarType()==CVariable::t_int) addAttribute(name,var->getData(),&fieldId) ; + else if (var->getVarType()==CVariable::t_short_int) addAttribute(name,var->getData(),&fieldId) ; + else if (var->getVarType()==CVariable::t_long_int) addAttribute(name,var->getData(),&fieldId) ; + else if (var->getVarType()==CVariable::t_float) addAttribute(name,var->getData(),&fieldId) ; + else if (var->getVarType()==CVariable::t_double) addAttribute(name,var->getData(),&fieldId) ; + else addAttribute(name,var->getData(),&fieldId) ; + } + catch (CNetCdfException& e) + { + StdString msg("On writing attributes of variable with name : "); + msg.append(name); msg.append("in the field "); msg.append(fieldId); msg.append("\n"); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << msg); + } + } + + void CNc4DataOutput::writeAttribute_ (CVariable* var) + { + string name ; + if (!var->name.isEmpty()) name=var->name ; + else if (var->hasId()) name=var->getId() ; + else return ; + try + { + if (var->getVarType()==CVariable::t_int) addAttribute(name,var->getData()) ; + else if (var->getVarType()==CVariable::t_short_int) addAttribute(name,var->getData()) ; + else if (var->getVarType()==CVariable::t_long_int) addAttribute(name,var->getData()) ; + else if (var->getVarType()==CVariable::t_float) addAttribute(name,var->getData()) ; + else if (var->getVarType()==CVariable::t_double) addAttribute(name,var->getData()) ; + else addAttribute(name,var->getData()) ; + } + catch (CNetCdfException& e) + { + StdString msg("On writing attributes of variable with name : "); + msg.append(name); msg.append("\n"); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << msg); + } + } + + void CNc4DataOutput::syncFile_ (void) + { + try + { + SuperClassWriter::sync() ; + } + catch (CNetCdfException& e) + { + StdString msg("On synchronizing the write among processes"); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::syncFile_ (void)", << msg); + } + } + + void CNc4DataOutput::closeFile_ (void) + { + try + { + SuperClassWriter::close() ; + } + catch (CNetCdfException& e) + { + StdString msg("On closing file"); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::syncFile_ (void)", << msg); + } + + } + + //--------------------------------------------------------------- + + StdString CNc4DataOutput::getTimeStamp(void) const + { + const int buffer_size = 100; + time_t rawtime; + struct tm * timeinfo = NULL; + char buffer [buffer_size]; + + time ( &rawtime ); + timeinfo = localtime ( &rawtime ); + strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo); + + return (StdString(buffer)); + } + + //--------------------------------------------------------------- + + void CNc4DataOutput::writeFieldData_ (CField* field) + { + CContext* context = CContext::getCurrent() ; +// if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ; + CContextServer* server=context->server ; + + CGrid* grid = field->grid ; + CDomain* domain = grid->domain ; + + if(SuperClass::type==MULTI_FILE || !isCollective) if (domain->isEmpty()) return; + + + StdString fieldid = (!field->name.isEmpty()) + ? field->name.getValue() + : field->getBaseFieldReference()->getId(); + + StdOStringStream oss; + string timeAxisId ; + if (field->foperation->timeType() == func::CFunctor::instant) timeAxisId="time_instant" ; + else if (field->foperation->timeType() == func::CFunctor::centered) timeAxisId="time_centered" ; + + StdString timeBoundId("time_counter_bounds"); + + StdString timeAxisBoundId; + if (field->foperation->timeType() == func::CFunctor::instant) timeAxisBoundId="time_instant_bounds" ; + else if (field->foperation->timeType() == func::CFunctor::centered) timeAxisBoundId="time_centered_bounds" ; + + CArray time_data(1) ; + CArray time_counter(1) ; + CArray time_counter_bound(2); + CArray time_data_bound(2); + + bool wtime = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once)); + + if (wtime) + { + time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2; + if (field->foperation->timeType() == func::CFunctor::instant) + time_data(0) = Time(*field->last_Write_srv); + else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0); + + time_counter_bound(0) = Time(*field->lastlast_Write_srv); + time_counter_bound(1) = Time(*field->last_Write_srv); + if (field->foperation->timeType() == func::CFunctor::instant) + time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv); + else if (field->foperation->timeType() == func::CFunctor::centered) + { + time_data_bound(0) = time_counter_bound(0); + time_data_bound(1) = time_counter_bound(1); + } + } + + bool isRoot ; + if (server->intraCommRank==0) isRoot=true ; + else isRoot=false ; + + if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty()) + { + double scaleFactor=1. ; + double addOffset=0. ; + if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ; + if (!field->add_offset.isEmpty()) addOffset=field->add_offset ; + field->scaleFactorAddOffset(scaleFactor,addOffset) ; + } + + try + { + if (grid->hasAxis()) // 3D + { + CAxis* axis = grid->axis ; + CArray field_data3D(domain->zoom_ni_srv,domain->zoom_nj_srv,axis->zoom_size) ; + if (!field->default_value.isEmpty()) field_data3D = field->default_value ; + + field->outputField(field_data3D); + + if (!field->prec.isEmpty() && field->prec==2) field_data3D=round(field_data3D) ; + + switch (SuperClass::type) + { + case (MULTI_FILE) : + { + SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1); + if (wtime) + { + SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1); + SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1); + SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1); + SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1); + } + break ; + } + case (ONE_FILE) : + { + std::vector start(3) ; + std::vector count(3) ; + if (domain->isEmpty()) + { + start[0]=0 ; start[1]=0 ; start[2]=0 ; + count[0]=0 ; count[1]=0 ; start[2]=0 ; + } + else + { + // start[2]=domain->zoom_ibegin_loc.getValue()-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_loc.getValue()-domain->zoom_jbegin.getValue() ; start[0]=0 ; + start[2]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; start[0]=0 ; + count[2]=domain->zoom_ni_srv ; count[1]=domain->zoom_nj_srv ; count[0] = axis->zoom_size.getValue(); + } + SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1,&start,&count ); + if (wtime) + { + SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot ); + SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot ); + SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot ); + SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot); + } + break; + } + } + + } + else // 2D + { + CArray field_data2D(domain->zoom_ni_srv,domain->zoom_nj_srv) ; + if (!field->default_value.isEmpty()) field_data2D = field->default_value ; + field->outputField(field_data2D); + if (!field->prec.isEmpty() && field->prec==2) field_data2D=round(field_data2D) ; + switch (SuperClass::type) + { + case (MULTI_FILE) : + { + SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1); + if (wtime) + { + SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1); + SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1); + SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1); + SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1); + } + break; + } + case (ONE_FILE) : + { + std::vector start(2) ; + std::vector count(2) ; + if (domain->isEmpty()) + { + start[0]=0 ; start[1]=0 ; + count[0]=0 ; count[1]=0 ; + } + else + { + start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; + count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ; + } + + SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1,&start,&count); + if (wtime) + { + SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot); + SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot); + SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot); + SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot); + } + break; + + } + } + } + } + catch (CNetCdfException& e) + { + StdString msg("On writing field data: "); + msg.append(fieldid); msg.append("\n"); + msg.append("In the context : "); + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeFieldData_ (CField* field)", << msg); + } + } + + //--------------------------------------------------------------- + + void CNc4DataOutput::writeTimeAxis_ + (CField* field, + const boost::shared_ptr cal) + { + StdOStringStream oss; + +// if (field->operation.getValue().compare("once") == 0) return ; + if (field->foperation->timeType() == func::CFunctor::once) return ; + +// oss << "time_" << field->operation.getValue() +// << "_" << field->getRelFile()->output_freq.getValue(); + +// StdString axisid = oss.str(); +// if (field->foperation->timeType() == func::CFunctor::centered) axisid="time_centered" ; +// else if (field->foperation->timeType() == func::CFunctor::instant) axisid="time_instant" ; + + StdString axisid("time_centered") ; + StdString axisBoundId("time_centered_bounds"); + StdString timeid("time_counter"); + StdString timeBoundId("time_bounds"); + + if (field->foperation->timeType() == func::CFunctor::instant) + { + axisid = "time_instant"; + axisBoundId = "time_instant_bounds"; + } + + try + { + // Adding time_instant or time_centered + std::vector dims; + dims.push_back(timeid); + if (!SuperClassWriter::varExist(axisid)) + { + SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims); + + CDate timeOrigin=cal->getTimeOrigin() ; + StdOStringStream oss2; + // oss2<writeTimeAxisAttributes + (axisid, cal->getType(), + StdString("seconds since ").append(strTimeOrigin), + strTimeOrigin, axisBoundId); + } + + // Adding time_instant_bounds or time_centered_bounds variables + if (!SuperClassWriter::varExist(axisBoundId)) + { + dims.clear() ; + dims.push_back(timeid); + dims.push_back(timeBoundId); + SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims); + } + + // Adding time_counter + axisid = "time_counter" ; + axisBoundId = "time_counter_bounds" ; + dims.clear() ; + dims.push_back(timeid); + if (!SuperClassWriter::varExist(axisid)) + { + SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims); + SuperClassWriter::addAttribute("axis", string("T"), &axisid); + CDate timeOrigin=cal->getTimeOrigin() ; + StdString strTimeOrigin=timeOrigin.toString() ; + + this->writeTimeAxisAttributes + (axisid, cal->getType(), + StdString("seconds since ").append(strTimeOrigin), + strTimeOrigin, axisBoundId); + } + + // Adding time_counter_bound dimension + if (!SuperClassWriter::varExist(axisBoundId)) + { + dims.clear(); + dims.push_back(timeid); + dims.push_back(timeBoundId); + SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims); + } + } + catch (CNetCdfException& e) + { + StdString msg("On writing time axis data: "); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeTimeAxis_ (CField* field, \ + const boost::shared_ptr cal)", << msg); + } + } + + //--------------------------------------------------------------- + + void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, + const StdString & calendar, + const StdString & units, + const StdString & time_origin, + const StdString & time_bounds, + const StdString & standard_name, + const StdString & long_name, + const StdString & title) + { + try + { + SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name); + SuperClassWriter::addAttribute("long_name", long_name , &axis_name); + SuperClassWriter::addAttribute("title", title , &axis_name); + SuperClassWriter::addAttribute("calendar", calendar , &axis_name); + SuperClassWriter::addAttribute("units", units , &axis_name); + SuperClassWriter::addAttribute("time_origin", time_origin , &axis_name); + SuperClassWriter::addAttribute("bounds", time_bounds , &axis_name); + } + catch (CNetCdfException& e) + { + StdString msg("On writing time axis Attribute: "); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, \ + const StdString & calendar,\ + const StdString & units, \ + const StdString & time_origin, \ + const StdString & time_bounds, \ + const StdString & standard_name, \ + const StdString & long_name, \ + const StdString & title)", << msg); + } + } + + //--------------------------------------------------------------- + + void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, + const StdString & axis, + const StdString & standard_name, + const StdString & long_name, + const StdString & units, + const StdString & nav_model) + { + try + { + SuperClassWriter::addAttribute("axis" , axis , &axis_name); + SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name); + SuperClassWriter::addAttribute("long_name" , long_name , &axis_name); + SuperClassWriter::addAttribute("units" , units , &axis_name); + SuperClassWriter::addAttribute("nav_model" , nav_model , &axis_name); + } + catch (CNetCdfException& e) + { + StdString msg("On writing Axis Attribute: "); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, \ + const StdString & axis, \ + const StdString & standard_name, \ + const StdString & long_name, \ + const StdString & units, \ + const StdString & nav_model)", << msg); + } + } + + //--------------------------------------------------------------- + + void CNc4DataOutput::writeLocalAttributes + (int ibegin, int ni, int jbegin, int nj, StdString domid) + { + try + { + SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin); + SuperClassWriter::addAttribute(StdString("ni" ).append(domid), ni); + SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin); + SuperClassWriter::addAttribute(StdString("nj" ).append(domid), nj); + } + catch (CNetCdfException& e) + { + StdString msg("On writing Local Attributes: "); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeLocalAttributes \ + (int ibegin, int ni, int jbegin, int nj, StdString domid)", << msg); + } + + } + + void CNc4DataOutput::writeLocalAttributes_IOIPSL + (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size) + { + CArray array(2) ; + + try + { + SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ; + SuperClassWriter::addAttribute("DOMAIN_number", rank) ; + array=1,2 ; + SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ; + array=ni_glo,nj_glo ; + SuperClassWriter::addAttribute("DOMAIN_size_global", array) ; + array=ni,nj ; + SuperClassWriter::addAttribute("DOMAIN_size_local", array) ; + array=ibegin,jbegin ; + SuperClassWriter::addAttribute("DOMAIN_position_first", array) ; + array=ibegin+ni-1,jbegin+nj-1 ; + SuperClassWriter::addAttribute("DOMAIN_position_last",array) ; + array=0,0 ; + SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ; + SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array); + SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ; + /* + SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ; + SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ; + SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ; + SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ; + */ + } + catch (CNetCdfException& e) + { + StdString msg("On writing Local Attributes IOI PSL \n"); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeLocalAttributes_IOIPSL \ + (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)", << msg); + } + } + //--------------------------------------------------------------- + + void CNc4DataOutput:: writeFileAttributes(const StdString & name, + const StdString & description, + const StdString & conventions, + const StdString & production, + const StdString & timeStamp) + { + try + { + SuperClassWriter::addAttribute("name" , name); + SuperClassWriter::addAttribute("description", description); + SuperClassWriter::addAttribute("conventions", conventions); + SuperClassWriter::addAttribute("production" , production); + SuperClassWriter::addAttribute("timeStamp" , timeStamp); + } + catch (CNetCdfException& e) + { + StdString msg("On writing File Attributes \n "); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput:: writeFileAttributes(const StdString & name, \ + const StdString & description, \ + const StdString & conventions, \ + const StdString & production, \ + const StdString & timeStamp)", << msg); + } + } + + //--------------------------------------------------------------- + + void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, + int data_dim, + int data_ni, + int data_nj, + int data_ibegin, + int data_jbegin) + { + try + { + SuperClassWriter::addAttribute("data_dim" , data_dim , &mask_name); + SuperClassWriter::addAttribute("data_ni" , data_ni , &mask_name); + SuperClassWriter::addAttribute("data_nj" , data_nj , &mask_name); + SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name); + SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name); + } + catch (CNetCdfException& e) + { + StdString msg("On writing Mask Attributes \n "); + msg.append("In the context : "); + CContext* context = CContext::getCurrent() ; + msg.append(context->getId()); msg.append("\n"); + msg.append(e.what()); + ERROR("CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, \ + int data_dim, \ + int data_ni, \ + int data_nj, \ + int data_ibegin, \ + int data_jbegin)", << msg); + } + } + + ///-------------------------------------------------------------- + +} // namespace xios diff --git a/src/output/nc4_data_output.hpp b/src/output/nc4_data_output.hpp new file mode 100644 index 0000000000000000000000000000000000000000..22f6dffa196f1a04ea505e60737e3c6b657d2ea5 --- /dev/null +++ b/src/output/nc4_data_output.hpp @@ -0,0 +1,101 @@ +#ifndef __XMLIO_NC4_DATA_OUTPUT__ +#define __XMLIO_NC4_DATA_OUTPUT__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "onetcdf4.hpp" +#include "data_output.hpp" + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + + class CNc4DataOutput + : protected CONetCDF4 + , public virtual CDataOutput + { + public : + + /// Définition de type /// + typedef CONetCDF4 SuperClassWriter; + typedef CDataOutput SuperClass; + + /// Constructeurs /// + CNc4DataOutput + (const StdString & filename, bool exist); + CNc4DataOutput + (const StdString & filename, bool exist, MPI_Comm comm_file, bool multifile, bool isCollective=true); + + CNc4DataOutput(const CNc4DataOutput & dataoutput); // Not implemented. + CNc4DataOutput(const CNc4DataOutput * const dataoutput); // Not implemented. + + /// Accesseur /// + const StdString & getFileName(void) const; + + /// Destructeur /// + virtual ~CNc4DataOutput(void); + bool singleDomain ; + bool isCollective ; + protected : + + /// Ecriture /// + virtual void writeDomain_ (CDomain* domain); + virtual void writeAxis_ (CAxis* axis); + virtual void writeTimeDimension_(void); + virtual void writeField_ (CField* field); + virtual void writeAttribute_ (CVariable* var); + virtual void writeAttribute_ (CVariable* var, const string& fieldId); + virtual void writeFieldData_ (CField* field); + virtual void writeFile_ (CFile* file); + virtual void closeFile_ (void); + virtual void syncFile_ (void); + virtual void writeTimeAxis_ (CField* field, + const boost::shared_ptr cal); + + protected : + void writeUnstructuredDomain (CDomain* domain); + void writeLocalAttributes(int ibegin, int ni, int jbegin, int nj, StdString domid); + void writeLocalAttributes_IOIPSL(int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size) ; + void writeTimeAxisAttributes(const StdString & axis_name, + const StdString & calendar, + const StdString & units, + const StdString & time_origin, + const StdString & time_bounds = StdString("bounds"), + const StdString & standard_name = StdString("time"), + const StdString & long_name = StdString("Time axis"), + const StdString & title = StdString("Time")); + + void writeFileAttributes(const StdString & name, + const StdString & description, + const StdString & conventions, + const StdString & production, + const StdString & timeStamp); + + void writeMaskAttributes(const StdString & mask_name, + int data_dim, + int data_ni = 0, + int data_nj = 0, + int data_ibegin = 0, + int data_jbegin = 0); + + void writeAxisAttributes(const StdString & axis_name, + const StdString & axis, + const StdString & standard_name, + const StdString & long_name, + const StdString & units, + const StdString & nav_model); + + private : + + /// Traitement /// + StdString getTimeStamp(void) const; + + /// Propriétés privées /// + MPI_Comm comm_file; + const StdString filename; + + }; // class CNc4DataOutput + +} // namespace xios + +#endif //__XMLIO_NC4_DATA_OUTPUT__ diff --git a/src/output/netCdfException.hpp b/src/output/netCdfException.hpp new file mode 100644 index 0000000000000000000000000000000000000000..15e9abaf877a18bb05962f0a2342733079899ba0 --- /dev/null +++ b/src/output/netCdfException.hpp @@ -0,0 +1,34 @@ +/*! + \file netCdfException.hpp + \author Ha NGUYEN + \date 08 Oct 2014 + \since 07 Oct 2014 + + \brief Exception management. + */ +#ifndef __NETCDF_EXCEPTION_HPP__ +#define __NETCDF_EXCEPTION_HPP__ + +#include +#include + +namespace xios +{ +/*! +\class CNetCdfException + This class manages exceptions risen by CNetCdfInterface +*/ +class CNetCdfException : public virtual std::exception +{ +public: + CNetCdfException(const std::string& ss) : exStr_(ss) {} + CNetCdfException(const CNetCdfException& netEx) : exStr_(netEx.exStr_) {} + ~CNetCdfException() throw() {} + const char* what() const throw() { return exStr_.c_str();} +protected: + std::string exStr_; +}; + +} + +#endif // __NETCDF_EXCEPTION_HPP__ diff --git a/src/output/netCdfInterface.cpp b/src/output/netCdfInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c58164c34c63e60f7a4e430b7f2b5ed44a005ec1 --- /dev/null +++ b/src/output/netCdfInterface.cpp @@ -0,0 +1,753 @@ +/*! + \file netCdfInterface.cpp + \author Ha NGUYEN + \date 08 Oct 2014 + \since 03 Oct 2014 + + \brief Wrapper of netcdf functions. + */ + +#include "netCdfInterface.hpp" +#include "netCdfException.hpp" + +namespace xios +{ +/*! +This function creates a new netcdf file and return its id +\param [in] fileName Name of the file +\param [in] cMode create mode +\param [in/out] ncId id of the created file +\return Status code +*/ +int CNetCdfInterface::create(const StdString& fileName, int cMode, int& ncId) +{ + int status = nc_create((fileName.c_str()), cMode, &ncId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + sstr << "Error in calling function : nc_create((fileName.c_str()), cMode, &ncId) " << std::endl + << errormsg << std::endl + << "Unable to create file, given its name : " << fileName + << "and its creation mode " << creationMode2String(cMode) << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function creates a new netcdf file on parallel file system +\param [in] fileName Name of the file +\param [in] cMode create mode +\param [in] comm MPI communicator +\param [in] info MPI information +\param [in/out] ncId id of the created file +\return Status code +*/ +int CNetCdfInterface::createPar(const StdString& fileName, int cMode, MPI_Comm comm, MPI_Info info, int& ncId) +{ + int status = xios::nc_create_par((fileName.c_str()), cMode, comm, info, &ncId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + sstr << "Error in calling function : nc_create_par((fileName.c_str()), cMode, comm, info, &ncId) " << std::endl + << errormsg << std::endl + << "Unable to create file on parallel filesys, given its name : " << std::endl + << "and its creation mode " << creationMode2String(cMode) << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function opens a netcdf file, given its name and open mode, return its id +\param [in] fileName Name of the file +\param [in] oMode open mode +\param [in/out] ncId id of the opening file +\return Status code +*/ +int CNetCdfInterface::open(const StdString& fileName, int oMode, int& ncId) +{ + int status = nc_open((fileName.c_str()), oMode, &ncId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + sstr << "Error in calling function : nc_open((fileName.c_str()), oMode, &ncId) "<< std::endl + << errormsg << std::endl + << "Unable to open file, given its name : " << fileName + << "and its open mode " << openMode2String(oMode) << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + + +/*! +This function opens a new netcdf file on parallel file system +\param [in] fileName Name of the file +\param [in] oMode open mode +\param [in] comm MPI communicator +\param [in] info MPI information +\param [in/out] ncId id of the opened file +\return Status code +*/ +int CNetCdfInterface::openPar(const StdString& fileName, int oMode, MPI_Comm comm, MPI_Info info, int& ncId) +{ + int status = xios::nc_open_par((fileName.c_str()), oMode, comm, info, &ncId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + sstr << "Error in calling function " << "nc_open_par((fileName.c_str()), oMode, comm, info, &ncId) " << std::endl + << errormsg << std::endl + << "Unable to open file on parallel filesys, given its name : " << fileName + << "and its open mode " << openMode2String(oMode) << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function closes a netcdf file, given its id +\param [in] ncId id of the opening netcdf file +\return Status code +*/ +int CNetCdfInterface::close(int ncId) +{ + int status = nc_close(ncId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + sstr << "Error in calling function " << "nc_close(ncId)" << std::endl + << errormsg << std::endl + << "Unable to close file, given its id : " << ncId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function put a netcdf file into define mode, given its id +\param [in] ncId id of the opening netcdf file to be put into define mode +\return Status code +*/ +int CNetCdfInterface::reDef(int ncId) +{ + int status = nc_redef(ncId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + sstr << "Error in calling function " << "nc_redef(ncId)" << std::endl + << errormsg << std::endl + << "Unable to put this file into define mode given its id : " << ncId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function ends a netcdf file define mode, given its id +\param [in] ncId id of the opening netcdf file to be put into define mode +\return Status code +*/ +int CNetCdfInterface::endDef(int ncId) +{ + int status = nc_enddef(ncId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_enddef(ncId)" << std::endl + << errormsg << std::endl + << "Unable to end define mode of this file, given its id : " << ncId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with ncid and group name then return ncid of the named group +\param [in] ncid Groupd id (or File Id) +\param [in] grpName Name of the desired group (or file) +\param [in/out] grpId Group id if the group is found +\return Status code +*/ +int CNetCdfInterface::inqNcId(int ncid, const StdString& grpName, int& grpId) +{ + int status = nc_inq_ncid(ncid, (grpName.c_str()), &grpId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_inq_ncid(ncid, (grpName.c_str()), &grpId)" << std::endl + << errormsg << std::endl + << "Unable to get id of a group (File), given its name : " << grpName << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + + +/*! +This function makes a request to netcdf with ncid and variable name then return ncid of the named variable +\param [in] ncid Groupd id (or File Id) +\param [in] varName Name of the desired variable +\param [in/out] varId Variable id if this variable is found +\return Status code +*/ +int CNetCdfInterface::inqVarId(int ncid,const StdString& varName, int& varId) +{ + int status = nc_inq_varid(ncid, (varName.c_str()), &varId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function : nc_inq_varid(ncid, (varName.c_str()), &varId)" << std::endl + << (errormsg) << std::endl + << "Unable to get id of variable with name : " << varName << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension +\param [in] ncid Groupd id (or File Id) +\param [in] dimName Name of the desired dimension +\param [in/out] dimId Dimension id if this dimension is found +\return Status code +*/ +int CNetCdfInterface::inqDimId(int ncid,const StdString& dimName, int& dimId) +{ + int status = nc_inq_dimid(ncid, (dimName.c_str()), &dimId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_inq_dimid(ncid, (dimName.c_str()), &dimId)" << std::endl + << errormsg << std::endl + << "Unable to get id of dimension, given its name : " << dimName << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension +\param [in] ncid Groupd id (or File Id) +\param [in/out] dimId Dimension id if this dimension is found +\return Status code +*/ +int CNetCdfInterface::inqUnLimDim(int ncid, int& dimId) +{ + int status = nc_inq_unlimdim(ncid, &dimId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_inq_dimid" << std::endl + << errormsg << std::endl + << "Unable to get id of unlimited dimension " << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf, returns name of a dimension, given its id +\param [in] ncid Groupd id (or File Id) +\param [in] dimId Id of desired dimension +\param [in/out] dimName Name of desired dimension +\return Status code +*/ +int CNetCdfInterface::inqDimName(int ncid, int dimId, StdString& dimName) +{ + char fullNameIn[NC_MAX_NAME +1]; + int status = nc_inq_dimname(ncid, dimId, fullNameIn); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_inq_dimname(ncid, dimId, fullNameIn)" << std::endl + << errormsg << std::endl + << "Unable to get dimension name from its id : " << dimId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + dimName = StdString(fullNameIn); + return status; +} + +/*! +This function makes a request to netcdf, returns length of a dimension, given its id +\param [in] ncid Groupd id (or File Id) +\param [in] dimId Id of desired dimension +\param [in/out] dimLen Length of desired dimension +\return Status code +*/ +int CNetCdfInterface::inqDimLen(int ncid, int dimId, StdSize& dimLen) +{ + int status = nc_inq_dimlen(ncid, dimId, &dimLen); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_inq_dimlen(ncid, dimId, &dimLen)" << std::endl + << errormsg << std::endl + << "Unable to get dimension length from its id: " << dimId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf, returns number of dimensions of a variable, given its id +\param [in] ncid Groupd id (or File Id) +\param [in] varId Id of variable +\param [in/out] ndims number of dimension of the variable +\return Status code +*/ +int CNetCdfInterface::inqVarNDims(int ncid, int varId, int& nDims) +{ + int status = nc_inq_varndims(ncid, varId, &nDims); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_inq_varndims(ncid, varId, &nDims)" << std::endl + << errormsg << std::endl + << "Unable to get the number of dimension of variable with Id : " << varId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf, returns a list of dimension ID describing the shape of the variable, given its id +\param [in] ncid Groupd id (or File Id) +\param [in] varId Id of variable +\param [in/out] dimIds list of dimension of the variable +\return Status code +*/ +int CNetCdfInterface::inqVarDimId(int ncid, int varId, int* dimIds) +{ + int status = nc_inq_vardimid(ncid, varId, dimIds); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_inq_vardimid(ncid, varId, dimIds)" << std::endl + << errormsg << std::endl + << "Unable to get list of dimension id of the variable with id " << varId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf, to find all dimension in a group +\param [in] ncid Groupd id (or File Id) +\param [in/out] nDims number of list of dimension +\param [in/out] dimIds list of dimension in a group or any of its parent +\param [in] includeParents number of parents +\return Status code +*/ +int CNetCdfInterface::inqDimIds(int ncid, int& nDims, int* dimIds, int includeParents) +{ + int status = nc_inq_dimids(ncid, &nDims, dimIds, includeParents); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_inq_dimids(ncid, &nDims, dimIds, includeParents)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to retrieve number of dimension in the group with id : " << ncid << std::endl; + sstr << "With number of Parents " << includeParents << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with a id of a prent groupd and then return id of the created group, given its name +\param [in] parentNcid Id of parent groupd(or File Id) +\param [in] grpName Name of the desired group +\param [in/out] grpId Group id if this group is created sucessfully +\return Status code +*/ +int CNetCdfInterface::defGrp(int parentNcid, const StdString& grpName, int& grpId) +{ + int status = nc_def_grp(parentNcid, (grpName.c_str()), &grpId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_def_grp(parentNcid, (grpName.c_str()), &grpId)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to create group Id, given its name : " << grpName << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf, add a new dimension to an open netcdf in define mode +\param [in] ncid Id of groupd(or File Id) +\param [in] dimName Name of the desired dimension +\param [in/out] grpId Group id if this group is created sucessfully +\return Status code +*/ +int CNetCdfInterface::defDim(int ncid, const StdString& dimName, StdSize dimLen, int& dimId) +{ + int status = nc_def_dim(ncid, (dimName.c_str()), dimLen, &dimId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_def_dim(ncid, (dimName.c_str()), dimLen, &dimId)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to create dimension with name : " << dimName + << " and with length " << dimLen << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with its id, to add a new variable to an open netCdf in define mode, +return a variable id, given its name, type, the number of dimensions and list of dimension id +\param [in] ncid Id of groupd(or File Id) +\param [in] varName Name of the desired dimension +\param [in] xtypes One of the set of predefined netCDF data types +\param [in] nDims Number of dimension for the variable +\param [in] dimIds List of ndims dimension ids corresponding to the variable dimensions +\param [in/out] varId Variable id if it is added sucessfully +\return Status code +*/ +int CNetCdfInterface::defVar(int ncid,const StdString& varName, nc_type xtype, + int nDims, const int dimIds[], int& varId) +{ + int status = nc_def_var(ncid, (varName.c_str()), xtype, nDims, dimIds, &varId); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << " nc_def_var(ncid, (varName.c_str()), xtype, nDims, dimIds, &varId)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to add a new variable with name : " << varName + << " with type " << xtype + << " and number of dimension " << nDims << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with a ncid, to set the chunking size of a variable, +given variable id and type of storage +\param [in] ncid Id groupd(or File Id) +\param [in] varId Id of the variable +\param [in] storage Type of storage (It can be : NC_CONTIGUOUS, NC_CHUNKED) +\param [in/out] chunkSize array list of chunk sizes +\return Status code +*/ +int CNetCdfInterface::defVarChunking(int ncid, int varId, int storage, StdSize chunkSize[]) +{ + int status = nc_def_var_chunking(ncid, varId, storage, chunkSize); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_def_var_chunking(ncid, varId, storage, chunkSize)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to set chunk size of the variable with id : " << varId + << " and storage type " << storage << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with a ncid, to set the fill parameters for a variable, +given variable id and type of fill +\param [in] ncid Id groupd(or File Id) +\param [in] varId Id of the variable +\param [in] noFill turn on/off nofill mode on a variable +\param [in/out] fillValue +\return Status code +*/ +int CNetCdfInterface::defVarFill(int ncid, int varId, int noFill, void* fillValue) +{ + int status = nc_def_var_fill(ncid, varId, noFill, fillValue); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_def_var_fill(ncid, varId, noFill, fillValue)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to set fill parameters of the variable with id : " << varId + << " and fill option " << noFill << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with a ncid, to change the way read/write operations are performed +collectively or independently on the variable. +\param [in] ncid Id groupd(or File Id) +\param [in] varId Id of the variable +\param [in] noFill turn on/off nofill mode on a variable +\param [in/out] fillValue +\return Status code +*/ +int CNetCdfInterface::varParAccess(int ncid, int varId, int access) +{ + int status = nc_var_par_access(ncid, varId, access); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_var_par_access(ncid, varId, access)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to change read/write option of the variable with id : " << varId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a synchronisation of the disk copy of a netCDF dataset. +\param [in] ncid Id groupd(or File Id) +\return Status code +*/ +int CNetCdfInterface::sync(int ncid) +{ + int status = nc_sync(ncid); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_sync(ncid)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to make a synchronization of a netCDF file with id : " << ncid << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + +/*! +This function makes a request to netcdf with its id, to add or change a variable attribute or gloabl attribute, +given its name, type, number of values provided for attribute +\param [in] ncid Id of groupd(or File Id) +\param [in] varId Id of the variable +\param [in] attrName Name of the attribute +\param [in] xtypes One of the set of predefined netCDF data types +\param [in] numVal Number of values +\param [in] op Array of values provided for attribute +\return Status code +*/ +int CNetCdfInterface::putAtt(int ncid, int varId, const StdString& attrName, nc_type xtype, + StdSize numVal, const void* op) +{ + int status = nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + + sstr << "Error in calling function " << "nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to set attribute " << attrName << " for a variable with id : " << varId + << " with number of attribute " << numVal + << " with type " << xtype << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; +} + + // Some specilization of putAttributeType +template<> +int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, + StdSize numVal, const double* op) +{ + return (nc_put_att_double(ncid, varid, attrName, NC_DOUBLE, numVal, op)); +} + +template<> +int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, + StdSize numVal, const float* op) +{ + return (nc_put_att_float(ncid, varid, attrName, NC_FLOAT, numVal, op)); +} + +template<> +int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, + StdSize numVal, const int* op) +{ + return (nc_put_att_int(ncid, varid, attrName, NC_INT, numVal, op)); +} + +template<> +int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, + StdSize numVal, const long* op) +{ + return (nc_put_att_long(ncid, varid, attrName, NC_LONG, numVal, op)); +} + +template<> +int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, + StdSize numVal, const short* op) +{ + return (nc_put_att_short(ncid, varid, attrName, NC_SHORT, numVal, op)); +} + + +// Some specilization of putVariableType +template<> +int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const double* op) +{ + return (nc_put_vara_double(ncid, varid, start, count, op)); +} + +template<> +int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const float* op) +{ + return (nc_put_vara_float(ncid, varid, start, count, op)); +} + +template<> +int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const int* op) +{ + return (nc_put_vara_int(ncid, varid, start, count, op)); +} + + /*! + This function verifies an existence of a variable by using its name. + Be careful, althoug false means variable doens't exist, it could show that netCDF file doesn't either + \param [in] ncid Id of groupd(or File Id) + \param [in] attrName Name of the variable + \return Existence of variable + */ +bool CNetCdfInterface::isVarExisted(int ncId, const StdString& varName) +{ + int varId = 0; + return (NC_NOERR == (nc_inq_varid(ncId, varName.c_str(), &varId))); +} + +StdString CNetCdfInterface::openMode2String(int oMode) +{ + StdString modeMes; + switch (oMode) + { + case NC_NOWRITE: + modeMes = StdString("NC_NOWRITE : Opening netCDF file with read-only access with buffering and caching access"); + break; + case NC_SHARE: + modeMes = StdString("NC_SHARE : Several processes can read the file concurrently"); + break; + case NC_WRITE: + modeMes = StdString("NC_WRITE : NetCDF file is readable and writable"); + break; + default: + modeMes = StdString("In the composed opening mode"); + break; + } + return modeMes; +} + +StdString CNetCdfInterface::creationMode2String(int cMode) +{ + StdString modeMes; + switch (cMode) + { + case NC_NOCLOBBER: + modeMes = StdString("NC_NOCLOBBER : Not overwrite an exisiting netCDF file "); + break; + case NC_SHARE: + modeMes = StdString("NC_SHARE : Several processes can read from and write into the file concurrently"); + break; + case NC_64BIT_OFFSET: + modeMes = StdString("NC_64BIT_OFFSET : NetCDF file is 64-bit offset"); + break; + case NC_NETCDF4: + modeMes = StdString("NC_NETCDF4 : NetCDF file is HDF5/NetCDF-4"); + break; + case NC_CLASSIC_MODEL: + modeMes = StdString("NC_CLASSIC_MODEL : NetCDF file is classical model"); + break; + default: + modeMes = StdString("In the composed creation mode"); + break; + } + return modeMes; +} + + } diff --git a/src/output/netCdfInterface.hpp b/src/output/netCdfInterface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..57d1cfa52896f84ff92691865b5ef52c8bf33954 --- /dev/null +++ b/src/output/netCdfInterface.hpp @@ -0,0 +1,137 @@ +/*! + \file netCdfInterface.hpp + \author Ha NGUYEN + \date 08 Oct 2014 + \since 03 Oct 2014 + + \brief Wrapper of netcdf functions. + */ +#ifndef __NETCDF_INTERFACE_HPP_ +#define __NETCDF_INTERFACE_HPP_ + +#include "xmlioserver_spl.hpp" + +#if !defined(USING_NETCDF_PAR) +#include "exception.hpp" +#endif + +#include "mpi.hpp" +#include "netcdf.hpp" + +namespace xios +{ + /*! + \class CNetCdfInterface + This class is wrapper of some common used functions of netCdf in Xios + */ + class CNetCdfInterface + { + public: + //! Create a netcdf file + static int create(const StdString& path, int cmode, int& ncId); + + //! Create a netcdf file on a parallel file system + static int createPar(const StdString& path, int cmode, MPI_Comm comm, MPI_Info info, int& ncId); + + //! Open a netcdf file + static int open(const StdString& path, int oMode, int& ncId); + + //! Open a netcdf file + static int openPar(const StdString& path, int cmode, MPI_Comm comm, MPI_Info info, int& ncId); + + //! Close a netcdf file + static int close(int ncId); + + //! Put netcdf file into define mode + static int reDef(int ncId); + + //! End define mode of a netcdf file + static int endDef(int ncId); + + //! Query identity of a named group + static int inqNcId(int ncid, const StdString& grpName, int& grpId); + + //! Query identity of a named variable + static int inqVarId(int ncid, const StdString& varName, int& varId); + + //! Query identity of a named dimension + static int inqDimId(int ncid,const StdString& dimName, int& dimId); + + //! Query identity of unlimited dimension + static int inqUnLimDim(int ncid, int& dimId); + + //! Query name of a dimension with its id + static int inqDimName(int ncid, int dimId, StdString& dimName); + + //! Query length of dimension with its id + static int inqDimLen(int ncid, int dimId, StdSize& dimLen); + + //! Query number of dimension of a variable with its id + static int inqVarNDims(int ncid, int varId, int& nDims); + + //! Query list of dimension of a variable with its id + static int inqVarDimId(int, int, int*); + + //! Query dimensions of a group + static int inqDimIds(int ncid, int& nDims, int* dimIds, int includeParents); + + + //! Define a group + static int defGrp(int parentNcid,const StdString& grpName, int& grpId); + + //! Define a dimension + static int defDim(int ncid,const StdString& dimName, StdSize dimLen, int& dimId); + + //! Define a variable + static int defVar(int ncid,const StdString& varName, nc_type xtype, + int nDims, const int dimIds[], int& varId); + + //! Define variable chunking size + static int defVarChunking(int ncid, int varId, int storage, StdSize chunkSize[]); + + //! Define variable fill parameters + static int defVarFill(int ncid, int varId, int noFill, void* fillValue); + + + //! Change access type of a variable + static int varParAccess(int ncid, int varid, int access); + + //! Syn + static int sync(int ncId); + + //! Put attribute into variable + static int putAtt(int ncid, int varid, const StdString& attrName, nc_type xtype, + StdSize numVal, const void* op); + + + //! Put attribute into variable with specific type + template + static int putAttType(int ncid, int varid, const StdString& attrName, StdSize numVal, const T* op); + + //! Put value into a variable with a specific type + template + static int putVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const T* op); + + private: + template + static int ncPutAttType(int ncid, int varid, const char* attrName, StdSize numVal, const T* op); + + template + static int ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const T* op); + + private: + static StdString openMode2String(int oMode); + + static StdString creationMode2String(int cMode); + + + public: + // Some functions dedude from several special cases + //! Query the existence of a variable + static bool isVarExisted(int ncId, const StdString& varName); + + }; +} + + +#endif // NETCDFINTERFACE_HPP_ diff --git a/src/output/netCdfInterface_decl.cpp b/src/output/netCdfInterface_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2fb39d6cc459cfde3df52780a336576fd039860b --- /dev/null +++ b/src/output/netCdfInterface_decl.cpp @@ -0,0 +1,30 @@ +/*! + \file netCdfInterface_impl.hpp + \author Ha NGUYEN + \date 06 Oct 2014 + \since 06 Oct 2014 + + \brief Implemention of some templated functions in netCdfInterface + */ + +#include "netCdfInterface_impl.hpp" + +namespace xios +{ +#define macroPutAtt(type) \ + template int CNetCdfInterface::putAttType(int ncid, int varid, const StdString& attrName, \ + StdSize numVal, const type* op); + + macroPutAtt(double); + macroPutAtt(float); + macroPutAtt(int); + macroPutAtt(long); + macroPutAtt(short); + +#define macroPutVar(type) \ + template int CNetCdfInterface::putVaraType(int ncid, int varId, const StdSize* start, \ + const StdSize* count, const type* op); + macroPutVar(double); + macroPutVar(float); + macroPutVar(int); +} diff --git a/src/output/netCdfInterface_impl.hpp b/src/output/netCdfInterface_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a397763536faa87f000f0944d6a8770c79eebb49 --- /dev/null +++ b/src/output/netCdfInterface_impl.hpp @@ -0,0 +1,77 @@ +/*! + \file netCdfInterface_impl.hpp + \author Ha NGUYEN + \date 08 Oct 2014 + \since 06 Oct 2014 + + \brief Implemention of some templated functions in netCdfInterface + */ + +#ifndef __NETCDF_INTERFACE_IMPL_HPP__ +#define __NETCDF_INTERFACE_IMPL_HPP__ + +#include "netCdfInterface.hpp" +#include "netCdfException.hpp" + +namespace xios +{ + /*! + This function makes a request to netcdf with its id, to add or change a variable attribute or gloabl attribute, + given its name, type, number of values provided for attribute + \param [in] ncid Id of groupd(or File Id) + \param [in] varId Id of the variable + \param [in] attrName Name of the attribute + \param [in] numVal Number of values + \param [in] op Array of values provided for attribute + \return Error code + */ + template + int CNetCdfInterface::putAttType(int ncid, int varId, const StdString& attrName, + StdSize numVal, const T* op) + { + int status = ncPutAttType(ncid, varId, attrName.c_str(), numVal, op); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + sstr << "Error in calling function " << "ncPutAttType(ncid, varId, attrName.c_str(), numVal, op)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to set attribute " << attrName << " for a variable with id : " << varId + << " with number of attribute " << numVal << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; + } + + /*! + This function makes a request to netcdf with its id, to write variable values into netcdf file, + \param [in] ncid Id of groupd(or File Id) + \param [in] varId Id of the variable + \param [in] start Array specifying the index in the variable where the first data value will be written + \param [in] count Array specifying the edge lengths along each dimension of block data + \param [in] op Array of values provided for attribute + \return Error code + */ + template + int CNetCdfInterface::putVaraType(int ncid, int varId, const StdSize* start, const StdSize* count, const T* op) + { + int status = ncPutVaraType(ncid, varId, start, count, op); + if (NC_NOERR != status) + { + StdString errormsg(nc_strerror(status)); + StdStringStream sstr; + sstr << "Error in calling function " << "ncPutVaraType(ncid, varId, start, count, op)" << std::endl; + sstr << errormsg << std::endl; + sstr << "Unable to write value of a variable with id : " << varId << std::endl; + StdString e = sstr.str(); + throw CNetCdfException(e); + } + + return status; + } + +} + +#endif // __NETCDF_INTERFACE_IMPL_HPP__ diff --git a/src/output/netcdf.hpp b/src/output/netcdf.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e358426d60151e2989f333edab09df08894b6c09 --- /dev/null +++ b/src/output/netcdf.hpp @@ -0,0 +1,67 @@ +#ifndef __XIOS_NETCDF_HPP__ +#define __XIOS_NETCDF_HPP__ +#include "mpi.hpp" +#define MPI_INCLUDED +#include + +#if defined(USING_NETCDF_INTERNAL) + const bool using_netcdf_internal=true ; +#else + const bool using_netcdf_internal=false ; +#endif + +#include "netcdf_version.hpp" + +#if NETCDF_VERSION >= 4110 + +# if defined(USING_NETCDF_PAR) +extern "C" +{ +# include +} +# endif +#endif + +#if !defined(USING_NETCDF_PAR) +#define NC_INDEPENDENT 0 +#define NC_COLLECTIVE 1 +#endif + +namespace xios +{ + inline int nc_create_par(const char *path, int cmode, MPI_Comm comm, MPI_Info info,int *ncidp) + { +#if defined(USING_NETCDF_PAR) + return ::nc_create_par(path, cmode, comm, info, ncidp) ; +#else + ERROR("int nc_create_par(const char *path, int cmode, MPI_Comm comm, MPI_Info info,int *ncidp)", + << "must not be use with netcdf sequential version") ; + return -1 ; +#endif + } + + inline int nc_open_par(const char *path, int mode, MPI_Comm comm, MPI_Info info,int *ncidp) + { +#if defined(USING_NETCDF_PAR) + return ::nc_open_par(path, mode, comm, info, ncidp) ; +#else + ERROR("int nc_open_par(const char *path, int mode, MPI_Comm comm, MPI_Info info,int *ncidp)", + << "must not be use with netcdf sequential version") ; + return -1 ; +#endif + } + + inline int nc_var_par_access(int ncid, int varid, int par_access) + { +#if defined(USING_NETCDF_PAR) + return ::nc_var_par_access(ncid, varid, par_access) ; +#else + ERROR("int nc_var_par_access(int ncid, int varid, int par_access)", + << "must not be use with netcdf sequential version") ; + return -1 ; +#endif + } +} + + +#endif diff --git a/src/output/netcdf_version.hpp b/src/output/netcdf_version.hpp new file mode 100644 index 0000000000000000000000000000000000000000..041b7bed9c55e80285e444267202085804ed380c --- /dev/null +++ b/src/output/netcdf_version.hpp @@ -0,0 +1,34 @@ +#ifndef __XIOS_NETCDF_VERSION_HPP__ +#define __XIOS_NETCDF_VERSION_HPP__ + +#if defined(NC_DISKLESS) && defined (NC_MMAP) + +# define NETCDF_VERSION 4211 + +#elif defined(NC_ETRANSLATION) + +# define NETCDF_VERSION 4130 + +#elif defined(NC_EURL) && defined(NC_ECONSTRAINT) + +# define NETCDF_VERSION 4120 + +#elif defined (NC_PNETCDF) + +# define NETCDF_VERSION 4110 + +#elif defined(NC_CHUNKED) && defined(NC_CONTIGUOUS) + +# define NETCDF_VERSION 4010 + +#elif defined(NC_NETCDF4) + +# define NETCDF_VERSION 4000 + +#else + +# error "netcdf version prior 4.0 incompatible with XIOS" + +#endif + +#endif diff --git a/src/output/onetcdf4.cpp b/src/output/onetcdf4.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ee741e44355ef0f675e90bd3de7082c3991c6a76 --- /dev/null +++ b/src/output/onetcdf4.cpp @@ -0,0 +1,522 @@ +#include "onetcdf4.hpp" +#include "group_template.hpp" +#include "mpi.hpp" +#include "netcdf.hpp" +#include "netCdfInterface.hpp" +#include "netCdfException.hpp" + +namespace xios +{ + /// ////////////////////// Définitions ////////////////////// /// + + CONetCDF4::CONetCDF4 + (const StdString & filename, bool exist, const MPI_Comm * comm, bool multifile) + : path() + { + this->wmpi = (comm != NULL) && !multifile; + this->initialize(filename, exist, comm,multifile); + } + + //--------------------------------------------------------------- + + + CONetCDF4::~CONetCDF4(void) + { +// CheckError(nc_close(this->ncidp)); + } + + ///-------------------------------------------------------------- + + void CONetCDF4::initialize + (const StdString & filename, bool exist, const MPI_Comm * comm, bool multifile) + { + if (!exist) + { + if (comm != NULL) + { + if (!multifile) (CNetCdfInterface::createPar(filename, NC_NETCDF4|NC_MPIIO, *comm, MPI_INFO_NULL, (this->ncidp))); + else (CNetCdfInterface::create(filename, NC_NETCDF4, this->ncidp)); + } + else (CNetCdfInterface::create(filename, NC_NETCDF4, this->ncidp)); + } + else + { + if (comm != NULL) + { + if (!multifile) (CNetCdfInterface::openPar(filename, NC_NETCDF4|NC_MPIIO, *comm, MPI_INFO_NULL, this->ncidp)); + else (CNetCdfInterface::open(filename, NC_NETCDF4, this->ncidp)); + } + else (CNetCdfInterface::open(filename, NC_NETCDF4, this->ncidp)); + } + } + + void CONetCDF4::close() + { + (CNetCdfInterface::close(this->ncidp)); + } + + //--------------------------------------------------------------- + + void CONetCDF4::definition_start(void) + { + (CNetCdfInterface::reDef(this->ncidp)); + } + + //--------------------------------------------------------------- + + void CONetCDF4::definition_end(void) + { + (CNetCdfInterface::endDef(this->ncidp)); + } + + //--------------------------------------------------------------- + +// Don't need it anymore? +// void CONetCDF4::CheckError(int status) +// { +// if (status != NC_NOERR) +// { +// StdString errormsg (nc_strerror(status)); // fuite mémoire ici ? +// ERROR("CONetCDF4::CheckError(int status)", +// << "[ status = " << status << " ] " << errormsg); +// } +// } + + //--------------------------------------------------------------- + + int CONetCDF4::getCurrentGroup(void) + { + return (this->getGroup(this->getCurrentPath())); + } + + //--------------------------------------------------------------- + + int CONetCDF4::getGroup(const CONetCDF4Path & path) + { + int retvalue = this->ncidp; + + CONetCDF4Path::const_iterator + it = path.begin(), end = path.end(); + + for (;it != end; it++) + { + const StdString & groupid = *it; + (CNetCdfInterface::inqNcId(retvalue, groupid, retvalue)); + } + return (retvalue); + } + + //--------------------------------------------------------------- + + int CONetCDF4::getVariable(const StdString & varname) + { + int varid = 0; + int grpid = this->getCurrentGroup(); + (CNetCdfInterface::inqVarId(grpid, varname, varid)); + return (varid); + } + + //--------------------------------------------------------------- + + int CONetCDF4::getDimension(const StdString & dimname) + { + int dimid = 0; + int grpid = this->getCurrentGroup(); + (CNetCdfInterface::inqDimId(grpid, dimname, dimid)); + return (dimid); + } + + //--------------------------------------------------------------- + + int CONetCDF4::getUnlimitedDimension(void) + { + int dimid = 0; + int grpid = this->getCurrentGroup(); + (CNetCdfInterface::inqUnLimDim(grpid, dimid)); + return (dimid); + } + + StdString CONetCDF4::getUnlimitedDimensionName(void) + { + int grpid = this->getGroup(path); + int dimid = this->getUnlimitedDimension(); + + if (dimid == -1) return (std::string()); + StdString dimname; + (CNetCdfInterface::inqDimName(grpid, dimid, dimname)); + + return (dimname); + } + + //--------------------------------------------------------------- + + std::vector CONetCDF4::getDimensions(const StdString & varname) + { + StdSize size = 0; + std::vector retvalue; + int grpid = this->getCurrentGroup(); + int varid = this->getVariable(varname); + int nbdim = 0, *dimid = NULL; + + (CNetCdfInterface::inqVarNDims(grpid, varid, nbdim)); + dimid = new int[nbdim](); + (CNetCdfInterface::inqVarDimId(grpid, varid, dimid)); + + for (int i = 0; i < nbdim; i++) + { + (CNetCdfInterface::inqDimLen(grpid, dimid[i], size)); + if (size == NC_UNLIMITED) + size = UNLIMITED_DIM; + retvalue.push_back(size); + } + delete [] dimid; + return (retvalue); + } + + std::vector CONetCDF4::getDimensionsIdList (const std::string * _varname) + { + int nDimNull = 0; + int nbdim = 0, *dimid = NULL; + int grpid = this->getCurrentGroup(); + int varid = (_varname != NULL) ? this->getVariable(*_varname) : NC_GLOBAL; + std::vector retvalue; + + if (_varname != NULL) + { + (CNetCdfInterface::inqVarNDims(grpid, varid, nbdim)); + dimid = new int[nbdim](); + (CNetCdfInterface::inqVarDimId(grpid, varid, dimid)); + } + else + { + (CNetCdfInterface::inqDimIds(grpid, nbdim, NULL, 1)); + dimid = new int[nbdim](); + (CNetCdfInterface::inqDimIds(grpid, nDimNull, dimid, 1)); + } + + for (int i = 0; i < nbdim; i++) + { + std::string dimname; + (CNetCdfInterface::inqDimName(grpid, dimid[i], dimname)); + retvalue.push_back(dimname); + } + delete [] dimid; + + return (retvalue); + } + + + //--------------------------------------------------------------- + + const CONetCDF4::CONetCDF4Path & CONetCDF4::getCurrentPath(void) const + { return (this->path); } + + void CONetCDF4::setCurrentPath(const CONetCDF4Path & path) + { this->path = path; } + + //--------------------------------------------------------------- + + int CONetCDF4::addGroup(const StdString & name) + { + int retvalue = 0; + int grpid = this->getCurrentGroup(); + (CNetCdfInterface::defGrp(grpid, name, retvalue)); + return (retvalue); + } + + //--------------------------------------------------------------- + + int CONetCDF4::addDimension(const StdString& name, const StdSize size) + { + int retvalue = 0; + int grpid = this->getCurrentGroup(); + if (size != UNLIMITED_DIM) + (CNetCdfInterface::defDim(grpid, name, size, retvalue)); + else + (CNetCdfInterface::defDim(grpid, name, NC_UNLIMITED, retvalue)); + return (retvalue); + } + + //--------------------------------------------------------------- + + int CONetCDF4::addVariable(const StdString & name, nc_type type, + const std::vector & dim) + { + int varid = 0; + std::vector dimids; + std::vector dimsizes ; + StdSize size ; + StdSize totalSize ; + StdSize maxSize=1024*1024*256 ; // == 2GB/8 if output double + + int grpid = this->getCurrentGroup(); + + std::vector::const_iterator + it = dim.begin(), end = dim.end(); + + for (;it != end; it++) + { + const StdString & dimid = *it; + dimids.push_back(this->getDimension(dimid)); + (CNetCdfInterface::inqDimLen(grpid, this->getDimension(dimid), size)); + if (size==NC_UNLIMITED) size=1 ; + dimsizes.push_back(size) ; + } + + (CNetCdfInterface::defVar(grpid, name, type, dimids.size(), &(dimids[0]), varid)); + +// set chunksize : size of one record +// but must not be > 2GB (netcdf or HDF5 problem) + totalSize=1 ; + for(vector::reverse_iterator it=dimsizes.rbegin(); it!=dimsizes.rend();++it) + { + totalSize*= *it ; + if (totalSize>=maxSize) *it=1 ; + } + + (CNetCdfInterface::defVarChunking(grpid, varid, NC_CHUNKED, &(dimsizes[0]))); + (CNetCdfInterface::defVarFill(grpid, varid, true, NULL)); + return (varid); + } + + //--------------------------------------------------------------- + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const StdString & value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAtt(grpid, varid, name, NC_CHAR, value.size(), value.c_str())); + //CheckError(nc_put_att_string(grpid, varid, name.c_str(), 1, &str)); + } + + //--------------------------------------------------------------- + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const double & value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value)); + } + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const CArray& value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst())); + } + //--------------------------------------------------------------- + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const float & value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value)); + } + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const CArray& value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst())); + } + + //--------------------------------------------------------------- + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const int & value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value)); + } + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const CArray& value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst())); + } + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const short int & value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value)); + } + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const CArray& value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst())); + } + + + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const long int & value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, 1, &value)); + } + + template <> + void CONetCDF4::addAttribute + (const StdString & name, const CArray& value, const StdString * varname ) + { + int grpid = this->getCurrentGroup(); + int varid = (varname == NULL) ? NC_GLOBAL : this->getVariable(*varname); + (CNetCdfInterface::putAttType(grpid, varid, name, value.numElements(), value.dataFirst())); + } + + + + //--------------------------------------------------------------- + + void CONetCDF4::getWriteDataInfos(const StdString & name, StdSize record, StdSize & array_size, + std::vector & sstart, + std::vector & scount, + const std::vector * start, + const std::vector * count) + { + std::vector sizes = this->getDimensions(name); + std::vector iddims = this->getDimensionsIdList (&name); + std::vector::const_iterator + it = sizes.begin(), end = sizes.end(); + int i = 0; + + if (iddims.begin()->compare(this->getUnlimitedDimensionName()) == 0) + { + sstart.push_back(record); + scount.push_back(1); + if ((start == NULL) && + (count == NULL)) i++; + it++; + } + + for (;it != end; it++) + { + if ((start != NULL) && (count != NULL)) + { + sstart.push_back((*start)[i]); + scount.push_back((*count)[i]); + array_size *= (*count)[i]; + i++; + } + else + { + sstart.push_back(0); + scount.push_back(sizes[i]); + array_size *= sizes[i]; + i++; + } + } + + } + + + + template <> + void CONetCDF4::writeData_(int grpid, int varid, + const std::vector & sstart, + const std::vector & scount, const double * data) + { + (CNetCdfInterface::putVaraType(grpid, varid, &(sstart[0]), &(scount[0]), data)); +// sync() ; + } + + //--------------------------------------------------------------- + + template <> + void CONetCDF4::writeData_(int grpid, int varid, + const std::vector & sstart, + const std::vector & scount, const int * data) + { + (CNetCdfInterface::putVaraType(grpid, varid, &(sstart[0]), &(scount[0]), data)); +// sync() ; + } + + //--------------------------------------------------------------- + + template <> + void CONetCDF4::writeData_(int grpid, int varid, + const std::vector & sstart, + const std::vector & scount, const float * data) + { + (CNetCdfInterface::putVaraType(grpid, varid, &(sstart[0]), &(scount[0]), data)); +// sync() ; + } + + //--------------------------------------------------------------- + + void CONetCDF4::writeData(const CArray& data, const StdString & name) + { + int grpid = this->getCurrentGroup(); + int varid = this->getVariable(name); + StdSize array_size = 1; + std::vector sstart, scount; + + this->getWriteDataInfos(name, 0, array_size, sstart, scount, NULL, NULL); + this->writeData_(grpid, varid, sstart, scount, data.dataFirst()); + } + + void CONetCDF4::writeTimeAxisData(const CArray& data, const StdString & name, + bool collective, StdSize record, bool isRoot) + { + int grpid = this->getCurrentGroup(); + int varid = this->getVariable(name); + + map::iterator it=timeAxis.find(varid) ; + if (it==timeAxis.end()) timeAxis[varid]=record ; + else + { + if (it->second >= record) return ; + else it->second =record ; + } + + StdSize array_size = 1; + std::vector sstart, scount; + + if (this->wmpi && collective) + (CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE)); + if (this->wmpi && !collective) + (CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT)); + + this->getWriteDataInfos(name, record, array_size, sstart, scount, NULL, NULL); + if (using_netcdf_internal) if (!isRoot) { sstart[0]=sstart[0]+1 ; scount[0]=0 ;} + this->writeData_(grpid, varid, sstart, scount, data.dataFirst()); + } + + //--------------------------------------------------------------- + + bool CONetCDF4::varExist(const StdString & varname) + { + int grpid = this->getCurrentGroup(); + return (CNetCdfInterface::isVarExisted(grpid, varname)); + } + + void CONetCDF4::sync(void) + { + (CNetCdfInterface::sync(this->ncidp)) ; + } + ///-------------------------------------------------------------- + } // namespace xios diff --git a/src/output/onetcdf4.hpp b/src/output/onetcdf4.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bd77e19e30e2525e340439c86c4d70f640e13991 --- /dev/null +++ b/src/output/onetcdf4.hpp @@ -0,0 +1,125 @@ +#ifndef __XMLIO_INETCDF4__ +#define __XMLIO_INETCDF4__ + +/// xios headers /// +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "data_output.hpp" +#include "array_new.hpp" +#include "mpi.hpp" +#include "netcdf.hpp" + +#ifndef UNLIMITED_DIM + #define UNLIMITED_DIM (size_t)(-1) +#endif //UNLIMITED_DIM + +namespace xios +{ + /// ////////////////////// Déclarations ////////////////////// /// + class CONetCDF4 + : public virtual CDataOutput + { + public : + + /// Définition de type /// + typedef std::vector CONetCDF4Path; + + /// Constructeurs /// + CONetCDF4(const StdString & filename, bool exist, const MPI_Comm * comm = NULL, bool multifile=true); + + CONetCDF4(const CONetCDF4 & onetcdf4); // Not implemented. + CONetCDF4(const CONetCDF4 * const onetcdf4); // Not implemented. + + + /// Initialisation /// + void initialize(const StdString & filename, bool exist, const MPI_Comm * comm, bool multifile); + void close(void) ; + void sync(void) ; + void definition_start(void); + void definition_end(void); + + /// Mutateurs /// + void setCurrentPath(const CONetCDF4Path & path); + + int addGroup(const StdString & name); + int addDimension(const StdString& name, const StdSize size = UNLIMITED_DIM); + int addVariable(const StdString & name, nc_type type, + const std::vector & dim); + + //---------------------------------------------------------------- + public : + + template + void setDefaultValue(const StdString & varname, const T * value = NULL); + + template void addAttribute (const StdString & name, const T & value, const StdString * varname = NULL); + + /// Ecriture des données /// + template + void writeData(const CArray& data, const StdString & name, + bool collective, StdSize record, + const std::vector * start = NULL, + const std::vector * count = NULL); + + void writeData(const CArray& data, const StdString & name); + void writeTimeAxisData(const CArray& data, const StdString & name, + bool collective, StdSize record, bool Isroot) ; + /// Accesseur /// + const CONetCDF4Path & getCurrentPath(void) const; + + /// Destructeur /// + virtual ~CONetCDF4(void); + + //---------------------------------------------------------------- + + protected : + + /// Ecriture /// + virtual void writeField_ (CField* field) = 0; + virtual void writeDomain_(CDomain* domain) = 0; + virtual void writeAxis_ (CAxis* axis) = 0; + + /// Accesseurs /// + int getCurrentGroup(void); + int getGroup(const CONetCDF4Path & path); + int getVariable(const StdString & varname); + int getDimension(const StdString & dimname); + std::vector getDimensions (const StdString & varname); + std::vector getDimensionsIdList (const StdString * varname); + int getUnlimitedDimension(void); + StdString getUnlimitedDimensionName(void); + + bool varExist(const StdString & varname); + + //---------------------------------------------------------------- + + private : + + template + void writeData_(int grpid, int varid, + const std::vector & sstart, + const std::vector & scount, T * data); + + void getWriteDataInfos(const StdString & name, StdSize record, StdSize & array_size, + std::vector & sstart, + std::vector & scount, + const std::vector * start, + const std::vector * count); + + /// Vérification des erreurs NetCDF /// + void CheckError(int status); + + /// Propriétés privées /// + CONetCDF4Path path; + int ncidp; + bool wmpi; + map timeAxis ; + }; // class CONetCDF4 + + ///--------------------------------------------------------------- + + + +} // namespace xios + +#endif //__XMLIO_INETCDF4__ diff --git a/src/output/onetcdf4_decl.cpp b/src/output/onetcdf4_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9e8a54edae08a617b99cbfd558a75d08b6fbf44 --- /dev/null +++ b/src/output/onetcdf4_decl.cpp @@ -0,0 +1,17 @@ +#include "onetcdf4_impl.hpp" + +namespace xios +{ +# define macro(type,size) \ + template void CONetCDF4::writeData(const CArray& data, const StdString & name, \ + bool collective, StdSize record, \ + const std::vector * start, \ + const std::vector * count) ; + + macro(double,1) + macro(double,2) + macro(double,3) + + template void CONetCDF4::setDefaultValue(const StdString & varname, const double* value) ; + template void CONetCDF4::setDefaultValue(const StdString & varname, const float* value) ; +} diff --git a/src/output/onetcdf4_impl.hpp b/src/output/onetcdf4_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1cff9fb7ec88ff08e1e5de3563f13b1414dc8eae --- /dev/null +++ b/src/output/onetcdf4_impl.hpp @@ -0,0 +1,60 @@ +#ifndef __ONETCDF4_IMPL_HPP__ +#define __ONETCDF4_IMPL_HPP__ + +#include "onetcdf4.hpp" +#include "netCdfInterface.hpp" + +namespace xios +{ + template + void CONetCDF4::writeData(const CArray& data, const StdString & name, + bool collective, StdSize record, + const std::vector * start, + const std::vector * count) + { + int grpid = this->getCurrentGroup(); + int varid = this->getVariable(name); + StdSize array_size = 1; + std::vector sstart, scount; + + if (this->wmpi && collective) + CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE); + if (this->wmpi && !collective) + CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT); + + this->getWriteDataInfos + (name, record, array_size, sstart, scount, start, count); + if (data.numElements() != array_size) + { + ERROR("CONetCDF4::writeData(...)", + << "[ input array size = " << data.numElements() + << ", intern array size = " << array_size + << " ] Invalid input data !" ); + } + + this->writeData_(grpid, varid, sstart, scount, data.dataFirst()); + } + +//---------------------------------------------------------------- + + template + void CONetCDF4::setDefaultValue(const StdString & varname, const T * value) + { + int grpid = this->getCurrentGroup(); + int varid = this->getVariable(varname); + + if (value != NULL) + { + CNetCdfInterface::defVarFill(grpid, varid, 0, (void*)value); + this->addAttribute(StdString("missing_value"), *value, &varname); + } + else CNetCdfInterface::defVarFill(grpid, varid, 1, NULL); + } + + ///--------------------------------------------------------------- + +} + + + +#endif diff --git a/src/parameters.cpp b/src/parameters.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3e52a5a7aae119a5c4860a5de74ed6891d9153a1 --- /dev/null +++ b/src/parameters.cpp @@ -0,0 +1,6 @@ +namespace xmlioserver +{ + + + +} diff --git a/src/parse_expr/expr_node.cpp b/src/parse_expr/expr_node.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90c0b58f5fb84e42edac6f2c58b984bf899d7561 --- /dev/null +++ b/src/parse_expr/expr_node.cpp @@ -0,0 +1,65 @@ +#include "expr_node.hpp" +#include "field.hpp" + +namespace xios +{ + + CScalarNode* CScalarNode::newNode(CSimpleNodeExpr* simpleNode) + { + if (simpleNode->nodeType==CSimpleNodeExpr::scalarDouble) return new CScalarDouble(simpleNode) ; + else if (simpleNode->nodeType==CSimpleNodeExpr::scalarVariable) return new CScalarVariable(simpleNode) ; + else if (simpleNode->nodeType==CSimpleNodeExpr::opScalar) return new COperatorScalarNode(simpleNode) ; + else if (simpleNode->nodeType==CSimpleNodeExpr::opScalarScalar) return new COperatorScalarScalarNode(simpleNode) ; + else + { + ERROR("CScalarNode* CScalarNode::allocateChild(CSimpleNodeExpr* simpleNode)",<<"Non coherent node") + return NULL; + } + }; + + + CFieldNode* CFieldNode::newNode(CSimpleNodeExpr* simpleNode) + { + if (simpleNode->nodeType==CSimpleNodeExpr::fieldInstant) return new CInstantFieldNode(simpleNode) ; + else if (simpleNode->nodeType==CSimpleNodeExpr::fieldAverage) return new CAverageFieldNode(simpleNode) ; + else if (simpleNode->nodeType==CSimpleNodeExpr::opFieldScalar) return new COperatorFieldScalarNode(simpleNode) ; + else if (simpleNode->nodeType==CSimpleNodeExpr::opScalarField) return new COperatorScalarFieldNode(simpleNode) ; + else if (simpleNode->nodeType==CSimpleNodeExpr::opFieldField) return new COperatorFieldFieldNode(simpleNode) ; + else if (simpleNode->nodeType==CSimpleNodeExpr::opField) return new COperatorFieldNode(simpleNode) ; + else + { + ERROR("CScalarNode* CScalarNode::allocateChild(CSimpleNodeExpr* simpleNode)",<<"Non coherent node") + return NULL; + } + }; + + void CInstantFieldNode::reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) + { + if (!reduced) + { + if (fieldId=="this") + { + field=thisField ; + array=thisField->getInstantData() ; + reduced=true ; + } + else + { + field=associatedInstantField[fieldId] ; + array=field->getInstantData() ; + reduced=true ; + } + } + } + + void CAverageFieldNode::reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) + { + if (!reduced) + { + field=associatedAverageField[fieldId] ; + array=field->getInstantData() ; + reduced=true ; + } + } + +} diff --git a/src/parse_expr/expr_node.hpp b/src/parse_expr/expr_node.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a6e5f2d8a1a1c234d60e28d5b91886641ac24dfb --- /dev/null +++ b/src/parse_expr/expr_node.hpp @@ -0,0 +1,440 @@ +#ifndef __XIOS_EXPR_NODE_HPP__ +#define __XIOS_EXPR_NODE_HPP__ + +#include "variable.hpp" +#include "simple_node_expr.hpp" +#include "operator_expr.hpp" +#include "lex_parser.hpp" + +namespace xios +{ + class CField ; +/////////////////////////////////////// +// class CNodeExpr // +/////////////////////////////////////// + + class CNodeExpr + { + public: + CNodeExpr(void) : reduced(false) {}; + + bool reduced ; + bool isReduced(void) { return reduced ; } + virtual ~CNodeExpr() {} + } ; + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////// +// class CScalarNode // +/////////////////////////////////////// + + class CScalarNode : public CNodeExpr + { + public: + CScalarNode(void) : CNodeExpr() {} + static CScalarNode* newNode(CSimpleNodeExpr* simpleNode) ; + virtual void reduce(void)=0 ; + + double val ; + virtual ~CScalarNode() {} + } ; + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////// +// class CScalarDouble // +/////////////////////////////////////// + + class CScalarDouble : public CScalarNode + { + public : + + CScalarDouble(CSimpleNodeExpr* simpleNode) : CScalarNode() + { + strVal=simpleNode->id ; + } + + virtual void reduce(void) + { + if (!reduced) + { + CType tval ; + tval.fromString(strVal) ; + val=tval ; + reduced=true ; + } + } + + virtual ~CScalarDouble() {} + string strVal ; + } ; + + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////// +// class CScalarVariable // +/////////////////////////////////////// + + + + class CScalarVariable : public CScalarNode + { + public : + CScalarVariable(CSimpleNodeExpr* simpleNode) : CScalarNode() + { + varId=simpleNode->id ; + } + + void reduce(void) + { + if (!reduced) + { + if (CVariable::has(varId)) + { + val=CVariable::get(varId)->getData() ; + reduced=true ; + } + else ERROR("void CScalarVariable::reduce(void)",<<" Variable "<id ; + child=newNode(simpleNode->children[0]) ; + } + + void reduce(void) + { + child->reduce() ; + op=operatorExpr.getOpScalar(opId) ; + if (child->isReduced()) + { + val=op(child->val) ; + reduced=true ; + } + } + + virtual ~COperatorScalarNode() { delete child; } + + CScalarNode* child ; + string opId ; + double (*op)(double) ; + } ; + +//////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////// +// class COperatorScalarScalarNode // +///////////////////////////////////////////// + + class COperatorScalarScalarNode : public CScalarNode + { + public : + COperatorScalarScalarNode(CSimpleNodeExpr* simpleNode) : CScalarNode() + { + opId=simpleNode->id ; + child1=newNode(simpleNode->children[0]) ; + child2=newNode(simpleNode->children[1]) ; + } + + void reduce(void) + { + child1->reduce() ; + child2->reduce() ; + op=operatorExpr.getOpScalarScalar(opId) ; + if (child1->isReduced() && child2->isReduced()) + { + op=operatorExpr.getOpScalarScalar(opId) ; + val=op(child1->val,child2->val) ; + reduced=true ; + } + } + + virtual ~COperatorScalarScalarNode() + { + delete child1 ; + delete child2 ; + } + + CScalarNode* child1 ; + CScalarNode* child2 ; + double (*op)(double,double) ; + string opId ; + } ; + + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////// +// class CFieldNode // +/////////////////////////////////////// + + + class CFieldNode : public CNodeExpr + { + public: + CFieldNode(void) : CNodeExpr() {} + static CFieldNode* newNode(CSimpleNodeExpr* simpleNode) ; + virtual void reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) =0 ; + virtual CArray compute(void)=0 ; + virtual void getFieldIds(set& fieldIds)=0 ; + virtual void getInstantFieldIds(set& fieldIds)=0 ; + virtual void getAverageFieldIds(set& fieldIds)=0 ; + virtual void getFields(set& fields)=0 ; + virtual void getInstantFields(set& fields)=0 ; + virtual void getAverageFields(set& fields)=0 ; + + virtual ~CFieldNode() {} + } ; + + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////// +// class CInstantFieldNode // +/////////////////////////////////////// + + class CInstantFieldNode : public CFieldNode + { + public: + CInstantFieldNode(CSimpleNodeExpr* simpleNode) : CFieldNode(), fieldId(simpleNode->id) {} + virtual void reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) ; + virtual CArray compute(void) { return CArray(*array);} + virtual ~CInstantFieldNode() { } + virtual void getFieldIds(set& fieldIds) { fieldIds.insert(fieldId) ;} + virtual void getInstantFieldIds(set& fieldIds) { fieldIds.insert(fieldId) ;} + virtual void getAverageFieldIds(set& fieldIds) { } + virtual void getFields(set& fields) { fields.insert(field) ;} + virtual void getInstantFields(set& fields) { fields.insert(field) ;} + virtual void getAverageFields(set& fields) { } + + string fieldId; + CField* field ; + CArray* array ; + }; + + + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////// +// class CAverageFieldNode // +/////////////////////////////////////// + + + class CAverageFieldNode : public CFieldNode + { + public: + + CAverageFieldNode(CSimpleNodeExpr* simpleNode) : CFieldNode(), fieldId(simpleNode->id) {} + + virtual void reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) ; + virtual CArray compute(void) { return CArray(*array); } + virtual void getFieldIds(set& fieldIds) { fieldIds.insert(fieldId) ;} + virtual void getInstantFieldIds(set& fieldIds) { } + virtual void getAverageFieldIds(set& fieldIds) { fieldIds.insert(fieldId) ;} + virtual void getFields(set& fields) { fields.insert(field) ;} + virtual void getInstantFields(set& fields) { } + virtual void getAverageFields(set& fields) { fields.insert(field) ;} + virtual ~CAverageFieldNode() {} + string fieldId; + CField* field ; + CArray* array ; + }; + + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////// +// class COperatorFieldNode // +/////////////////////////////////////// + + class COperatorFieldNode : public CFieldNode + { + public: + + COperatorFieldNode(CSimpleNodeExpr* simpleNode) : CFieldNode(), opId(simpleNode->id) + { + child=newNode(simpleNode->children[0]) ; + } + + virtual void reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) + { + child->reduce(thisField, associatedInstantField, associatedAverageField) ; + op=operatorExpr.getOpField(opId) ; + reduced=true ; + } + + virtual void getFieldIds(set& fieldIds) {child-> getFieldIds(fieldIds);} + virtual void getInstantFieldIds(set& fieldIds) {child-> getInstantFieldIds(fieldIds) ;} + virtual void getAverageFieldIds(set& fieldIds) {child-> getAverageFieldIds(fieldIds) ;} + virtual void getFields(set& fields) { child-> getFields(fields) ;} + virtual void getInstantFields(set& fields) {child-> getInstantFields(fields) ; } + virtual void getAverageFields(set& fields) {child-> getAverageFields(fields) ; } + virtual CArray compute(void) + { + return op(child->compute()) ; + } + virtual ~COperatorFieldNode() { delete child; } + + CFieldNode* child ; + string opId ; + CArray (*op)( const CArray&) ; + }; + + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////// +// COperatorFieldFieldNode // +/////////////////////////////////////// + + + class COperatorFieldFieldNode : public CFieldNode + { + public: + + COperatorFieldFieldNode(CSimpleNodeExpr* simpleNode) : CFieldNode(),opId(simpleNode->id) + { + child1=newNode(simpleNode->children[0]) ; + child2=newNode(simpleNode->children[1]) ; + } + + virtual void reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) + { + child1->reduce(thisField, associatedInstantField, associatedAverageField) ; + child2->reduce(thisField, associatedInstantField, associatedAverageField) ; + op=operatorExpr.getOpFieldField(opId) ; + reduced=true ; + } + + virtual void getFieldIds(set& fieldIds) {child1-> getFieldIds(fieldIds); child2-> getFieldIds(fieldIds);} + virtual void getInstantFieldIds(set& fieldIds) {child1-> getInstantFieldIds(fieldIds); child2-> getInstantFieldIds(fieldIds);} + virtual void getAverageFieldIds(set& fieldIds) {child1-> getAverageFieldIds(fieldIds); child2-> getAverageFieldIds(fieldIds);} + virtual void getFields(set& fields) {child1-> getFields(fields); child2-> getFields(fields);} + virtual void getInstantFields(set& fields) {child1-> getInstantFields(fields); child2-> getInstantFields(fields);} + virtual void getAverageFields(set& fields) {child1-> getAverageFields(fields); child2-> getAverageFields(fields);} + + virtual CArray compute(void) + { + return op(child1->compute(),child2->compute()) ; + } + + virtual ~COperatorFieldFieldNode() { delete child1; delete child2 ; } + + CFieldNode* child1 ; + CFieldNode* child2 ; + string opId ; + CArray (*op)( const CArray&,const CArray&) ; + }; + + +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////// +// class COperatorScalarFieldNode // +//////////////////////////////////////////// + + class COperatorScalarFieldNode : public CFieldNode + { + public: + + COperatorScalarFieldNode(CSimpleNodeExpr* simpleNode) : CFieldNode(), opId(simpleNode->id) + { + child1=CScalarNode::newNode(simpleNode->children[0]) ; + child2=newNode(simpleNode->children[1]) ; + } + + virtual void reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) + { + child1->reduce() ; + child2->reduce(thisField, associatedInstantField, associatedAverageField) ; + op=operatorExpr.getOpScalarField(opId) ; + reduced=true ; + } + + virtual void getFieldIds(set& fieldIds) {child2-> getFieldIds(fieldIds);} + virtual void getInstantFieldIds(set& fieldIds) {child2-> getInstantFieldIds(fieldIds);} + virtual void getAverageFieldIds(set& fieldIds) {child2-> getAverageFieldIds(fieldIds);} + virtual void getFields(set& fields) {child2-> getFields(fields);} + virtual void getInstantFields(set& fields) {child2-> getInstantFields(fields);} + virtual void getAverageFields(set& fields) {child2-> getAverageFields(fields);} + + virtual CArray compute(void) + { + return op(child1->val,child2->compute()) ; + } + + ~COperatorScalarFieldNode() { delete child1 ; delete child2 ; } + + CScalarNode* child1 ; + CFieldNode* child2 ; + string opId ; + CArray (*op)(double,const CArray&) ; + }; + + +//////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////// +// class COperatorFieldScalarNode // +/////////////////////////////////////////// + + class COperatorFieldScalarNode : public CFieldNode + { + public: + + COperatorFieldScalarNode(CSimpleNodeExpr* simpleNode) : CFieldNode(), opId(simpleNode->id) + { + child1=newNode(simpleNode->children[0]) ; + child2=CScalarNode::newNode(simpleNode->children[1]) ; + } + + virtual void reduce(CField* thisField, map& associatedInstantField, map& associatedAverageField) + { + child1->reduce(thisField, associatedInstantField, associatedAverageField) ; + child2->reduce() ; + op=operatorExpr.getOpFieldScalar(opId) ; + reduced=true ; + } + + virtual CArray compute(void) + { + return op(child1->compute(),child2->val) ; + } + + virtual void getFieldIds(set& fieldIds) {child1-> getFieldIds(fieldIds);} + virtual void getInstantFieldIds(set& fieldIds) {child1-> getInstantFieldIds(fieldIds);} + virtual void getAverageFieldIds(set& fieldIds) {child1-> getAverageFieldIds(fieldIds);} + virtual void getFields(set& fields) {child1-> getFields(fields);} + virtual void getInstantFields(set& fields) {child1-> getInstantFields(fields);} + virtual void getAverageFields(set& fields) {child1-> getAverageFields(fields);} + + ~COperatorFieldScalarNode() {delete child1, delete child2; } + + CFieldNode* child1 ; + CScalarNode* child2 ; + string opId ; + CArray (*op)( const CArray&, double) ; + }; + +} + +#endif diff --git a/src/parse_expr/generate_lex_yacc.sh b/src/parse_expr/generate_lex_yacc.sh new file mode 100755 index 0000000000000000000000000000000000000000..e3f04db65599d7517356bebc4106d02c3138b066 --- /dev/null +++ b/src/parse_expr/generate_lex_yacc.sh @@ -0,0 +1,2 @@ +bison -d yacc_parser.yacc -o yacc_parser.cpp +flex -o lex_parser.cpp -f lex_parser.lex diff --git a/src/parse_expr/lex_parser.cpp b/src/parse_expr/lex_parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65fa9222d2a8e357c97f04cfb6ad3924d49a2347 --- /dev/null +++ b/src/parse_expr/lex_parser.cpp @@ -0,0 +1,2257 @@ +#line 2 "lex_parser.cpp" + +#line 4 "lex_parser.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext +static yyconst flex_int16_t yy_nxt[][128] = + { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + + { + 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 5, 4, 4, 4, 6, 4, 4, 4, + 7, 8, 9, 10, 4, 11, 4, 12, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 4, 4, + 4, 4, 4, 4, 14, 15, 15, 15, 15, 15, + + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 4, 4, 4, 16, 4, 4, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 4, 4, 4, 4, 4 + }, + + { + 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 5, 4, 4, 4, 6, 4, 4, 4, + + 7, 8, 9, 10, 4, 11, 4, 12, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 4, 4, + 4, 4, 4, 4, 14, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 4, 4, 4, 16, 4, 4, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 4, 4, 4, 4, 4 + }, + + { + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3 + }, + + { + 3, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -4, -4, -4, -4, -4, -4, -4 + }, + + { + 3, -5, -5, -5, -5, -5, -5, -5, -5, 18, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, 18, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, + -5, -5, -5, -5, -5, -5, -5, -5 + }, + + { + 3, -6, -6, -6, -6, -6, -6, -6, -6, -6, + -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, + + -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, + -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, + -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, + -6, -6, -6, -6, -6, -6, -6, -6, -6, -6, + -6, -6, -6, -6, -6, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, -6, -6, -6, -6, -6, -6, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + + 19, 19, 19, -6, -6, -6, -6, -6 + }, + + { + 3, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7 + }, + + { + 3, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8 + }, + + { + 3, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9 + + }, + + { + 3, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10 + }, + + { + 3, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11 + }, + + { + 3, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12 + }, + + { + 3, -13, -13, -13, -13, -13, -13, -13, -13, -13, + + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, 20, -13, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, 22, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, 22, -13, -13, -13, -13, -13, -13, -13, -13, + + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13 + }, + + { + 3, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, -14, -14, -14, -14, -14, -14, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, -14, -14, -14, -14, -14 + }, + + { + 3, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, 24, 24, + + 24, 24, 24, 24, 24, 24, 24, 24, -15, -15, + -15, -15, -15, -15, -15, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, -15, -15, -15, -15, 24, -15, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, -15, -15, -15, -15, -15 + }, + + { + 3, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + + -16, -16, -16, -16, -16, -16, -16, -16 + }, + + { + 3, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17 + }, + + { + 3, -18, -18, -18, -18, -18, -18, -18, -18, 18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, 18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18 + }, + + { + 3, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, -19, -19, + -19, -19, -19, -19, -19, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, -19, -19, -19, -19, 25, -19, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, -19, -19, -19, -19, -19 + + }, + + { + 3, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20 + }, + + { + 3, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, 20, -21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, 22, + + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, 22, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21 + }, + + { + 3, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + + -22, -22, -22, 27, -22, 27, -22, -22, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22 + }, + + { + 3, -23, -23, -23, -23, -23, -23, -23, -23, -23, + + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, -23, -23, + -23, -23, -23, -23, -23, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, -23, -23, -23, -23, 29, -23, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, -23, -23, -23, -23, -23 + }, + + { + 3, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, -24, -24, -24, -24, -24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, -24, -24, + -24, -24, -24, -24, -24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, -24, -24, -24, -24, 24, -24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, -24, -24, -24, -24, -24 + }, + + { + 3, -25, -25, -25, -25, -25, -25, -25, -25, -25, + -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, + -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, + -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, + -25, -25, -25, -25, -25, -25, -25, -25, 25, 25, + + 25, 25, 25, 25, 25, 25, 25, 25, -25, -25, + -25, -25, -25, -25, -25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, -25, -25, -25, -25, 25, -25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, -25, -25, -25, -25, -25 + }, + + { + 3, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, 22, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, 22, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + + -26, -26, -26, -26, -26, -26, -26, -26 + }, + + { + 3, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27 + }, + + { + 3, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, -28, -28, + + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28 + }, + + { + 3, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, -29, -29, + -29, -29, -29, -29, -29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, -29, -29, -29, -29, 29, -29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, -29, -29, -29, -29, -29 + + }, + + } ; + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 14 +#define YY_END_OF_BUFFER 15 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[30] = + { 0, + 0, 0, 15, 14, 1, 14, 11, 12, 8, 6, + 7, 9, 2, 14, 5, 10, 13, 1, 4, 0, + 2, 0, 3, 5, 4, 2, 0, 2, 3 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +static yyconst yy_state_type yy_NUL_trans[30] = + { 0, + 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0 + } ; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "lex_parser.lex" +#line 3 "lex_parser.lex" + +extern "C" +{ + int yylex(void); +} +#undef YY_INPUT +#define YY_INPUT(b,r,s) readInputForLexer(b,&r,s) +#include + +int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ) ; + + +#include "simple_node_expr.hpp" +#include "yacc_parser.hpp" + +#line 941 "lex_parser.cpp" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +int yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + errno=0; \ + while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 29 "lex_parser.lex" + + +#line 1110 "lex_parser.cpp" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + while ( (yy_current_state = yy_nxt[yy_current_state][ YY_SC_TO_UI(*yy_cp) ]) > 0 ) + { + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + + ++yy_cp; + } + + yy_current_state = -yy_current_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos) + 1; + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 31 "lex_parser.lex" +{ /* We ignore white characters */ } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 33 "lex_parser.lex" +{ + yylval.str=new std::string(yytext); + return NUMBER ; + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 38 "lex_parser.lex" +{ + yylval.str=new std::string(yytext+1) ; + return AVERAGE ; + } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 43 "lex_parser.lex" +{ + yylval.str=new std::string(yytext+1) ; + return VAR ; + } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 48 "lex_parser.lex" +{ + yylval.str=new std::string(yytext) ; + return ID ; + } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 54 "lex_parser.lex" +return(PLUS); + YY_BREAK +case 7: +YY_RULE_SETUP +#line 55 "lex_parser.lex" +return(MINUS); + YY_BREAK +case 8: +YY_RULE_SETUP +#line 57 "lex_parser.lex" +return(TIMES); + YY_BREAK +case 9: +YY_RULE_SETUP +#line 58 "lex_parser.lex" +return(DIVIDE); + YY_BREAK +case 10: +YY_RULE_SETUP +#line 60 "lex_parser.lex" +return(POWER); + YY_BREAK +case 11: +YY_RULE_SETUP +#line 62 "lex_parser.lex" +return(LEFT_PARENTHESIS); + YY_BREAK +case 12: +YY_RULE_SETUP +#line 63 "lex_parser.lex" +return(RIGHT_PARENTHESIS); + YY_BREAK +case 13: +YY_RULE_SETUP +#line 65 "lex_parser.lex" +{ + return(END); + } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 68 "lex_parser.lex" +ECHO; + YY_BREAK +#line 1265 "lex_parser.cpp" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + if ( *yy_cp ) + { + yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]; + } + else + yy_current_state = yy_NUL_trans[yy_current_state]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + yy_current_state = yy_NUL_trans[yy_current_state]; + yy_is_jam = (yy_current_state == 0); + + if ( ! yy_is_jam ) + { + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + } + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 68 "lex_parser.lex" diff --git a/src/parse_expr/lex_parser.hpp b/src/parse_expr/lex_parser.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a6cb25bb797837bc2a794e63c986581f2f32a60b --- /dev/null +++ b/src/parse_expr/lex_parser.hpp @@ -0,0 +1,10 @@ +#ifndef __XIOS_LEX_PARSER_HPP__ +#define __XIOS_LEX_PARSER_HPP__ + +#include +namespace xios +{ + CSimpleNodeExpr* parseExpr(const std::string& strExpr) ; +} + +#endif diff --git a/src/parse_expr/lex_parser.lex b/src/parse_expr/lex_parser.lex new file mode 100644 index 0000000000000000000000000000000000000000..0a5278d87dee699d957cb602bab283d096f91e2f --- /dev/null +++ b/src/parse_expr/lex_parser.lex @@ -0,0 +1,67 @@ +%option noyywrap +%{ + +extern "C" +{ + int yylex(void); +} +#undef YY_INPUT +#define YY_INPUT(b,r,s) readInputForLexer(b,&r,s) +#include + +int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ) ; + + +#include "simple_node_expr.hpp" +#include "yacc_parser.hpp" + +%} + +white [ \t]+ + +digit [0-9] +integer {digit}+ +exponant [eE][+-]?{integer} +real {integer}("."{integer})?{exponant}? +id [a-zA-Z][a-zA-Z0-9_]* +average @{id} +var \${id} +%% + +{white} { /* We ignore white characters */ } + +{real} { + yylval.str=new std::string(yytext); + return NUMBER ; + } + +{average} { + yylval.str=new std::string(yytext+1) ; + return AVERAGE ; + } + +{var} { + yylval.str=new std::string(yytext+1) ; + return VAR ; + } + +{id} { + yylval.str=new std::string(yytext) ; + return ID ; + } + + +"+" return(PLUS); +"-" return(MINUS); + +"*" return(TIMES); +"/" return(DIVIDE); + +"^" return(POWER); + +"(" return(LEFT_PARENTHESIS); +")" return(RIGHT_PARENTHESIS); + +"\0" { + return(END); + } diff --git a/src/parse_expr/operator_expr.cpp b/src/parse_expr/operator_expr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eacca556043c54022d4033a0d8aad4d3d6d4a532 --- /dev/null +++ b/src/parse_expr/operator_expr.cpp @@ -0,0 +1,6 @@ +#include "operator_expr.hpp" + +namespace xios +{ + COperatorExpr operatorExpr ; +} diff --git a/src/parse_expr/operator_expr.hpp b/src/parse_expr/operator_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a8bd933a93e71229c4bd797f7bccbbc30e7b4cfa --- /dev/null +++ b/src/parse_expr/operator_expr.hpp @@ -0,0 +1,172 @@ +#ifndef __XIOS_OPERATOR_EXPR_HPP__ +#define __XIOS_OPERATOR_EXPR_HPP__ + +#include +#include +#include +#include "exception.hpp" +#include "array_new.hpp" + +using namespace std ; + +namespace xios +{ + class COperatorExpr + { + public: + typedef double (*functionScalar)(double) ; + typedef double (*functionScalarScalar)(double, double) ; + typedef CArray (*functionField)(const CArray&) ; + typedef CArray (*functionFieldField)(const CArray&, const CArray&) ; + typedef CArray (*functionFieldScalar)(const CArray&, double) ; + typedef CArray (*functionScalarField)(double, const CArray&) ; + + COperatorExpr(void) + { + opScalar[string("neg")]=neg_s ; + opScalar[string("cos")]=cos_s ; + opScalar[string("sin")]=sin_s ; + opScalar[string("tan")]=tan_s ; + opScalar[string("exp")]=exp_s ; + opScalar[string("log")]=log_s ; + opScalar[string("log10")]=log10_s ; + opScalar[string("sqrt")]=sqrt_s ; + + opScalarScalar[string("add")]=add_ss ; + opScalarScalar[string("minus")]=minus_ss ; + opScalarScalar[string("mult")]=mult_ss ; + opScalarScalar[string("div")]=div_ss ; + opScalarScalar[string("pow")]=pow_ss ; + + opField[string("neg")]=neg_f ; + opField[string("cos")]=cos_f ; + opField[string("sin")]=sin_f ; + opField[string("tan")]=tan_f ; + opField[string("exp")]=exp_f ; + opField[string("log")]=log_f ; + opField[string("log10")]=log10_f ; + opField[string("sqrt")]=sqrt_f ; + + opFieldField[string("add")]=add_ff ; + opFieldField[string("minus")]=minus_ff ; + opFieldField[string("mult")]=mult_ff ; + opFieldField[string("div")]=div_ff ; + opFieldField[string("pow")]=pow_ff ; + + opFieldScalar[string("add")]=add_fs ; + opFieldScalar[string("minus")]=minus_fs ; + opFieldScalar[string("mult")]=mult_fs ; + opFieldScalar[string("div")]=div_fs ; + opFieldScalar[string("pow")]=pow_fs ; + + opScalarField[string("add")]=add_sf ; + opScalarField[string("minus")]=minus_sf ; + opScalarField[string("mult")]=mult_sf ; + opScalarField[string("div")]=div_sf ; + } + + functionScalar getOpScalar(const string& id) + { + map::iterator it ; + it=opScalar.find(id) ; + if (it==opScalar.end()) ERROR("double (*)(double) COperatorExpr::getOpScalar(const string& id)",<<"unknown operator : "<second ; + } + + functionScalarScalar getOpScalarScalar(const string& id) + { + map::iterator it ; + it=opScalarScalar.find(id) ; + if (it==opScalarScalar.end()) ERROR("double (*)(double) COperatorExpr::getOpScalarScalar(const string& id)",<<"unknown operator : "<second ; + } + + functionField getOpField(const string& id) + { + map::iterator it ; + it=opField.find(id) ; + if (it==opField.end()) ERROR("functionField COperatorExpr::getOpField(const string& id)",<<"unknown operator : "<second ; + } + + functionFieldField getOpFieldField(const string& id) + { + map::iterator it ; + it=opFieldField.find(id) ; + if (it==opFieldField.end()) ERROR("dfunctionFieldField COperatorExpr::getOpFieldField(const string& id)",<<"unknown operator : "<second ; + } + + functionFieldScalar getOpFieldScalar(const string& id) + { + map::iterator it ; + it=opFieldScalar.find(id) ; + if (it==opFieldScalar.end()) ERROR("functionFieldScalar COperatorExpr::getOpFieldScalar(const string& id)",<<"unknown operator : "<second ; + } + + functionScalarField getOpScalarField(const string& id) + { + map::iterator it ; + it=opScalarField.find(id) ; + if (it==opScalarField.end()) ERROR("functionScalarField COperatorExpr::getOpFieldField(const string& id)",<<"unknown operator : "<second ; + } + + map opScalar ; + map opScalarScalar ; + map opField ; + map opFieldField ; + map opFieldScalar ; + map opScalarField ; + + static inline double neg_s(double x) {return -x;} + static inline double cos_s(double x) {return std::cos(x);} + static inline double sin_s(double x) {return std::sin(x);} + static inline double tan_s(double x) {return std::tan(x);} + static inline double exp_s(double x) {return std::exp(x);} + static inline double log_s(double x) {return std::log(x);} + static inline double log10_s(double x) {return std::log10(x);} + static inline double sqrt_s(double x) {return std::sqrt(x);} + + static inline double add_ss(double x, double y) {return x+y;} + static inline double minus_ss(double x, double y) {return x-y;} + static inline double mult_ss(double x, double y) {return x*y;} + static inline double div_ss(double x, double y) {return x/y;} + static inline double pow_ss(double x, double y) {return std::pow(x,y);} + + static inline CArray neg_f(const CArray& x) {return Array(-x);} + static inline CArray cos_f(const CArray& x) {return Array(cos(x));} + static inline CArray sin_f(const CArray& x) {return Array(sin(x));} + static inline CArray tan_f(const CArray& x) {return Array(tan(x));} + static inline CArray exp_f(const CArray& x) {return Array(exp(x));} + static inline CArray log_f(const CArray& x) {return Array(log(x));} + static inline CArray log10_f(const CArray& x) {return Array(log10(x));} + static inline CArray sqrt_f(const CArray& x) {return Array(sqrt(x));} + + static inline CArray add_ff(const CArray& x, const CArray& y) {return Array(x+y);} + static inline CArray minus_ff(const CArray& x, const CArray& y) {return Array(x-y);} + static inline CArray mult_ff(const CArray& x, const CArray& y) {return Array(x*y);} + static inline CArray div_ff(const CArray& x, const CArray& y) {return Array(x/y);} + static inline CArray pow_ff(const CArray& x, const CArray& y) {return Array(pow(x,y));} + + static inline CArray add_fs(const CArray& x, double y) {return Array(x+y);} + static inline CArray minus_fs(const CArray& x, double y) {return Array(x-y);} + static inline CArray mult_fs(const CArray& x, double y) {return Array(x*y);} + static inline CArray div_fs(const CArray& x, double y) {return Array(x/y);} + static inline CArray pow_fs(const CArray& x, double y) {return Array(pow(x,y));} + + static inline CArray add_sf(double x, const CArray& y) {return Array(x+y);} + static inline CArray minus_sf(double x, const CArray& y) {return Array(x-y);} + static inline CArray mult_sf(double x, const CArray& y) {return Array(x*y);} + static inline CArray div_sf(double x, const CArray& y) {return Array(x/y);} + + + } ; + + extern COperatorExpr operatorExpr ; + +} + +#endif + diff --git a/src/parse_expr/simple_node_expr.hpp b/src/parse_expr/simple_node_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..863539879c65a3a0617e46849ded08ee8a8da855 --- /dev/null +++ b/src/parse_expr/simple_node_expr.hpp @@ -0,0 +1,52 @@ +#ifndef __XIOS_SIMPLE_NODE_EXPR_HPP__ +#define __XIOS_SIMPLE_NODE_EXPR_HPP__ + +#include +#include + +class CSimpleNodeExpr +{ + public : + + enum ENodeType + { + scalarDouble, scalarVariable, opScalar, opScalarScalar, + fieldInstant, fieldAverage, opFieldScalar, opScalarField, opFieldField, opField + } ; + + CSimpleNodeExpr(ENodeType nodeType, const std::string* str) : nodeType(nodeType) + { + id=*str ; + } + + CSimpleNodeExpr(ENodeType nodeType, const char* str) : nodeType(nodeType) + { + id=std::string(str) ; + } + + void addChild(CSimpleNodeExpr* child) + { + children.push_back(child) ; + } + + std::string print(void) + { + if (nodeType==scalarDouble) return id ; + else if (nodeType==scalarVariable) return "$"+id ; + else if (nodeType==fieldInstant) return id ; + else if (nodeType==fieldAverage) return "@"+id ; + else if (nodeType==opScalar || nodeType==opField) return id+"("+children[0]->print()+")" ; + else return "("+children[0]->print()+id+children[1]->print()+")" ; + } + ~CSimpleNodeExpr() + { + for(std::vector::iterator it=children.begin();it!=children.end();++it) delete *it ; + } + + ENodeType nodeType ; + std::string id ; + + std::vector children ; +} ; + +#endif diff --git a/src/parse_expr/yacc_parser.cpp b/src/parse_expr/yacc_parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a4310e8dbdf3adb8644b067874a938b3a8f5b3d --- /dev/null +++ b/src/parse_expr/yacc_parser.cpp @@ -0,0 +1,1878 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "yacc_parser.yacc" + +#include "simple_node_expr.hpp" +#include +#include +#include "exception.hpp" + +using namespace std ; +using namespace xios ; + +extern "C" +{ + int yyparse(void); + int yylex(void); + int yyerror(const char *s) ; +} + + CSimpleNodeExpr* parsed ; + std::string globalInputText; + int globalReadOffset=0; + + int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ) + { + int numBytesToRead = maxBytesToRead; + int bytesRemaining = globalInputText.length()-globalReadOffset; + int i; + if ( numBytesToRead > bytesRemaining ) numBytesToRead = bytesRemaining; + for ( i = 0; i < numBytesToRead; i++ ) buffer[i] = globalInputText.c_str()[globalReadOffset+i]; + *numBytesRead = numBytesToRead; + globalReadOffset += numBytesToRead; + return 0; + } + + + +/* Line 189 of yacc.c */ +#line 108 "yacc_parser.cpp" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + NUMBER = 258, + VAR = 259, + ID = 260, + AVERAGE = 261, + PLUS = 262, + MINUS = 263, + TIMES = 264, + DIVIDE = 265, + POWER = 266, + LEFT_PARENTHESIS = 267, + RIGHT_PARENTHESIS = 268, + END = 269, + NEG = 270 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 214 of yacc.c */ +#line 36 "yacc_parser.yacc" + + std::string* str ; /* symbol table index */ + CSimpleNodeExpr* node ; + + + +/* Line 214 of yacc.c */ +#line 166 "yacc_parser.cpp" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 178 "yacc_parser.cpp" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 16 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 134 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 16 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 4 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 32 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 68 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 270 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 8, 10, 12, 16, 20, 24, + 28, 31, 35, 39, 44, 46, 48, 52, 56, 60, + 64, 67, 71, 75, 79, 83, 87, 91, 95, 99, + 103, 107, 111 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 17, 0, -1, 14, -1, 19, 14, -1, 3, -1, + 4, -1, 18, 7, 18, -1, 18, 8, 18, -1, + 18, 9, 18, -1, 18, 10, 18, -1, 8, 18, + -1, 18, 11, 18, -1, 12, 18, 13, -1, 5, + 12, 18, 13, -1, 5, -1, 6, -1, 19, 7, + 19, -1, 19, 8, 19, -1, 19, 9, 19, -1, + 19, 10, 19, -1, 8, 19, -1, 19, 11, 19, + -1, 12, 19, 13, -1, 19, 7, 18, -1, 18, + 7, 19, -1, 19, 8, 18, -1, 18, 8, 19, + -1, 19, 9, 18, -1, 18, 9, 19, -1, 19, + 10, 18, -1, 18, 10, 19, -1, 19, 11, 18, + -1, 5, 12, 19, 13, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 58, 58, 59, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "NUMBER", "VAR", "ID", "AVERAGE", "PLUS", + "MINUS", "TIMES", "DIVIDE", "POWER", "LEFT_PARENTHESIS", + "RIGHT_PARENTHESIS", "END", "NEG", "$accept", "Line", "Expression", + "Field_expr", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 16, 17, 17, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 2, 1, 1, 3, 3, 3, 3, + 2, 3, 3, 4, 1, 1, 3, 3, 3, 3, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 4 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 4, 5, 14, 15, 0, 0, 2, 0, 0, + 0, 0, 10, 20, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 12, 22, 6, 24, 7, 26, 8, 28, 9, 30, + 0, 0, 0, 11, 23, 16, 25, 17, 27, 18, + 29, 19, 31, 21, 13, 32, 0, 10, 0, 0, + 0, 0, 0, 0, 6, 7, 8, 9 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 8, 9, 10 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -6 +static const yytype_int8 yypact[] = +{ + 55, -6, -6, -4, -6, -1, -1, -6, 9, 123, + 73, -1, 14, 20, 81, 88, -6, -1, -1, -1, + -1, 67, -1, -1, -1, -1, -1, -6, 95, 102, + -6, -6, 13, 19, 13, 19, 14, 20, 14, 20, + -2, 67, 67, 14, 13, 19, 13, 19, 14, 20, + 14, 20, 14, 20, -6, -6, 67, 14, 109, 67, + 67, 67, 67, 116, 24, 24, 14, 14 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -6, -6, -5, 21 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 12, 14, 1, 2, 3, 4, 28, 5, 11, 16, + 56, 6, 32, 34, 36, 38, 43, 44, 46, 48, + 50, 52, 19, 20, 21, 21, 13, 15, 24, 25, + 26, 26, 29, 61, 62, 21, 57, 58, 33, 35, + 37, 39, 0, 45, 47, 49, 51, 53, 0, 0, + 0, 63, 0, 0, 64, 65, 66, 67, 1, 2, + 3, 4, 0, 5, 0, 0, 0, 6, 0, 7, + 1, 2, 40, 0, 0, 41, 0, 0, 0, 42, + 22, 23, 24, 25, 26, 0, 0, 27, 17, 18, + 19, 20, 21, 0, 30, 22, 23, 24, 25, 26, + 0, 31, 17, 18, 19, 20, 21, 0, 54, 22, + 23, 24, 25, 26, 0, 55, 59, 60, 61, 62, + 21, 0, 30, 59, 60, 61, 62, 21, 0, 54, + 17, 18, 19, 20, 21 +}; + +static const yytype_int8 yycheck[] = +{ + 5, 6, 3, 4, 5, 6, 11, 8, 12, 0, + 12, 12, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 9, 10, 11, 11, 5, 6, 9, 10, + 11, 11, 11, 9, 10, 11, 41, 42, 17, 18, + 19, 20, -1, 22, 23, 24, 25, 26, -1, -1, + -1, 56, -1, -1, 59, 60, 61, 62, 3, 4, + 5, 6, -1, 8, -1, -1, -1, 12, -1, 14, + 3, 4, 5, -1, -1, 8, -1, -1, -1, 12, + 7, 8, 9, 10, 11, -1, -1, 14, 7, 8, + 9, 10, 11, -1, 13, 7, 8, 9, 10, 11, + -1, 13, 7, 8, 9, 10, 11, -1, 13, 7, + 8, 9, 10, 11, -1, 13, 7, 8, 9, 10, + 11, -1, 13, 7, 8, 9, 10, 11, -1, 13, + 7, 8, 9, 10, 11 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 4, 5, 6, 8, 12, 14, 17, 18, + 19, 12, 18, 19, 18, 19, 0, 7, 8, 9, + 10, 11, 7, 8, 9, 10, 11, 14, 18, 19, + 13, 13, 18, 19, 18, 19, 18, 19, 18, 19, + 5, 8, 12, 18, 18, 19, 18, 19, 18, 19, + 18, 19, 18, 19, 13, 13, 12, 18, 18, 7, + 8, 9, 10, 18, 18, 18, 18, 18 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: + +/* Line 1455 of yacc.c */ +#line 58 "yacc_parser.yacc" + { ;} + break; + + case 3: + +/* Line 1455 of yacc.c */ +#line 59 "yacc_parser.yacc" + { parsed=(yyvsp[(1) - (2)].node) ;;} + break; + + case 4: + +/* Line 1455 of yacc.c */ +#line 63 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::scalarDouble,(yyvsp[(1) - (1)].str)); delete (yyvsp[(1) - (1)].str) ;} + break; + + case 5: + +/* Line 1455 of yacc.c */ +#line 64 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::scalarVariable,(yyvsp[(1) - (1)].str)) ; delete (yyvsp[(1) - (1)].str);} + break; + + case 6: + +/* Line 1455 of yacc.c */ +#line 65 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"add") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 7: + +/* Line 1455 of yacc.c */ +#line 66 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"minus") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 8: + +/* Line 1455 of yacc.c */ +#line 67 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"mult") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 9: + +/* Line 1455 of yacc.c */ +#line 68 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"div") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 10: + +/* Line 1455 of yacc.c */ +#line 69 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalar,"neg") ; (yyval.node)->addChild((yyvsp[(2) - (2)].node)); ;} + break; + + case 11: + +/* Line 1455 of yacc.c */ +#line 70 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"pow") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 12: + +/* Line 1455 of yacc.c */ +#line 71 "yacc_parser.yacc" + { (yyval.node)=(yyvsp[(2) - (3)].node) ; ;} + break; + + case 13: + +/* Line 1455 of yacc.c */ +#line 72 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalar,(yyvsp[(1) - (4)].str)) ; (yyval.node)->addChild((yyvsp[(3) - (4)].node)) ; delete (yyvsp[(1) - (4)].str) ;} + break; + + case 14: + +/* Line 1455 of yacc.c */ +#line 76 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::fieldInstant,(yyvsp[(1) - (1)].str)); delete (yyvsp[(1) - (1)].str);} + break; + + case 15: + +/* Line 1455 of yacc.c */ +#line 77 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::fieldAverage,(yyvsp[(1) - (1)].str)); delete (yyvsp[(1) - (1)].str);} + break; + + case 16: + +/* Line 1455 of yacc.c */ +#line 78 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"add") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 17: + +/* Line 1455 of yacc.c */ +#line 79 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"minus") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 18: + +/* Line 1455 of yacc.c */ +#line 80 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"mult") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 19: + +/* Line 1455 of yacc.c */ +#line 81 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"div") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 20: + +/* Line 1455 of yacc.c */ +#line 82 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opField,"neg") ; (yyval.node)->addChild((yyvsp[(2) - (2)].node));;} + break; + + case 21: + +/* Line 1455 of yacc.c */ +#line 83 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"pow") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 22: + +/* Line 1455 of yacc.c */ +#line 84 "yacc_parser.yacc" + { (yyval.node)=(yyvsp[(2) - (3)].node) ;;} + break; + + case 23: + +/* Line 1455 of yacc.c */ +#line 85 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"add") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 24: + +/* Line 1455 of yacc.c */ +#line 86 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarField,"add") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 25: + +/* Line 1455 of yacc.c */ +#line 87 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"minus") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 26: + +/* Line 1455 of yacc.c */ +#line 88 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarField,"minus") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 27: + +/* Line 1455 of yacc.c */ +#line 89 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"mult") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 28: + +/* Line 1455 of yacc.c */ +#line 90 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarField,"mult") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 29: + +/* Line 1455 of yacc.c */ +#line 91 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"div") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 30: + +/* Line 1455 of yacc.c */ +#line 92 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarField,"div") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 31: + +/* Line 1455 of yacc.c */ +#line 93 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"pow") ; (yyval.node)->addChild((yyvsp[(1) - (3)].node)) ; (yyval.node)->addChild((yyvsp[(3) - (3)].node)); ;} + break; + + case 32: + +/* Line 1455 of yacc.c */ +#line 94 "yacc_parser.yacc" + { (yyval.node)=new CSimpleNodeExpr(CSimpleNodeExpr::opField,(yyvsp[(1) - (4)].str)) ; (yyval.node)->addChild((yyvsp[(3) - (4)].node)) ; delete (yyvsp[(1) - (4)].str);} + break; + + + +/* Line 1455 of yacc.c */ +#line 1644 "yacc_parser.cpp" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1675 of yacc.c */ +#line 96 "yacc_parser.yacc" + + +extern "C" +{ + int yyerror(const char *s) + { + ERROR("int yyerror(const char *s)", <<"Parsing error :"<. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + NUMBER = 258, + VAR = 259, + ID = 260, + AVERAGE = 261, + PLUS = 262, + MINUS = 263, + TIMES = 264, + DIVIDE = 265, + POWER = 266, + LEFT_PARENTHESIS = 267, + RIGHT_PARENTHESIS = 268, + END = 269, + NEG = 270 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 1676 of yacc.c */ +#line 36 "yacc_parser.yacc" + + std::string* str ; /* symbol table index */ + CSimpleNodeExpr* node ; + + + +/* Line 1676 of yacc.c */ +#line 74 "yacc_parser.hpp" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + +extern YYSTYPE yylval; + + diff --git a/src/parse_expr/yacc_parser.yacc b/src/parse_expr/yacc_parser.yacc new file mode 100644 index 0000000000000000000000000000000000000000..c485daec80ce7518ffb3dc72912315e5c960cc78 --- /dev/null +++ b/src/parse_expr/yacc_parser.yacc @@ -0,0 +1,117 @@ +%{ +#include "simple_node_expr.hpp" +#include +#include +#include "exception.hpp" + +using namespace std ; +using namespace xios ; + +extern "C" +{ + int yyparse(void); + int yylex(void); + int yyerror(const char *s) ; +} + + CSimpleNodeExpr* parsed ; + std::string globalInputText; + int globalReadOffset=0; + + int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ) + { + int numBytesToRead = maxBytesToRead; + int bytesRemaining = globalInputText.length()-globalReadOffset; + int i; + if ( numBytesToRead > bytesRemaining ) numBytesToRead = bytesRemaining; + for ( i = 0; i < numBytesToRead; i++ ) buffer[i] = globalInputText.c_str()[globalReadOffset+i]; + *numBytesRead = numBytesToRead; + globalReadOffset += numBytesToRead; + return 0; + } + +%} + +%union +{ + std::string* str ; /* symbol table index */ + CSimpleNodeExpr* node ; +}; + +%token NUMBER +%token VAR ID AVERAGE +%token PLUS MINUS TIMES DIVIDE POWER +%token LEFT_PARENTHESIS RIGHT_PARENTHESIS +%token END + +%left PLUS MINUS +%left TIMES DIVIDE +%nonassoc NEG +%right POWER + +%type Line Expression Field_expr +%start Line +%% + + +Line: + END { } + | Field_expr END { parsed=$1 ;} + ; + +Expression: + NUMBER { $$=new CSimpleNodeExpr(CSimpleNodeExpr::scalarDouble,$1); delete $1 } + | VAR { $$=new CSimpleNodeExpr(CSimpleNodeExpr::scalarVariable,$1) ; delete $1} + | Expression PLUS Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"add") ; $$->addChild($1) ; $$->addChild($3); } + | Expression MINUS Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"minus") ; $$->addChild($1) ; $$->addChild($3); } + | Expression TIMES Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"mult") ; $$->addChild($1) ; $$->addChild($3); } + | Expression DIVIDE Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"div") ; $$->addChild($1) ; $$->addChild($3); } + | MINUS Expression %prec NEG { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalar,"neg") ; $$->addChild($2); } + | Expression POWER Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarScalar,"pow") ; $$->addChild($1) ; $$->addChild($3); } + | LEFT_PARENTHESIS Expression RIGHT_PARENTHESIS { $$=$2 ; } + | ID LEFT_PARENTHESIS Expression RIGHT_PARENTHESIS { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalar,$1) ; $$->addChild($3) ; delete $1 } + ; + +Field_expr: + ID { $$=new CSimpleNodeExpr(CSimpleNodeExpr::fieldInstant,$1); delete $1} + | AVERAGE { $$=new CSimpleNodeExpr(CSimpleNodeExpr::fieldAverage,$1); delete $1} + | Field_expr PLUS Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"add") ; $$->addChild($1) ; $$->addChild($3); } + | Field_expr MINUS Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"minus") ; $$->addChild($1) ; $$->addChild($3); } + | Field_expr TIMES Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"mult") ; $$->addChild($1) ; $$->addChild($3); } + | Field_expr DIVIDE Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"div") ; $$->addChild($1) ; $$->addChild($3); } + | MINUS Field_expr %prec NEG { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opField,"neg") ; $$->addChild($2);} + | Field_expr POWER Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldField,"pow") ; $$->addChild($1) ; $$->addChild($3); } + | LEFT_PARENTHESIS Field_expr RIGHT_PARENTHESIS { $$=$2 ;} + | Field_expr PLUS Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"add") ; $$->addChild($1) ; $$->addChild($3); } + | Expression PLUS Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarField,"add") ; $$->addChild($1) ; $$->addChild($3); } + | Field_expr MINUS Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"minus") ; $$->addChild($1) ; $$->addChild($3); } + | Expression MINUS Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarField,"minus") ; $$->addChild($1) ; $$->addChild($3); } + | Field_expr TIMES Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"mult") ; $$->addChild($1) ; $$->addChild($3); } + | Expression TIMES Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarField,"mult") ; $$->addChild($1) ; $$->addChild($3); } + | Field_expr DIVIDE Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"div") ; $$->addChild($1) ; $$->addChild($3); } + | Expression DIVIDE Field_expr { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opScalarField,"div") ; $$->addChild($1) ; $$->addChild($3); } + | Field_expr POWER Expression { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opFieldScalar,"pow") ; $$->addChild($1) ; $$->addChild($3); } + | ID LEFT_PARENTHESIS Field_expr RIGHT_PARENTHESIS { $$=new CSimpleNodeExpr(CSimpleNodeExpr::opField,$1) ; $$->addChild($3) ; delete $1} + ; +%% + +extern "C" +{ + int yyerror(const char *s) + { + ERROR("int yyerror(const char *s)", <<"Parsing error :"< +#include +#include "mpi.hpp" +#include "tracer.hpp" +#include "timer.hpp" +#include "event_scheduler.hpp" + +namespace xios +{ + MPI_Comm CServer::intraComm ; + list CServer::interComm ; + bool CServer::isRoot ; + int CServer::rank = INVALID_RANK; + StdOFStream CServer::m_infoStream; + StdOFStream CServer::m_errorStream; + map CServer::contextList ; + bool CServer::finished=false ; + bool CServer::is_MPI_Initialized ; + CEventScheduler* CServer::eventScheduler ; + + void CServer::initialize(void) + { + int initialized ; + MPI_Initialized(&initialized) ; + if (initialized) is_MPI_Initialized=true ; + else is_MPI_Initialized=false ; + + // Not using OASIS + if (!CXios::usingOasis) + { + + if (!is_MPI_Initialized) + { + int argc=0; + char** argv=NULL; + MPI_Init(&argc,&argv) ; + } + CTimer::get("XIOS").resume() ; + + boost::hash hashString ; + + unsigned long hashServer=hashString(CXios::xiosCodeId) ; + unsigned long* hashAll ; + +// int rank ; + int size ; + int myColor ; + int i,c ; + MPI_Comm newComm ; + + MPI_Comm_size(CXios::globalComm,&size) ; + MPI_Comm_rank(CXios::globalComm,&rank); + hashAll=new unsigned long[size] ; + + MPI_Allgather(&hashServer,1,MPI_LONG,hashAll,1,MPI_LONG,CXios::globalComm) ; + + map colors ; + map leaders ; + map::iterator it ; + + for(i=0,c=0;ifirst!=hashServer) + { + clientLeader=it->second ; + int intraCommSize, intraCommRank ; + MPI_Comm_size(intraComm,&intraCommSize) ; + MPI_Comm_rank(intraComm,&intraCommRank) ; + info(50)<<"intercommCreate::server "<("oasis_codes_id") ; + + vector splitted ; + boost::split( splitted, codesId, boost::is_any_of(","), boost::token_compress_on ) ; + vector::iterator it ; + + MPI_Comm newComm ; + int globalRank ; + MPI_Comm_rank(CXios::globalComm,&globalRank); + + for(it=splitted.begin();it!=splitted.end();it++) + { + oasis_get_intercomm(newComm,*it) ; + if (rank==0) MPI_Send(&globalRank,1,MPI_INT,0,0,newComm) ; + MPI_Comm_remote_size(newComm,&size); + interComm.push_back(newComm) ; + } + oasis_enddef() ; + } + +// int rank; + MPI_Comm_rank(intraComm,&rank) ; + if (rank==0) isRoot=true; + else isRoot=false; + + eventScheduler = new CEventScheduler(intraComm) ; + } + + void CServer::finalize(void) + { + CTimer::get("XIOS").suspend() ; + + delete eventScheduler ; + + if (!is_MPI_Initialized) + { + if (CXios::usingOasis) oasis_finalize(); + else MPI_Finalize() ; + } + report(0)<<"Performance report : Time spent for XIOS : "<checkEvent() ; + } + CTimer::get("XIOS server").suspend() ; + } + + void CServer::listenFinalize(void) + { + list::iterator it; + int msg ; + int flag ; + + for(it=interComm.begin();it!=interComm.end();it++) + { + MPI_Status status ; + traceOff() ; + MPI_Iprobe(0,0,*it,&flag,&status) ; + traceOn() ; + if (flag==true) + { + MPI_Recv(&msg,1,MPI_INT,0,0,*it,&status) ; + info(20)<<" CServer : Receive client finalize"< recvContextId ; + map::iterator it ; + + CBufferIn buffer(buff,count) ; + string id ; + int clientLeader ; + int nbMessage ; + + buffer>>id>>nbMessage>>clientLeader ; + + it=recvContextId.find(id) ; + if (it==recvContextId.end()) + { + contextMessage msg={0,0} ; + pair::iterator,bool> ret ; + ret=recvContextId.insert(pair(id,msg)) ; + it=ret.first ; + } + it->second.nbRecv+=1 ; + it->second.leaderRank+=clientLeader ; + + if (it->second.nbRecv==nbMessage) + { + int size ; + MPI_Comm_size(intraComm,&size) ; + MPI_Request* requests= new MPI_Request[size-1] ; + MPI_Status* status= new MPI_Status[size-1] ; + + for(int i=1;isecond.leaderRank) ; + + recvContextId.erase(it) ; + delete [] requests ; + delete [] status ; + + } + } + + void CServer::listenRootContext(void) + { + + MPI_Status status ; + int flag ; + static void* buffer ; + static MPI_Request request ; + static bool recept=false ; + int rank ; + int count ; + const int root=0 ; + + if (recept==false) + { + traceOff() ; + MPI_Iprobe(root,2,intraComm, &flag, &status) ; + traceOn() ; + if (flag==true) + { + MPI_Get_count(&status,MPI_CHAR,&count) ; + buffer=new char[count] ; + MPI_Irecv(buffer,count,MPI_CHAR,root,2,intraComm,&request) ; + recept=true ; + } + } + else + { + MPI_Test(&request,&flag,&status) ; + if (flag==true) + { + MPI_Get_count(&status,MPI_CHAR,&count) ; + registerContext(buffer,count) ; + delete [] buffer ; + recept=false ; + } + } + } + + + + void CServer::registerContext(void* buff,int count, int leaderRank) + { + + string contextId; + CBufferIn buffer(buff,count) ; + + buffer>>contextId ; + MPI_Comm contextIntercomm ; + MPI_Intercomm_create(intraComm,0,CXios::globalComm,leaderRank,10+leaderRank,&contextIntercomm) ; + + info(20)<<"CServer : Register new Context : "<initServer(intraComm,contextIntercomm) ; + + } + + + void CServer::contextEventLoop(void) + { + bool finished ; + map::iterator it ; + for(it=contextList.begin();it!=contextList.end();it++) + { + finished=it->second->eventLoop() ; + if (finished) + { + contextList.erase(it) ; + break ; + } + } + + } + + //! Get rank of the current process + int CServer::getRank() + { + return rank; + } + + /*! + * Open a file specified by a suffix and an extension and use it for the given file buffer. + * The file name will be suffix+rank+extension. + * + * \param fileName[in] protype file name + * \param ext [in] extension of the file + * \param fb [in/out] the file buffer + */ + void CServer::openStream(const StdString& fileName, const StdString& ext, std::filebuf* fb) + { + StdStringStream fileNameClient; + int numDigit = 0; + int size = 0; + MPI_Comm_size(CXios::globalComm, &size); + while (size) + { + size /= 10; + ++numDigit; + } + + fileNameClient << fileName << "_" << std::setfill('0') << std::setw(numDigit) << getRank() << ext; + fb->open(fileNameClient.str().c_str(), std::ios::out); + if (!fb->is_open()) + ERROR("void CServer::openStream(const StdString& fileName, const StdString& ext, std::filebuf* fb)", + << std::endl << "Can not open <" << fileNameClient << "> file to write the server log(s)."); + } + + /*! + * \brief Open a file stream to write the info logs + * Open a file stream with a specific file name suffix+rank + * to write the info logs. + * \param fileName [in] protype file name + */ + void CServer::openInfoStream(const StdString& fileName) + { + std::filebuf* fb = m_infoStream.rdbuf(); + openStream(fileName, ".out", fb); + + info.write2File(fb); + report.write2File(fb); + } + + //! Write the info logs to standard output + void CServer::openInfoStream() + { + info.write2StdOut(); + report.write2StdOut(); + } + + //! Close the info logs file if it opens + void CServer::closeInfoStream() + { + if (m_infoStream.is_open()) m_infoStream.close(); + } + + /*! + * \brief Open a file stream to write the error log + * Open a file stream with a specific file name suffix+rank + * to write the error log. + * \param fileName [in] protype file name + */ + void CServer::openErrorStream(const StdString& fileName) + { + std::filebuf* fb = m_errorStream.rdbuf(); + openStream(fileName, ".err", fb); + + error.write2File(fb); + } + + //! Write the error log to standard error output + void CServer::openErrorStream() + { + error.write2StdErr(); + } + + //! Close the error log file if it opens + void CServer::closeErrorStream() + { + if (m_errorStream.is_open()) m_errorStream.close(); + } +} diff --git a/src/server.hpp b/src/server.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7604578cbb48e6aa6c206d3e49407028f4d0dfc5 --- /dev/null +++ b/src/server.hpp @@ -0,0 +1,68 @@ +#ifndef __SERVER_HPP__ +#define __SERVER_HPP__ + +#include "xmlioserver_spl.hpp" +#include "context.hpp" +#include "mpi.hpp" +#include "event_scheduler.hpp" + +namespace xios +{ + class CServer + { + public: + static void initialize(void); + static void finalize(void); + static void eventLoop(void); + static void contextEventLoop(void); + static void listenContext(void); + static void listenFinalize(void); + static void recvContextMessage(void* buff,int count); + static void listenRootContext(void); + static void listenRootFinalize(void); + static void registerContext(void* buff,int count, int leaderRank=0); + + static MPI_Comm intraComm; + static list interComm; + static CEventScheduler* eventScheduler; + + struct contextMessage + { + int nbRecv; + int leaderRank; + }; + + static bool isRoot; + + static map contextList; + static bool finished; + static bool is_MPI_Initialized; + + public: + //! Get rank of the current process + static int getRank(); + + //! Open a file stream to write the info logs + static void openInfoStream(const StdString& fileName); + //! Write the info logs to standard output + static void openInfoStream(); + //! Close the info logs file if it opens + static void closeInfoStream(); + + //! Open a file stream to write the error log + static void openErrorStream(const StdString& fileName); + //! Write the error log to standard error output + static void openErrorStream(); + //! Close the error log file if it opens + static void closeErrorStream(); + + private: + static int rank; + static StdOFStream m_infoStream; + static StdOFStream m_errorStream; + + static void openStream(const StdString& fileName, const StdString& ext, std::filebuf* fb); + }; +} + +#endif diff --git a/src/test/parse_xml.f90 b/src/test/parse_xml.f90 new file mode 100644 index 0000000000000000000000000000000000000000..64e0381abb6071ee793e441f84222976785ff712 --- /dev/null +++ b/src/test/parse_xml.f90 @@ -0,0 +1,12 @@ +PROGRAM parse_xml + USE, INTRINSIC :: ISO_C_BINDING + IMPLICIT NONE + + INTERFACE + SUBROUTINE xios_init() BIND(C, name='cxios_init') + END SUBROUTINE + END INTERFACE + + CALL xios_init() ! This will parse the XML file and report any parsing error + +END PROGRAM parse_xml diff --git a/src/test/test.cpp b/src/test/test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d46d60ec3e77c233d049ca5118ee5984056b30a --- /dev/null +++ b/src/test/test.cpp @@ -0,0 +1,155 @@ +#include +#include +#include + +#include +#include +#include "calendar_type.hpp" +#include "date.hpp" +#include "calendar_util.hpp" +//#include "test_enum.hpp" +#include "type.hpp" +//#include "axis.hpp" +//#include "field.hpp" +#include "declare_attribute.hpp" +#include "attribute_map.hpp" +#include "array_new.hpp" +#include "attribute_array.hpp" +#include "attribute_array_impl.hpp" + + + +using namespace std ; +using namespace boost::posix_time ; +using namespace boost::gregorian ; +using namespace xios; +using namespace blitz; + + class CEnum_color + { + public: + enum t_enum { rouge=0, vert, bleu} ; + static const char** getStr(void) { static const char * enumStr[] = { "rouge", "vert", "bleu" } ; return enumStr ; } + int getSize(void) { return 3 ; } + } ; + +#include "enum.hpp" +#include "enum_impl.hpp" +#include "enum_ref_impl.hpp" +#include "attribute_enum.hpp" +#include "attribute_enum_impl.hpp" + +template class CEnum ; +template class CAttributeEnum ; + + +int main(void) +{ +// ptime t(time_from_string("2012-02-30 15:24")) ; +// std::cout << to_simple_string(t) << std::endl; + CGregorianCalendar MyCalendar("2011-03-01 00:00") ; + cout< MyEnum ; + //MyEnum.val=CEnum::rouge ; + + CEnum_color::t_enum y; + + CType a(10) ; + CType b ; + + a=5 ; + b=10.5 ; + a=a+b ; + cout< c(a); + cout< xx("toto") ; +// test::totoatt toto ; +// test::titiatt titi ; +// CAxis A ; +// CTest A ; +// CAxis B ; +// CField A ; +// cout< color,color1 ; + color=CEnum::rouge ; + color1=color ; + + if (color1==CEnum::rouge) cout<<"Rouge !!"<::bleu ; + + if (color1==color) cout<<"Rouge !!"< toto("toto",CEnum_color::rouge) ; + CAttributeEnum titi("titi",CEnum_color::vert) ; + cout< A(2,2) ; + CArray B(2,2) ; + A=1,2,3,4 ; + B = 1 ; + B+=A ; + cout< C ; + CBufferOut out(B.size()) ; + + B.toBuffer(out) ; + + CBufferIn in(out.begin,B.size()) ; + C.fromBuffer(in) ; + + cout< attr("toto") ; + attr.resize(2,2) ; + attr=C ; + cout<<"attr "<=0) + j2=MAX(j1-ncell_x+1,1) + j=(j1+j2)/2 + n=NINT(COS(Pi/2-(j-0.5)*PI/nlat)*nlon) + np = MIN(n/ncell_x,rank+1) ; + if (j2==1) np=rank+1 + + PRINT *,"domain ",j2,j1,rank,np ; + DO j=j2,j1 + n=NINT(COS(Pi/2-(j-0.5)*PI/nlat)*nlon) + IF (n<8) n=8 + DO i=1,n + ind=list_ind(i,j) + IF ( (i-1) < MOD(n,np)*(n/np+1)) THEN + i_index_glo(ind) = rank - (i-1)/(n/np+1) + ELSE + i_index_glo(ind) = rank-(MOD(n,np)+ (i-1-MOD(n,np)*(n/np+1))/(n/np)) + ENDIF + ENDDO + ENDDO + rank=rank-np + j1=j2-1 + ENDDO + + rank=(mpi_size-1)/2+1 + ncell_x=sqrt(ncell_glo*1./mpi_size) + + j1=nlat/2+1 + DO WHILE(rank<=mpi_size-1) + j2=MIN(j1+ncell_x-1,nlat) + j=(j1+j2)/2 + n=NINT(COS(Pi/2-(j-0.5)*PI/nlat)*nlon) + np = MIN(n/ncell_x,mpi_size-rank) ; + if (j2==nlat) np=mpi_size-rank + + PRINT *,"domain ",j2,j1,rank,np ; + DO j=j1,j2 + n=NINT(COS(Pi/2-(j-0.5)*PI/nlat)*nlon) + IF (n<8) n=8 + DO i=1,n + ind=list_ind(i,j) + IF ( (i-1) < MOD(n,np)*(n/np+1)) THEN + i_index_glo(ind) = rank + (i-1)/(n/np+1) + ELSE + i_index_glo(ind) = rank+(MOD(n,np)+ (i-1-MOD(n,np)*(n/np+1))/(n/np)) + ENDIF + ENDDO + ENDDO + rank=rank+np + j1=j2+1 + ENDDO + + ncell=0 + DO ind=1,ncell_glo + IF (i_index_glo(ind)==mpi_rank) ncell=ncell+1 + ENDDO + ALLOCATE(i_index(ncell)) + ALLOCATE(lon(ncell)) + ALLOCATE(lat(ncell)) + ALLOCATE(bounds_lon(4,ncell)) + ALLOCATE(bounds_lat(4,ncell)) + ALLOCATE(field_A_srf(ncell,llm)) + ALLOCATE(mask(ncell)) + ncell=0 + data_n_index=0 + DO ind=1,ncell_glo + IF (i_index_glo(ind)==mpi_rank) THEN + ncell=ncell+1 + i_index(ncell)=ind-1 + lon(ncell)=lon_glo(ind) + lat(ncell)=lat_glo(ind) + bounds_lon(:,ncell)=bounds_lon_glo(:,ind) + bounds_lat(:,ncell)=bounds_lat_glo(:,ind) + field_A_srf(ncell,:)=i_index_glo(ind) + IF (MOD(ind,8)>=0 .AND. MOD(ind,8)<2) THEN + mask(ncell)=.FALSE. + ELSE + mask(ncell)=.TRUE. + data_n_index=data_n_index+1 + ENDIF + ENDIF + ENDDO + + ALLOCATE(field_A_compressed(data_n_index,llm)) + ALLOCATE(data_i_index(data_n_index)) + data_n_index=0 + DO ind=1,ncell + IF (mask(ind)) THEN + data_n_index=data_n_index+1 + data_i_index(data_n_index)=ind + field_A_compressed(data_n_index,:)=field_A_srf(ind,:) + ENDIF + ENDDO + + + + CALL xios_context_initialize("surface",comm) + CALL xios_get_handle("surface",ctx_hdl) + CALL xios_set_current_context(ctx_hdl) + + CALL xios_set_axis_attr("axis_srf",size=llm ,value=lval) ; + CALL xios_set_domain_attr("domain_srf",ni_glo=ncell_glo, ni=ncell, ibegin=1, i_index=RESHAPE(i_index,(/ncell,1/) )) + CALL xios_set_domain_attr("domain_srf",data_dim=1, data_ni=data_n_index, data_n_index=data_n_index, data_i_index=data_i_index, type='unstructured') + CALL xios_set_domain_attr("domain_srf",lonvalue=lon,latvalue=lat) + CALL xios_set_domain_attr("domain_srf", nvertex=4, bounds_lon=bounds_lon, bounds_lat=bounds_lat ) + + + dtime%second=3600 + CALL xios_set_timestep(dtime) + CALL xios_close_context_definition() + + DO ts=1,24*10 + CALL xios_update_calendar(ts) + CALL xios_send_field("field_A_srf",field_A_compressed) + ENDDO + + CALL xios_context_finalize() + CALL xios_finalize() + + END PROGRAM test_unstruct_complete + + + + + diff --git a/src/test/test_xios.cpp b/src/test/test_xios.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2be157426f7e0fe61e8103337727d78a2a48e9d7 --- /dev/null +++ b/src/test/test_xios.cpp @@ -0,0 +1,118 @@ +#include "xmlioserver.hpp" +#include "attribute_template.hpp" +#include "buffer_out.hpp" +#include "buffer_in.hpp" +#include "type.hpp" +#include "cxios.hpp" +#include "client.hpp" +#include "event_client.hpp" +#include "context.hpp" +#include "context_client.hpp" +#include "context_server.hpp" +#include "object_template.hpp" +#include "array_new.hpp" +#include "mpi.hpp" + + +using namespace std ; + +int main (int argc, char ** argv, char ** UNUSED (env)) +{ + + int a=3 ; + int b=2 ; + int c=1 ; + int buff[100] ; + string str("titi") ; + CBufferOut bufferOut(&buff,sizeof(buff)) ; + CBufferIn bufferIn(&buff,sizeof(buff)) ; + CMessage msg ; + + CAttributeArray tabIn("in") ; + CAttributeArray tabOut("out") ; + + CArray tab(5) + tab=0,1,2,3,4 ; + tabIn=tab ; + tab= 4,3,2,1,0 + tabOut=tab ; +// tabOut=1 ; + tabIn.toBuffer(bufferOut) ; + tabOut.fromBuffer(bufferIn) ; + + cout<<"attribut>="<=0 && rank<=1) + { + CXios::initClientSide("test1") ; + CClient::registerContext("toto",CClient::intraComm) ; +// CClient::registerContext("tata",CClient::intraComm) ; + CClient::registerContext("tutu",CClient::intraComm) ; + CContext::setCurrent("tutu") ; + CContext* tutu=CContext::get("tutu").get() ; + + + CContext::setCurrent("toto") ; + CContext* toto=(CContext::get("toto").get() ; + toto->calendar_type.setValue("NoLeap") ; + toto->sendAttributToServer("calendar_type" ); + + + for(int i=0;i<0;i++) + { + CMessage msg ; + int count ; + int msgSize; + CEventClient event(1,1) ; + count=rand()%32 ; + msg<client->sendEvent(event) ; + cout<<"Send Event from toto : size "<client->finalize() ; + tutu->client->finalize() ; + CXios::clientFinalize() ; + } + else if (rank>=2 && rank<=3) CXios::initServerSide(); + else if (rank>=4 && rank<=6) + { + CXios::initClientSide("test2") ; + CClient::registerContext("tito",CClient::intraComm) ; + CContext::setCurrent("tito") ; + CContext* tito=CContext::get("tito").get() ; + + CClient::registerContext("tete",CClient::intraComm) ; + CContext::setCurrent("tete") ; + CContext* tete=CContext::get("tete").get() ; + + tito->client->finalize() ; + tete->client->finalize() ; + CXios::clientFinalize() ; + } + else if (rank>=7 && rank<=7) + { + CXios::initClientSide("test3") ; + CClient::registerContext("turlututu",CClient::intraComm) ; + CContext::setCurrent("turlututu") ; + CContext* turlututu=CContext::get("turlututu").get() ; + turlututu->client->finalize() ; + CXios::clientFinalize() ; + } + + + + MPI_Barrier(MPI_COMM_WORLD); + MPI_Finalize() ; + + return EXIT_SUCCESS ; + +} diff --git a/src/test/test_xios_interface.f90 b/src/test/test_xios_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..60d57356ba3c2bb2c70e62b7cb87b957b50a9299 --- /dev/null +++ b/src/test/test_xios_interface.f90 @@ -0,0 +1,358 @@ +PROGRAM test_xios_interface + + ! This test is based on test_complete + USE xios + USE mod_wait + IMPLICIT NONE + INCLUDE "mpif.h" + INTEGER :: rank + INTEGER :: size_loc + INTEGER :: ierr + + CHARACTER(len=*),PARAMETER :: id="client" + INTEGER :: comm + TYPE(xios_time) :: dtime + TYPE(xios_context) :: ctx_hdl + INTEGER,PARAMETER :: ni_glo=100 + INTEGER,PARAMETER :: nj_glo=100 + INTEGER,PARAMETER :: llm=5 + DOUBLE PRECISION :: lval(llm)=1 + TYPE(xios_field) :: field_hdl + TYPE(xios_fieldgroup) :: fieldgroup_hdl + TYPE(xios_file) :: file_hdl + LOGICAL :: ok + CHARACTER(len=256) :: crname + + DOUBLE PRECISION,DIMENSION(ni_glo,nj_glo) :: lon_glo,lat_glo + DOUBLE PRECISION :: field_A_glo(ni_glo,nj_glo,llm) + DOUBLE PRECISION,ALLOCATABLE :: lon(:,:),lat(:,:),field_A_atm(:,:,:), field_A_srf(:,:), lonvalue(:) + INTEGER, ALLOCATABLE :: kindex(:) + INTEGER :: ni,ibegin,iend,nj,jbegin,jend + INTEGER :: i,j,l,ts,n, nb_pt + + INTEGER :: var_val_int + REAL :: var_val_float + DOUBLE PRECISION :: var_val_double + LOGICAL :: var_val_bool + CHARACTER(len=256) :: var_val_char ="" + CHARACTER(len=256) :: var_id + +!!! MPI Initialization + + CALL MPI_INIT(ierr) + + CALL init_wait + +!!! XIOS Initialization (get the local communicator) + + CALL xios_initialize(id,return_comm=comm) + + CALL MPI_COMM_RANK(comm,rank,ierr) + CALL MPI_COMM_SIZE(comm,size_loc,ierr) + +!------------------------------------------------------------------------------- +! +! Define all neccessary values for test +! +!------------------------------------------------------------------------------- +!########################################################################### +! Contexte ATM +!########################################################################### + +!!! Initialisation des coordonnées globales et locales pour la grille régulière + + DO j=1,nj_glo + DO i=1,ni_glo + lon_glo(i,j)=(i-1)+(j-1)*ni_glo + lat_glo(i,j)=1000+(i-1)+(j-1)*ni_glo + DO l=1,llm + field_A_glo(i,j,l)=(i-1)+(j-1)*ni_glo+10000*l + ENDDO + ENDDO + ENDDO + ni=ni_glo ; ibegin=1 + + jbegin=1 + DO n=0,size_loc-1 + nj=nj_glo/size_loc + IF (n + class CEnum : public CEnumType + { + public : +// typedef CEnum::t_enum myEnum; + } ; +} + diff --git a/src/timer.cpp b/src/timer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..80d3ddf1adf30f0e4cfc407effa225a1dd5988c8 --- /dev/null +++ b/src/timer.cpp @@ -0,0 +1,61 @@ +#include "timer.hpp" +#include "mpi.hpp" +#include +#include +#include "tracer.hpp" + +namespace xios +{ + using namespace std; + + map CTimer::allTimer ; + + CTimer::CTimer(const string& name_) : name(name_) + { + reset() ; + } + + double CTimer::getTime(void) + { + return MPI_Wtime(); + } + + void CTimer::suspend(void) + { + if (!suspended) + { + traceEnd(name) ; + cumulatedTime+=getTime()-lastTime ; + } + suspended=true ; + } + + void CTimer::resume(void) + { + if (suspended) + { + lastTime=getTime() ; + traceBegin(name) ; + } + suspended=false ; + } + + void CTimer::reset(void) + { + cumulatedTime=0. ; + suspended=true ; + } + + double CTimer::getCumulatedTime(void) + { + return cumulatedTime ; + } + + CTimer& CTimer::get(const string name) + { + map::iterator it ; + it=allTimer.find(name) ; + if (it==allTimer.end()) it=allTimer.insert(pair(name,new CTimer(name))).first ; + return *(it->second) ; + } +} diff --git a/src/timer.hpp b/src/timer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b59d20d91ed5693853ffa3f83c197d133eb454fc --- /dev/null +++ b/src/timer.hpp @@ -0,0 +1,35 @@ +#ifndef __TIMER_HPP__ +#define __TIMER_HPP__ + +#include +#include + +namespace xios +{ + using namespace std ; + + + class CTimer + { + public : + + double cumulatedTime ; + double lastTime ; + bool suspended ; + string name ; + + CTimer(const string& name) ; + void suspend(void) ; + void resume(void) ; + void reset(void) ; + double getCumulatedTime(void) ; + static map allTimer ; + static double getTime(void) ; + static CTimer& get(string name) ; + } ; + +} + + + +#endif diff --git a/src/tracer.cpp b/src/tracer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fbc5489c83a4b4ec55fced3f03c69ac62cad32d5 --- /dev/null +++ b/src/tracer.cpp @@ -0,0 +1,42 @@ +#include "tracer.hpp" +#ifdef VTRACE +#include +#endif +#include + +namespace xios +{ + using namespace std ; + + void traceOn(void) + { +#ifdef VTRACE + VT_ON() ; +#endif + } + + void traceOff(void) + { +#ifdef VTRACE + VT_OFF() ; +#endif + } + + void traceBegin(const string& name) + { +#ifdef VTRACE + VT_USER_START(name.c_str()) ; +#endif + } + + void traceEnd(const string& name) + { +#ifdef VTRACE + VT_USER_END(name.c_str()) ; +#endif + } + +// void marker(const string& name,const string& text) ; + + +} diff --git a/src/tracer.hpp b/src/tracer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b96f338f8a8756b4e53f975fe880b9e20afb49eb --- /dev/null +++ b/src/tracer.hpp @@ -0,0 +1,22 @@ +#ifndef __TRACER_HPP__ +#define __TRACER_HPP__ + +#include + +namespace xios +{ + using namespace std ; + + void traceOn(void) ; + void traceOff(void) ; + + void traceBegin(const string& name) ; + void traceEnd(const string& name) ; + + void marker(const string& name,const string& text) ; + +} + + + +#endif diff --git a/src/type/base_type.hpp b/src/type/base_type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e25f7e14455dea79f6f5da902df8fcaa850f8eb6 --- /dev/null +++ b/src/type/base_type.hpp @@ -0,0 +1,30 @@ +#ifndef __BASE_TYPE_HPP__ +#define __BASE_TYPE_HPP__ + +#include "xmlioserver_spl.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" + +namespace xios +{ + + class CBaseType + { + public: + + CBaseType(void) {} + virtual ~CBaseType() {} + virtual void fromString(const string& str) =0 ; + virtual string toString(void) const =0; + + virtual bool fromBuffer(CBufferIn& buffer) =0; + virtual bool toBuffer(CBufferOut& buffer) const =0; + virtual CBaseType* clone(void) const =0; + virtual size_t size(void) const =0; + virtual bool isEmpty(void) const =0; + virtual void reset(void) =0; + } ; + +} + +#endif diff --git a/src/type/enum.hpp b/src/type/enum.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3a39243d9935fd11c2e13bb1bfb7614c26bb7f27 --- /dev/null +++ b/src/type/enum.hpp @@ -0,0 +1,154 @@ +#ifndef __XIOS_ENUM__ +#define __XIOS_ENUM__ + +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "base_type.hpp" +#include "message.hpp" + +#define __INLINE__ inline + + +namespace xios +{ + class CEnumBase + { + } ; + + template class CEnum_ref ; + + template + class CEnum : public virtual CBaseType, public T + { + public: + typedef typename T::t_enum T_enum ; + CEnum(void) ; + __INLINE__ CEnum(const T_enum& val) ; + __INLINE__ CEnum(const CEnum& type) ; + __INLINE__ CEnum(const CEnum_ref& type) ; + virtual ~CEnum() { _reset() ; } + + __INLINE__ T_enum& get(void) ; + __INLINE__ const T_enum& get(void) const; + + __INLINE__ void set(const T_enum& val) ; + __INLINE__ void set(const CEnum& val) ; + __INLINE__ void set(const CEnum_ref& val) ; + __INLINE__ CEnum& operator = (const T_enum& val) ; + __INLINE__ CEnum& operator = (const CEnum& val) ; + __INLINE__ CEnum& operator = (const CEnum_ref& val) ; + __INLINE__ operator T_enum&() ; + + inline virtual CBaseType* clone(void) const { return _clone(); } + virtual void fromString(const string& str) { _fromString(str); } + virtual string toString(void) const { return _toString(); } + virtual bool fromBuffer(CBufferIn& buffer) { return _fromBuffer(buffer) ; } + virtual bool toBuffer(CBufferOut& buffer) const { return _toBuffer(buffer); } + virtual void reset(void) { _reset(); } + virtual bool isEmpty() const { return _isEmpty(); } + virtual size_t size(void) const { return _size(); } + + __INLINE__ void allocate(void) ; + __INLINE__ void checkEmpty(void) const; + + T_enum* ptrValue ; + bool empty ; + + friend class CEnum_ref ; + + private : + + __INLINE__ CEnum* _clone(void) const; + __INLINE__ void _fromString(const string& str) ; + __INLINE__ string _toString(void) const; + __INLINE__ bool _fromBuffer(CBufferIn& buffer) ; + __INLINE__ bool _toBuffer(CBufferOut& buffer) const; + __INLINE__ void _reset(void) ; + __INLINE__ bool _isEmpty() const ; + __INLINE__ size_t _size(void) const ; + + } ; + + + + template + class CEnum_ref : public virtual CBaseType, public T + { + public: + + typedef typename T::t_enum T_enum ; + __INLINE__ CEnum_ref(void) ; + __INLINE__ CEnum_ref(T_enum& val) ; + __INLINE__ CEnum_ref(CEnum& type) ; + __INLINE__ CEnum_ref(const CEnum_ref& type) ; + virtual ~CEnum_ref() {}; + + __INLINE__ T_enum& get(void) const; + + __INLINE__ void set(const T_enum& val) const ; + __INLINE__ void set(const CEnum& val) const ; + __INLINE__ void set(const CEnum_ref& val) const ; + + __INLINE__ void set_ref(T_enum& val) ; + __INLINE__ void set_ref(CEnum& val) ; + __INLINE__ void set_ref(const CEnum_ref& val) ; + + __INLINE__ const CEnum_ref& operator = (T_enum& val) const ; + __INLINE__ const CEnum_ref& operator = (CEnum& val) const ; + __INLINE__ const CEnum_ref& operator = (const CEnum_ref& val) const; + __INLINE__ operator T_enum&() const; + bool operator == (const CEnum_ref &other) {return this->get()==other.get() ;} + + inline virtual CBaseType* clone(void) const { return _clone(); } + virtual void fromString(const string& str) { _fromString(str); } + virtual void fromString(const string& str) const { _fromString(str); } + virtual string toString(void) const { return _toString(); } + virtual bool fromBuffer(CBufferIn& buffer) { return _fromBuffer(buffer) ; } + virtual bool fromBuffer(CBufferIn& buffer) const { return _fromBuffer(buffer); } + virtual bool toBuffer(CBufferOut& buffer) const { return _toBuffer(buffer); } + virtual void reset(void) { _reset(); } + virtual bool isEmpty() const { return _isEmpty(); } + virtual size_t size(void) const { return _size(); } + + __INLINE__ void checkEmpty(void) const; + + + T_enum mutable * ptrValue ; + bool empty ; + friend class CEnum ; + + private : + + __INLINE__ CEnum_ref* _clone(void) const; + __INLINE__ void _fromString(const string& str) ; + __INLINE__ void _fromString(const string& str) const; + __INLINE__ string _toString(void) const; + __INLINE__ bool _fromBuffer(CBufferIn& buffer) ; + __INLINE__ bool _fromBuffer(CBufferIn& buffer) const ; + __INLINE__ bool _toBuffer(CBufferOut& buffer) const; + __INLINE__ void _reset(void) ; + __INLINE__ bool _isEmpty() const ; + __INLINE__ size_t _size(void) const ; + } ; + + template __INLINE__ CBufferOut& operator<<(CBufferOut& buffer, const CEnum& type) ; + template __INLINE__ CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type) ; + template __INLINE__ CBufferIn& operator>>(CBufferIn& buffer, CEnum& type) ; +// template __INLINE__ CMessage& operator<<(CMessage& msg, const CEnum& type) ; + template __INLINE__ CMessage& operator<<(CMessage& msg, const typename T::t_enum & type) ; + + template __INLINE__ CBufferOut& operator<<(CBufferOut& buffer, const CEnum& type) ; + template __INLINE__ CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type); + template __INLINE__ CBufferIn& operator>>(CBufferIn& buffer, CEnum& type); +// template __INLINE__ CMessage& operator<<(CMessage& msg, const CEnum& type); + template __INLINE__ CMessage& operator<<(CMessage& msg, const typename T::t_enum & type); +} + +# ifdef __INLINE__ +# include "enum_impl.hpp" +# include "enum_ref_impl.hpp" +# endif + +#endif diff --git a/src/type/enum_impl.hpp b/src/type/enum_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c6d1eda72aeb6063035e1cf7319dd55562a42702 --- /dev/null +++ b/src/type/enum_impl.hpp @@ -0,0 +1,295 @@ +#ifndef __XIOS_ENUM_IMPL__ +#define __XIOS_ENUM_IMPL__ + +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "message.hpp" +#include +#include + +namespace xios +{ + + using namespace std; + + template + CEnum::CEnum(void) + { + empty=true ; + } + + template + CEnum::CEnum(const T_enum& val) + { + empty=true ; + set(val) ; + } + + template + CEnum::CEnum(const CEnum& type) + { + empty=true ; + set(type) ; + } + + template + CEnum::CEnum(const CEnum_ref& type) + { + empty=true ; + set(type) ; + } + + template + void CEnum::set(const T_enum& val) + { + if (empty) + { + ptrValue = new T_enum(val) ; + empty=false ; + } + else *ptrValue = val ; + } + + template + void CEnum::set(const CEnum& type) + { + if (type.isEmpty()) reset() ; + else + { + if (empty) + { + ptrValue = new T_enum(*type.ptrValue) ; + empty=false ; + } + else *ptrValue = *type.ptrValue ; + } + } + + template + void CEnum::set(const CEnum_ref& type) + { + if (type.isEmpty()) reset() ; + else + { + if (empty) + { + ptrValue = new T_enum(*type.ptrValue) ; + empty=false ; + } + else *ptrValue = *type.ptrValue ; + } + } + + + template + typename T::t_enum & CEnum::get(void) + { + checkEmpty(); + return *ptrValue ; + } + + template + const typename T::t_enum& CEnum::get(void) const + { + checkEmpty(); + return *ptrValue ; + } + + template + CEnum& CEnum::operator = (const T_enum& val) + { + set(val) ; + return *this ; + } + + template + CEnum& CEnum::operator = (const CEnum& type) + { + set(type) ; + return *this ; + } + + template + CEnum& CEnum::operator = (const CEnum_ref& type) + { + set(type) ; + return *this ; + } + + + template + CEnum::operator T_enum&() + { + checkEmpty(); + return *ptrValue ; + } + + template + CEnum* CEnum::_clone(void) const + { + checkEmpty(); + return new CEnum(*this) ; + } + + + template + void CEnum::_fromString(const string& str) + { + string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ; + + bool found=false ; + for(int i=0;i0) strList<<", " ; + strList< void CEnum::_fromString(const string& str)", + << tmpStr << " cannot be converted in a valid enumeration, possibilities are : "< + size_t CEnum::_size(void) const + { + return sizeof(T_enum) ; + } + + template + bool CEnum::_isEmpty(void) const + { + return empty ; + } + + template + string CEnum::_toString(void) const + { + if (empty) return string("empty") ; + return string((T::getStr())[(int)(*ptrValue)]) ; + } + + template + bool CEnum::_toBuffer(CBufferOut& buffer) const + { + checkEmpty(); + if (sizeof(*ptrValue)==sizeof(short int)) return buffer.put((short int) *ptrValue) ; + else if (sizeof(*ptrValue)==sizeof(int)) return buffer.put((int) *ptrValue) ; + else if (sizeof(*ptrValue)==sizeof(long int)) return buffer.put((long int) *ptrValue) ; + else ERROR("template bool CEnum::_toBuffer(CBufferOut& buffer) const", + <<"incompatibility between enumeration and standard integer type") ; + return false ; + } + + template + bool CEnum::_fromBuffer(CBufferIn& buffer) + { + bool ret ; + allocate() ; + if (sizeof(*ptrValue)==sizeof(short int)) + { + short int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else if (sizeof(*ptrValue)==sizeof(int)) + { + int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else if (sizeof(*ptrValue)==sizeof(long int)) + { + long int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else ERROR("template bool CEnum::_fromBuffer(CBufferIn& buffer)", + <<"incompatibility between enumeration and standard integer type") ; + return ret ; + } + + + template + void CEnum::allocate(void) + { + if (empty) + { + ptrValue = new T_enum ; + empty=false ; + } + } + + template + void CEnum::_reset(void) + { + if (!empty) + { + delete ptrValue ; + empty=true ; + } + } + + template + void CEnum::checkEmpty(void) const + { + if (empty) ERROR("template void CEnum::checkEmpty(void) const", <<"Type is not initialized") ; + } + + + template + CBufferOut& operator<<(CBufferOut& buffer, const CEnum& type) + { + if (!type.toBuffer(buffer)) ERROR("template CBufferOut& operator<<(CBufferOut& buffer, const CEnum& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type) + { + if (!CEnum(type).toBuffer(buffer)) ERROR("template CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum & type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferIn& operator>>(CBufferIn& buffer, CEnum& type) + { + if (! type.fromBuffer(buffer)) ERROR("template CBufferIn& operator>>(CBufferIn& buffer, CEnum& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + +/* + template + CMessage& operator<<(CMessage& msg, const CEnum& type) + { + msg.push(*type.clone()) ; + return msg ; + } +*/ + + template + CMessage& operator<<(CMessage& msg, const typename T::t_enum & type) + { + msg.push(*CEnum(type).clone()) ; + return msg ; + } + +} + +#endif + diff --git a/src/type/enum_ref_impl.hpp b/src/type/enum_ref_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9c7eca32b4cf74201400910945d5d77af62d32d8 --- /dev/null +++ b/src/type/enum_ref_impl.hpp @@ -0,0 +1,319 @@ +#ifndef __XIOS_ENUM_REF_IMPL__ +#define __XIOS_ENUM_REF_IMPL__ + +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "message.hpp" +#include +#include + +namespace xios +{ + + + using namespace std; + + template + CEnum_ref::CEnum_ref(void) + { + empty=true ; + } + + template + CEnum_ref::CEnum_ref(T_enum& val) + { + empty=true ; + set_ref(val) ; + } + + template + CEnum_ref::CEnum_ref(CEnum& type) + { + empty=true ; + set_ref(type) ; + } + + template + CEnum_ref::CEnum_ref(const CEnum_ref& type) + { + empty=true ; + set_ref(type) ; + } + + + template + void CEnum_ref::set_ref(T_enum& val) + { + ptrValue=&val ; + empty=false ; + } + + template + void CEnum_ref::set_ref(CEnum& type) + { + ptrValue=&type.get() ; + empty=false ; + } + + template + void CEnum_ref::set_ref(const CEnum_ref& type) + { + ptrValue=type.ptrValue ; + empty=type.empty ; + } + + template + void CEnum_ref::set(const T_enum& val) const + { + checkEmpty() ; + *ptrValue=val ; + } + + template + void CEnum_ref::set(const CEnum& type) const + { + checkEmpty() ; + *ptrValue=type.get() ; + } + + template + void CEnum_ref::set(const CEnum_ref& type) const + { + checkEmpty() ; + *ptrValue=type.get() ; + } + + template + typename T::t_enum & CEnum_ref::get(void) const + { + checkEmpty() ; + return *ptrValue ; + } + + template + const CEnum_ref& CEnum_ref::operator = (T_enum& val) const + { + set(val) ; + return *this ; + } + + template + const CEnum_ref& CEnum_ref::operator = (CEnum& type) const + { + set(type) ; + return *this ; + } + + template + const CEnum_ref& CEnum_ref::operator = (const CEnum_ref& type) const + { + set(type) ; + return *this ; + } + + template + CEnum_ref::operator T_enum&() const + { + checkEmpty() ; + return *ptrValue ; + } + + template + CEnum_ref* CEnum_ref::_clone(void) const + { + checkEmpty() ; + return new CEnum_ref(*this) ; + } + + template + void CEnum_ref::_fromString(const string& str) const + { + istringstream iss(str); + checkEmpty() ; + iss>>*ptrValue ; + } + + template + void CEnum_ref::_fromString(const string& str) + { + checkEmpty() ; + string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ; + + bool found=false ; + for(int i=0;i0) strList<<", " ; + strList< void CEnum_ref::_fromString(const string& str)", + << tmpStr << " cannot be converted in a valid enumeration, possibilities are : "< + string CEnum_ref::_toString(void) const + { + if (empty) return string("empty"); + return string((T::getStr())[(int)(*ptrValue)]) ; + } + + + template + bool CEnum_ref::_toBuffer(CBufferOut& buffer) const + { + checkEmpty() ; + if (sizeof(*ptrValue)==sizeof(short int)) return buffer.put((short int) *ptrValue) ; + else if (sizeof(*ptrValue)==sizeof(int)) return buffer.put((int) *ptrValue) ; + else if (sizeof(*ptrValue)==sizeof(long int)) return buffer.put((long int) *ptrValue) ; + else ERROR("template bool CEnum_ref::_toBuffer(CBufferOut& buffer) const", + <<"incompatibility between enumeration and standard integer type") ; + return false ; + } + + template + bool CEnum_ref::_fromBuffer(CBufferIn& buffer) + { + checkEmpty() ; + bool ret ; + if (sizeof(*ptrValue)==sizeof(short int)) + { + short int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else if (sizeof(*ptrValue)==sizeof(int)) + { + int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else if (sizeof(*ptrValue)==sizeof(long int)) + { + long int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else ERROR("template bool CEnum_ref::_fromBuffer(CBufferIn& buffer)", + <<"incompatibility between enumeration and standard integer type") ; + return ret ; + } + + template + bool CEnum_ref::_fromBuffer(CBufferIn& buffer) const + { + checkEmpty() ; + bool ret ; + if (sizeof(*ptrValue)==sizeof(short int)) + { + short int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else if (sizeof(*ptrValue)==sizeof(int)) + { + int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else if (sizeof(*ptrValue)==sizeof(long int)) + { + long int val ; + ret=buffer.get(val) ; + if (ret) *ptrValue = (T_enum) val ; + } + else ERROR("template bool CEnum_ref::_fromBuffer(CBufferIn& buffer)", + <<"incompatibility between enumeration and standard integer type") ; + } + + template + size_t CEnum_ref::_size(void) const + { + return sizeof(T_enum) ; + } + + template + bool CEnum_ref::_isEmpty(void) const + { + return empty ; + } + + template + void CEnum_ref::_reset(void) + { + empty=true ; + } + + template + void CEnum_ref::checkEmpty(void) const + { + if (empty) ERROR("template void CEnum_ref::checkEmpty(void)", + <<"Type_ref reference is not assigned") ; + } + + + + template + CBufferOut& operator<<(CBufferOut& buffer, const CEnum_ref& type) + { + if (!type.toBuffer(buffer)) ERROR("template CBufferOut& operator<<(CBufferOut& buffer, const CEnum_ref& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferOut& operator<<(CBufferOut& buffer, typename T::t_enum& type) + { + if (!CEnum_ref(type).toBuffer(buffer)) ERROR("template CBufferOut& operator<<(CBufferOut& buffer, const typename T::t_enum& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferIn& operator>>(CBufferIn& buffer, typename T::t_enum& type) + { + if (! CEnum_ref(type).fromBuffer(buffer)) ERROR("template CBufferIn& operator>>(CBufferIn& buffer, typename T::t_enum& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferIn& operator>>(CBufferIn& buffer, const CEnum_ref& type) + { + if (! type.fromBuffer(buffer) ) ERROR(" template CBufferIn& operator>>(CBufferIn& buffer, const CEnum_ref& type) ", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + +/* + template + CMessage& operator<<(CMessage& msg, const CEnum_ref& type) + { + msg.push(*type.clone()) ; + return msg ; + } +*/ + + template + CMessage& operator<<(CMessage& msg, typename T::t_enum & type) + { + msg.push(*CEnum_ref(type).clone()) ; + return msg ; + } + +} + +#endif + diff --git a/src/type/message.cpp b/src/type/message.cpp new file mode 100644 index 0000000000000000000000000000000000000000..adb9fa617c8668623d2c05988d24f7575fb203f9 --- /dev/null +++ b/src/type/message.cpp @@ -0,0 +1,105 @@ +#include "xmlioserver_spl.hpp" +#include "message.hpp" +#include "base_type.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" + +namespace xios +{ + + CMessage::CMessage(void) {} + + CMessage& CMessage::push(const CBaseType& type) + { + typeList.push_back(type.clone()); + return *this ; + } + +// CMessage& CMessage::push(CBaseType& type) +// { +// typeList.push_back(&type); +// return *this ; +// } + + size_t CMessage::size(void) const + { + list::const_iterator it; + size_t retSize=0 ; + + for(it=typeList.begin();it!=typeList.end();it++) retSize+=(*it)->size() ; + return retSize ; + } + + bool CMessage::fromBuffer(CBufferIn& buffer) const + { + list::const_iterator it; + + if (buffer.remain()>=size()) + { + for(it=typeList.begin();it!=typeList.end();it++) (*it)->fromBuffer(buffer) ; + return true ; + } + else + { + return false ; + } + } + + + bool CMessage::toBuffer(CBufferOut& buffer) const + { + list::const_iterator it; + if (buffer.remain()>=size()) + { + for(it=typeList.begin();it!=typeList.end();it++) (*it)->toBuffer(buffer) ; + return true ; + } + else + { + return false ; + } + + } + + + void CMessage::clear() + { + list::iterator it; + for(it=typeList.begin();it!=typeList.end();it++) delete *it ; + typeList.clear() ; + } + + CMessage::~CMessage() + { + clear() ; + } + + + CBufferOut& operator<<(CBufferOut& buffer, CMessage& msg) + { + if (!msg.toBuffer(buffer)) ERROR("CBufferOut& operator<<(CBufferOut& buffer, CMessage& msg)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + + CBufferIn& operator>>(CBufferIn& buffer, CMessage& msg) + { + if (!msg.fromBuffer(buffer)) ERROR("CBufferIn& operator>>(CBufferIn& buffer, CMessage& msg)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + CMessage& operator<<(CMessage& msg,const CBaseType& type) + { + msg.push(type) ; + return msg ; + } + +// CMessage& operator<<(CMessage& msg, const CBaseType& type) +// { +// msg.push(*type.clone()) ; +// return msg ; +// } + +} diff --git a/src/type/message.hpp b/src/type/message.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2d740365bee9f042f287b0e672ab1656f0e0eec9 --- /dev/null +++ b/src/type/message.hpp @@ -0,0 +1,39 @@ +#ifndef __MESSAGE_HPP__ +#define __MESSAGE_HPP__ + +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "base_type.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" + + +namespace xios +{ + + class CMessage + { + public: + + CMessage(void) ; + list typeList ; + virtual bool fromBuffer(CBufferIn& buffer) const; + virtual bool toBuffer(CBufferOut& buffer) const; + virtual size_t size(void) const; + + CMessage& push(const CBaseType& type) ; +// CMessage& push(CBaseType& type) ; + void clear(void) ; + ~CMessage() ; + } ; + + CBufferOut& operator<<(CBufferOut& buffer, CMessage& msg) ; + CBufferIn& operator>>(CBufferIn& buffer, CMessage& msg) ; + +// CMessage& operator<<(CMessage& msg,CBaseType& type) ; + CMessage& operator<<(CMessage& msg,const CBaseType& type) ; + +} + +#endif + diff --git a/src/type/type.hpp b/src/type/type.hpp new file mode 100644 index 0000000000000000000000000000000000000000..eac9e3f4e5cbeb20a20bd09b0202ae4d1edfcebb --- /dev/null +++ b/src/type/type.hpp @@ -0,0 +1,175 @@ +#ifndef __XIOS_TYPE__ +#define __XIOS_TYPE__ + +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "base_type.hpp" + + +namespace xios +{ + + template class CType_ref ; + + template + class CType : public virtual CBaseType + { + public: + + CType(void) ; + CType(const T& val) ; + CType(const CType& type) ; + CType(const CType_ref& type) ; + virtual ~CType() { _reset() ; } + + T& get(void) ; + const T& get(void) const; + + void set(const T& val) ; + void set(const CType& val) ; + void set(const CType_ref& val) ; + CType& operator = (const T& val) ; + CType& operator = (const CType& val) ; + CType& operator = (const CType_ref& val) ; + operator T&() ; + + inline virtual CBaseType* clone(void) const { return _clone(); } + virtual void fromString(const string& str) { _fromString(str); } + virtual string toString(void) const { return _toString(); } + virtual bool fromBuffer(CBufferIn& buffer) { return _fromBuffer(buffer) ; } + virtual bool toBuffer(CBufferOut& buffer) const { return _toBuffer(buffer); } + virtual void reset(void) { _reset(); } + virtual bool isEmpty() const { return _isEmpty(); } + virtual size_t size(void) const { return _size(); } + + void allocate(void) ; + void checkEmpty(void) const; + + T* ptrValue ; + bool empty ; + + friend class CType_ref ; + + private : + + CType* _clone(void) const; + void _fromString(const string& str) ; + string _toString(void) const; + bool _fromBuffer(CBufferIn& buffer) ; + bool _toBuffer(CBufferOut& buffer) const; + void _reset(void) ; + bool _isEmpty() const ; + size_t _size(void) const ; + + } ; + + + template class CType ; + + template + class CType_ref : public virtual CBaseType + { + public: + + CType_ref(void) ; + CType_ref(T& val) ; + CType_ref(CType& type) ; + CType_ref(const CType_ref& type) ; + virtual ~CType_ref() {}; + + T& get(void) const; + + void set(const T& val) const ; + void set(const CType& val) const ; + void set(const CType_ref& val) const ; + + void set_ref(T& val) ; + void set_ref(CType& val) ; + void set_ref(const CType_ref& val) ; + + const CType_ref& operator = (T& val) const ; + const CType_ref& operator = (CType& val) const ; + const CType_ref& operator = (const CType_ref& val) const; + operator T&() const; + + inline virtual CBaseType* clone(void) const { return _clone(); } + virtual void fromString(const string& str) { _fromString(str); } + virtual void fromString(const string& str) const { _fromString(str); } + virtual string toString(void) const { return _toString(); } + virtual bool fromBuffer(CBufferIn& buffer) { return _fromBuffer(buffer) ; } + virtual bool fromBuffer(CBufferIn& buffer) const { return _fromBuffer(buffer); } + virtual bool toBuffer(CBufferOut& buffer) const { return _toBuffer(buffer); } + virtual void reset(void) { _reset(); } + virtual bool isEmpty() const { return _isEmpty(); } + virtual size_t size(void) const { return _size(); } + + void checkEmpty(void) const; + + + T mutable * ptrValue ; + bool empty ; + friend class CType ; + + private : + + CType_ref* _clone(void) const; + void _fromString(const string& str) ; + void _fromString(const string& str) const; + string _toString(void) const; + bool _fromBuffer(CBufferIn& buffer) ; + bool _fromBuffer(CBufferIn& buffer) const ; + bool _toBuffer(CBufferOut& buffer) const; + void _reset(void) ; + bool _isEmpty() const ; + size_t _size(void) const ; + } ; + + + class CMessage ; + + template + CBufferOut& operator<<(CBufferOut& buffer, const CType& type) ; + + template + CBufferOut& operator<<(CBufferOut& buffer, const CType_ref& type) ; + + template + CBufferOut& operator<<(CBufferOut& buffer, const T& type) ; + + template + CBufferOut& operator<<(CBufferOut& buffer, T& type) ; + + + template + CBufferIn& operator>>(CBufferIn& buffer, CType& type) ; + + template + CBufferIn& operator>>(CBufferIn& buffer, const CType_ref& type) ; + + template + CBufferIn& operator>>(CBufferIn& buffer, T& type) ; + +/* + template + CMessage& operator<<(CMessage& msg, const CType& type) ; + + template + CMessage& operator<<(CMessage& msg, const CType_ref& type) ; +*/ + + template + CMessage& operator<<(CMessage& msg, const T& type) ; + + template + CMessage& operator<<(CMessage& msg, T& type) ; + +} + + +//#include "test_type_impl.hpp" +//#include "test_type_specialisation.hpp" + +#endif + diff --git a/src/type/type_decl.cpp b/src/type/type_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b48c56de6a8718b3e343d4b75bd8c7d4c7857869 --- /dev/null +++ b/src/type/type_decl.cpp @@ -0,0 +1,31 @@ +#include "type.hpp" +#include "type_impl.hpp" +#include "type_ref_impl.hpp" +#include "type_specialisation.hpp" +#include ; +#include "xmlioserver_spl.hpp" + +namespace xios +{ +#define macro(decl_type) \ + template class CType ; \ + template class CType_ref ; \ + template CBufferOut& operator<< (CBufferOut& buffer, const CType& type) ; \ + template CBufferOut& operator<< (CBufferOut& buffer, const CType_ref& type) ; \ + template CBufferOut& operator<< (CBufferOut& buffer, decl_type& type) ; \ + template CBufferOut& operator<< (CBufferOut& buffer, const decl_type& type) ; \ + template CBufferIn& operator>> (CBufferIn& buffer, CType& type) ; \ + template CBufferIn& operator>> (CBufferIn& buffer, const CType_ref& type) ; \ + template CBufferIn& operator>> (CBufferIn& buffer, decl_type& type) ; \ +/* template CMessage& operator<< (CMessage& msg, const CType& type) ;*/ \ +/* template CMessage& operator<< (CMessage& msg, const CType_ref& type) ;*/ \ + template CMessage& operator<< (CMessage& msg, const decl_type& type) ; \ + template CMessage& operator<< (CMessage& msg, decl_type& type) ; + + macro(string) + macro(int) + macro(double) + macro(bool) + macro(StdSize) + +} diff --git a/src/type/type_impl.hpp b/src/type/type_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..be936d5eb620fe3446105496e50c8d221f48e2c9 --- /dev/null +++ b/src/type/type_impl.hpp @@ -0,0 +1,249 @@ +#ifndef __XIOS_TYPE_IMPL__ +#define __XIOS_TYPE_IMPL__ + +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "message.hpp" + + + + +namespace xios +{ + + using namespace std; + + template + CType::CType(void) + { + empty=true ; + } + + template + CType::CType(const T& val) + { + empty=true ; + set(val) ; + } + + template + CType::CType(const CType& type) + { + empty=true ; + set(type) ; + } + + template + CType::CType(const CType_ref& type) + { + empty=true ; + set(type) ; + } + + template + void CType::set(const T& val) + { + if (empty) + { + ptrValue = new T(val) ; + empty=false ; + } + else *ptrValue = val ; + } + + template + void CType::set(const CType& type) + { + if (type.isEmpty()) reset() ; + else + { + if (empty) + { + ptrValue = new T(*type.ptrValue) ; + empty=false ; + } + else *ptrValue = *type.ptrValue ; + } + } + + template + void CType::set(const CType_ref& type) + { + if (type.isEmpty()) reset() ; + else + { + if (empty) + { + ptrValue = new T(*type.ptrValue) ; + empty=false ; + } + else *ptrValue = *type.ptrValue ; + } + } + + template + T& CType::get(void) + { + checkEmpty(); + return *ptrValue ; + } + + template + const T& CType::get(void) const + { + checkEmpty(); + return *ptrValue ; + } + + template + CType& CType::operator = (const T& val) + { + set(val) ; + return *this ; + } + + template + CType& CType::operator = (const CType& type) + { + set(type) ; + return *this ; + } + + template + CType& CType::operator = (const CType_ref& type) + { + set(type) ; + return *this ; + } + + template + CType::operator T&() + { + checkEmpty(); + return *ptrValue ; + } + + template + CType* CType::_clone(void) const + { + checkEmpty(); + return new CType(*this) ; + } + + + template + void CType::_fromString(const string& str) + { + istringstream iss(str); + allocate() ; + iss>>*ptrValue ; + } + + template + size_t CType::_size(void) const + { + return sizeof(T) ; + } + + template + bool CType::_isEmpty(void) const + { + return empty ; + } + + template + string CType::_toString(void) const + { + ostringstream oss; + checkEmpty(); + oss<<*ptrValue ; + return oss.str() ; + } + + template + bool CType::_toBuffer(CBufferOut& buffer) const + { + checkEmpty(); + return buffer.put(*ptrValue) ; + } + + template + bool CType::_fromBuffer(CBufferIn& buffer) + { + allocate() ; + return buffer.get(*ptrValue) ; + } + + + template + void CType::allocate(void) + { + if (empty) + { + ptrValue = new T ; + empty=false ; + } + } + + template + void CType::_reset(void) + { + if (!empty) + { + delete ptrValue ; + empty=true ; + } + } + + template + void CType::checkEmpty(void) const + { + if (empty) ERROR("template void CTypef::checkEmpty(void) const", <<"Type is not initialized") ; + } + + + template + CBufferOut& operator<<(CBufferOut& buffer, const CType& type) + { + if (!type.toBuffer(buffer)) ERROR("CBuffer& operator<<(CBuffer& buffer, CType& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + + template + CBufferOut& operator<<(CBufferOut& buffer, const T& type) + { + if (!CType(type).toBuffer(buffer)) ERROR("operator<<(CBuffer& buffer, const T& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferIn& operator>>(CBufferIn& buffer, CType& type) + { + if (! type.fromBuffer(buffer)) ERROR("CBuffer& operator<<(CBuffer& buffer, CType& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + +/* + template + CMessage& operator<<(CMessage& msg, const CType& type) + { + msg.push(*type.clone()) ; + return msg ; + } +*/ + template + CMessage& operator<<(CMessage& msg, const T& type) + { + msg.push(CType(type)) ; + return msg ; + } + +} + +#endif diff --git a/src/type/type_ref_impl.hpp b/src/type/type_ref_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..07977bf485029d79cb2eb9b45e7723b6ec191515 --- /dev/null +++ b/src/type/type_ref_impl.hpp @@ -0,0 +1,256 @@ + +#ifndef __XIOS_TYPE_REF_IMPL__ +#define __XIOS_TYPE_REF_IMPL__ + +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "message.hpp" +#include "type.hpp" + + + +namespace xios +{ + + using namespace std; + + template + CType_ref::CType_ref(void) + { + empty=true ; + } + + template + CType_ref::CType_ref(T& val) + { + empty=true ; + set_ref(val) ; + } + + template + CType_ref::CType_ref(CType& type) + { + empty=true ; + set_ref(type) ; + } + + template + CType_ref::CType_ref(const CType_ref& type) + { + empty=true ; + set_ref(type) ; + } + + + template + void CType_ref::set_ref(T& val) + { + ptrValue=&val ; + empty=false ; + } + + template + void CType_ref::set_ref(CType& type) + { + ptrValue=&type.get() ; + empty=false ; + } + + template + void CType_ref::set_ref(const CType_ref& type) + { + ptrValue=type.ptrValue ; + empty=type.empty ; + } + + template + void CType_ref::set(const T& val) const + { + checkEmpty() ; + *ptrValue=val ; + } + + template + void CType_ref::set(const CType& type) const + { + checkEmpty() ; + *ptrValue=type.get() ; + } + + template + void CType_ref::set(const CType_ref& type) const + { + checkEmpty() ; + *ptrValue=type.get() ; + } + + template + T& CType_ref::get(void) const + { + checkEmpty() ; + return *ptrValue ; + } + + template + const CType_ref& CType_ref::operator = (T& val) const + { + set(val) ; + return *this ; + } + + template + const CType_ref& CType_ref::operator = (CType& type) const + { + set(type) ; + return *this ; + } + + template + const CType_ref& CType_ref::operator = (const CType_ref& type) const + { + set(type) ; + return *this ; + } + + template + CType_ref::operator T&() const + { + checkEmpty() ; + return *ptrValue ; + } + + template + CType_ref* CType_ref::_clone(void) const + { + checkEmpty() ; + return new CType_ref(*this) ; + } + + template + void CType_ref::_fromString(const string& str) const + { + istringstream iss(str); + checkEmpty() ; + iss>>*ptrValue ; + } + + template + void CType_ref::_fromString(const string& str) + { + istringstream iss(str); + checkEmpty() ; + iss>>*ptrValue ; + } + + template + string CType_ref::_toString(void) const + { + ostringstream oss; + checkEmpty() ; + oss<<*ptrValue ; + return oss.str() ; + } + + + template + bool CType_ref::_toBuffer(CBufferOut& buffer) const + { + checkEmpty() ; + return buffer.put(*ptrValue) ; + } + + template + bool CType_ref::_fromBuffer(CBufferIn& buffer) + { + checkEmpty() ; + return buffer.get(*ptrValue) ; + } + + template + bool CType_ref::_fromBuffer(CBufferIn& buffer) const + { + checkEmpty() ; + return buffer.get(*ptrValue) ; + } + + template + size_t CType_ref::_size(void) const + { + return sizeof(T) ; + } + + template + bool CType_ref::_isEmpty(void) const + { + return empty ; + } + + template + void CType_ref::_reset(void) + { + empty=true ; + } + + template + void CType_ref::checkEmpty(void) const + { + if (empty) ERROR("template void CType_ref::checkEmpty(void)", + <<"Type_ref reference is not assigned") ; + } + + + + template + CBufferOut& operator<<(CBufferOut& buffer, const CType_ref& type) + { + if (!type.toBuffer(buffer)) ERROR("CBuffer& operator<<(CBuffer& buffer, CType& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferOut& operator<<(CBufferOut& buffer, T& type) + { + if (!CType_ref(type).toBuffer(buffer)) ERROR("CBufferOut& operator<<(CBufferOut& buffer, T& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferIn& operator>>(CBufferIn& buffer, T& type) + { + if (! CType_ref(type).fromBuffer(buffer)) ERROR(" template CBufferIn& operator>>(CBufferIn& buffer, T& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + template + CBufferIn& operator>>(CBufferIn& buffer, const CType_ref& type) + { + if (! type.fromBuffer(buffer) ) ERROR("CBuffer& operator<<(CBuffer& buffer, CType& type)", + <<"Buffer remain size is to low for size type") ; + return buffer ; + } + + +/* + template + CMessage& operator<<(CMessage& msg, const CType_ref& type) + { + msg.push(type) ; + return msg ; + } +*/ + + template + CMessage& operator<<(CMessage& msg, T& type) + { + msg.push(CType_ref(type)) ; + return msg ; + } + +} + +#endif diff --git a/src/type/type_specialisation.hpp b/src/type/type_specialisation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d9cae9d9c15c55e458e0e51e3d55a197e678b8c1 --- /dev/null +++ b/src/type/type_specialisation.hpp @@ -0,0 +1,317 @@ +#ifndef __XIOS_TYPE_SPECIALISATION_HPP__ +#define __XIOS_TYPE_SPECIALISATION_HPP__ + +#include "xmlioserver_spl.hpp" +#include "exception.hpp" +#include "buffer_in.hpp" +#include "buffer_out.hpp" +#include "type.hpp" +#include +#include + +namespace xios +{ + +// template specialization for bool + + template <> void CType::_fromString(const string& str) + { + string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ; + if (tmpStr=="true" || tmpStr==".true." || tmpStr=="yes" || tmpStr=="y") set(true) ; + else if (tmpStr=="false" || tmpStr==".false." || tmpStr=="no" || tmpStr=="n") set(false) ; + else ERROR("template <> CType::fromString(const string& str)",<< tmpStr << " cannot be converted in a boolean value") ; + } + + template <> string CType::_toString(void) const + { + if (get()) return string("true") ; + else return string("false") ; + } + + template <> void CType_ref::_fromString(const string& str) const + { + string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ; + if (tmpStr=="true" || tmpStr==".true." || tmpStr=="yes" || tmpStr=="y") set(true) ; + else if (tmpStr=="false" || tmpStr==".false." || tmpStr=="no" || tmpStr=="n") set(false) ; + else ERROR("template <> CType::fromString(const string& str)",<< tmpStr << " cannot be converted in a boolean value") ; + } + + template <> void CType_ref::_fromString(const string& str) + { + string tmpStr=boost::to_lower_copy(boost::trim_copy(str)) ; + if (tmpStr=="true" || tmpStr==".true." || tmpStr=="yes" || tmpStr=="y") set(true) ; + else if (tmpStr=="false" || tmpStr==".false." || tmpStr=="no" || tmpStr=="n") set(false) ; + else ERROR("template <> CType::fromString(const string& str)",<< tmpStr << " cannot be converted in a boolean value") ; + } + + template <> string CType_ref::_toString(void) const + { + if (get()) return string("true") ; + else return string("false") ; + } + +// template specialization for string + + template <> + size_t CType::_size() const + { + size_t typeSize=0 ; + typeSize+=sizeof(size_t) ; + typeSize+=ptrValue->size() ; + return typeSize ; + } + + template <> + size_t CType_ref::_size() const + { + size_t typeSize=0 ; + typeSize+=sizeof(size_t) ; + typeSize+=ptrValue->size() ; + return typeSize ; + } + + template <> + void CType::_fromString(const string& str) + { + allocate() ; + *ptrValue=str ; + } + + template <> + void CType_ref::_fromString(const string& str) + { + checkEmpty() ; + *ptrValue=str ; + } + + template <> + void CType_ref::_fromString(const string& str) const + { + checkEmpty() ; + *ptrValue=str ; + } + + template <> + bool CType::_toBuffer(CBufferOut& buffer) const + { + if (buffer.remain()size()) ; + if (ret) ret&=buffer.put(ptrValue->data(),ptrValue->size()) ; + return ret ; + } + } + + template <> + bool CType_ref::_toBuffer(CBufferOut& buffer) const + { + if (buffer.remain()size()) ; + if (ret) ret&=buffer.put(ptrValue->data(),ptrValue->size()) ; + return ret ; + } + } + + + + template <> + bool CType::_fromBuffer(CBufferIn& buffer) + { + allocate() ; + bool ret=true ; + size_t typeSize ; + if (ret) ret&=buffer.get(typeSize) ; + + char* str; + str= (char*) buffer.ptr() ; + if (ret) buffer.advance(typeSize) ; + if (ret) *ptrValue=string(str,typeSize) ; + + return ret ; + } + + template <> + bool CType_ref::_fromBuffer(CBufferIn& buffer) const + { + bool ret=true ; + size_t typeSize ; + if (ret) ret&=buffer.get(typeSize) ; + + char* str; + str= (char*) buffer.ptr() ; + if (ret) buffer.advance(typeSize) ; + if (ret) *ptrValue=string(str,typeSize) ; + + return ret ; + } + + template <> + bool CType_ref::_fromBuffer(CBufferIn& buffer) + { + bool ret=true ; + size_t typeSize ; + if (ret) ret&=buffer.get(typeSize) ; + + char* str; + str= (char*) buffer.ptr() ; + if (ret) buffer.advance(typeSize) ; + if (ret) *ptrValue=string(str,typeSize) ; + + return ret ; + } + // template specialisation for CArray +/* + template<> + size_t CType< ARRAY(int, 1)>::size() const + { + return (*(this->ptrValue))->getSize() ; + } + + template <> + bool CType::toBuffer(CBufferOut& buffer) const + { + return (*(this->ptrValue))->toBuffer(buffer) ; + } + + template <> + bool CType::fromBuffer(CBufferIn& buffer) const + { + return (*(this->ptrValue))->fromBuffer(buffer) ; + } + + template <> + void CType::fromString(const string& str) const + { + // to implement + } + + template <> + string CType::toString(void) const + { + // to implement + return string("") ; + + } +*/ + + +/* +template +boost::detail::multi_array::extent_gen getExtentNull(void) { return getExtentNull()[0];} + +template<> +boost::detail::multi_array::extent_gen<1> getExtentNull<1>(void) { return extents[0]; } +*/ +/* +#define CTYPE_ARRAY(ValueType,NumsDims) \ + \ + template <> \ + void CType::allocate(void) \ + { \ + if (empty) ptrValue=new shared_ptr >(new CArray()) ;\ + empty=false ; \ + } \ + \ + template<> \ + size_t CType< ARRAY(ValueType,NumsDims)>::_size() const \ + { \ + return (*(this->ptrValue))->getSize() ; \ + } \ + \ + template<> \ + size_t CType_ref< ARRAY(ValueType,NumsDims)>::_size() const \ + { \ + return (*(this->ptrValue))->getSize() ; \ + } \ + \ + template <> \ + bool CType::_toBuffer(CBufferOut& buffer) const \ + { \ + return (*(this->ptrValue))->toBuffer(buffer) ; \ + } \ + \ + template <> \ + bool CType_ref::_toBuffer(CBufferOut& buffer) const \ + { \ + return (*(this->ptrValue))->toBuffer(buffer) ; \ + } \ + \ + template <> \ + bool CType::_fromBuffer(CBufferIn& buffer) \ + { \ + allocate(); \ + return (*(ptrValue))->fromBuffer(buffer) ; \ + } \ + \ + template <> \ + bool CType_ref::_fromBuffer(CBufferIn& buffer) const \ + { \ + checkEmpty() ; \ + return (*(this->ptrValue))->fromBuffer(buffer) ; \ + } \ + \ + template <> \ + bool CType_ref::_fromBuffer(CBufferIn& buffer) \ + { \ + shared_ptr > tmp(new CArray() ) ; \ + *(this->ptrValue)=tmp ;\ + return (*(this->ptrValue))->fromBuffer(buffer) ; \ + } \ + \ + \ + template <> \ + void CType::_fromString(const string& str) \ + { \ + \ + } \ + \ + template <> \ + void CType_ref::_fromString(const string& str) const \ + { \ + \ + } \ + template <> \ + void CType_ref::_fromString(const string& str) \ + { \ + \ + } \ + \ + template <> \ + string CType::_toString(void) const \ + { \ + \ + return string("") ; \ + } \ + \ + template <> \ + string CType_ref::_toString(void) const \ + { \ + \ + return string("") ; \ + } +//CTYPE_ARRAY(double,1) + +//CTYPE_ARRAY(double,2) + + +CTYPE_ARRAY(int,1) +CTYPE_ARRAY(int,2) +CTYPE_ARRAY(int,3) +CTYPE_ARRAY(bool,1) +CTYPE_ARRAY(bool,2) +CTYPE_ARRAY(bool,3) +CTYPE_ARRAY(double,1) +CTYPE_ARRAY(double,2) +CTYPE_ARRAY(double,3) +CTYPE_ARRAY(float,1) +CTYPE_ARRAY(float,2) +CTYPE_ARRAY(float,3) +*/ +} + +#endif diff --git a/src/type/type_util.hpp b/src/type/type_util.hpp new file mode 100644 index 0000000000000000000000000000000000000000..837023be6235e475bfb09b051f2dc8bfb79291d3 --- /dev/null +++ b/src/type/type_util.hpp @@ -0,0 +1,63 @@ +#ifndef __TYPE_UTIL_HPP__ +#define __TYPE_UTIL_HPP__ + +#include +namespace xios +{ + class CDomain ; + class CDomainGroup; + class CField; + class CFieldGroup; + class CGrid; + class CGridGroup; + class CAxis; + class CAxisGroup; + class CFile; + class CFileGroup; + class CContext; + class CContextGroup; + class CVariable ; + class CVariableGroup ; + + template inline string getStrType(void) ; + +#define macro(T) template <> inline string getStrType(void) { return std::string(#T) ; } + + macro(short) + macro(unsigned short) + macro(int) + macro(unsigned int) + macro(long) + macro(unsigned long) + macro(float) + macro(double) + macro(long double) + macro(char) + macro(unsigned char) + macro(wchar_t) + macro(bool) +#undef macro + +#define macro(T) template <> inline string getStrType(void) { return std::string(#T) ; } + macro(CDomain) + macro(CDomainGroup) + macro(CField) + macro(CFieldGroup) + macro(CGrid) + macro(CGridGroup) + macro(CAxis) + macro(CAxisGroup) + macro(CFile) + macro(CFileGroup) + macro(CContext) + macro(CContextGroup) + macro(CVariable) + macro(CVariableGroup) + + +#undef macro + +} + + +#endif diff --git a/src/wait.f90 b/src/wait.f90 new file mode 100644 index 0000000000000000000000000000000000000000..87ffac6f2e6c370acb4994aa0b774e9391598ad6 --- /dev/null +++ b/src/wait.f90 @@ -0,0 +1,68 @@ +MODULE mod_wait + INTEGER, SAVE :: wait_param=10 + REAL, SAVE :: opt_param + + + INTEGER, SAVE :: last_count + +CONTAINS + + + FUNCTION Top() + IMPLICIT NONE + DOUBLE PRECISION :: Top + INTEGER :: count,count_rate,count_max + LOGICAL, SAVE :: first=.TRUE. + + + CALL system_clock(count,count_rate,count_max) + IF (first) THEN + Top=0. + ELSE + IF (Count>=Last_Count) THEN + Top=(1.*(Count-last_Count))/count_rate + ELSE + Top=(1.*(Count-last_Count+Count_max))/count_rate + ENDIF + ENDIF + Last_Count=Count + first=.FALSE. + END FUNCTION Top + + SUBROUTINE Init_wait + IMPLICIT NONE + INTEGER :: i,j + LOGICAL :: out_ok + DOUBLE PRECISION :: time + INTEGER :: last_param + + out_ok=.FALSE. + + DO WHILE (.NOT. out_ok) + opt_param=0. + + time=top() +!CDIR NOVECTOR + DO i=1,1000000*wait_param + opt_param=opt_param+(i/(i+opt_param)) + ENDDO + time=top() + last_param=wait_param + wait_param=wait_param*(1./time) + IF (ABS(wait_param-last_param)/(0.5*(wait_param+last_param)) <0.01) out_ok=.TRUE. + END DO + END SUBROUTINE Init_wait + + SUBROUTINE Wait_us(n) + IMPLICIT NONE + INTEGER :: n + INTEGER :: i + +!CDIR NOVECTOR + DO i=1,n*wait_param + opt_param=opt_param+(i/(i+opt_param)) + ENDDO + + END SUBROUTINE Wait_us + +END MODULE mod_wait diff --git a/src/xios_server.f90 b/src/xios_server.f90 new file mode 100644 index 0000000000000000000000000000000000000000..09180f57ac5d4dda531988ae7f3c77dc6f098e91 --- /dev/null +++ b/src/xios_server.f90 @@ -0,0 +1,9 @@ +PROGRAM server_main + USE xios + IMPLICIT NONE + INCLUDE "mpif.h" + INTEGER :: ierr + + CALL xios_init_server + + END PROGRAM server_main diff --git a/src/xml_node.cpp b/src/xml_node.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0168d6561c8469c41b1da7dc8ae9efe6e61a8ab --- /dev/null +++ b/src/xml_node.cpp @@ -0,0 +1,101 @@ +#include "xml_node.hpp" + +namespace xios +{ + namespace xml + { + /// ////////////////////// Définitions ////////////////////// /// + + StdString CXMLNode::RootName("simulation"); + + CXMLNode::CXMLNode(rapidxml::xml_node * const root) + : node(root) + , level(0) + { /* Ne rien faire de plus */ } + + CXMLNode::~CXMLNode(void) + { /* Ne rien faire de plus */ } + + StdString CXMLNode::getElementName(void) const + { + return (this->node->name()); + } + + bool CXMLNode::goToNextElement(void) + { + bool retvalue = false; + for(rapidxml::xml_node * nextElement = this->node->next_sibling(); + ; nextElement = this->node->next_sibling()) + { + if (nextElement == NULL) break; + else if (nextElement->type() == rapidxml::node_element) + { + node = nextElement; + return (!retvalue); + } + } + return (retvalue); + } + + bool CXMLNode::goToChildElement(void) + { + bool retvalue = false; + rapidxml::xml_node * nextElement = this->node->first_node(); + if (nextElement != NULL) + { + for(;;nextElement = this->node->next_sibling()) + { + if (nextElement == NULL) break; + else if (nextElement->type() == rapidxml::node_element) + { + node = nextElement; + level++; + return (!retvalue); + } + } + } + return (retvalue); + } + + bool CXMLNode::goToParentElement(void) + { + bool retvalue = false; + if (!(this->getElementName().compare(CXMLNode::RootName)) || (level == 0)) + return (retvalue); + node = node->parent(); + level--; + return (!retvalue); + } + + bool CXMLNode::getContent(StdString & content) + { + if (this->node->value_size() == 0) return (false); + content.assign(this->node->value(), this->node->value_size()); + return (true); + } + + const StdString & CXMLNode::GetRootName(void) + { + return (CXMLNode::RootName); + } + + THashAttributes CXMLNode::getAttributes(void) const + { + THashAttributes attributes; + rapidxml::xml_attribute *currentAttr = NULL; + + if ((currentAttr = this->node->first_attribute()) != NULL) + { + do + { + attributes.insert(std::pair + (StdString(currentAttr->name()), + StdString(currentAttr->value()))); + } while ((currentAttr = currentAttr->next_attribute()) != NULL); + } + + return (attributes) ; + } + + }// namespace xml +} // namespace xmlioserve diff --git a/src/xml_node.hpp b/src/xml_node.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3c5bbbe3ecb08f22a1a7c55c1dd015d8d4e27de1 --- /dev/null +++ b/src/xml_node.hpp @@ -0,0 +1,57 @@ +#ifndef __XMLIO_CXMLNode__ +#define __XMLIO_CXMLNode__ + +/// rapidXML headers /// +#include + +/// xios headers /// +#include "xmlioserver_spl.hpp" + +namespace xios +{ + namespace xml + { + /// ////////////////////// Déclarations ////////////////////// /// + typedef xios_map THashAttributes; + + class CXMLNode + { + public : + + /// Constructeurs /// + CXMLNode(rapidxml::xml_node * const root); + + /// Destructeur /// + ~CXMLNode(void); + + /// Accesseurs /// + StdString getElementName(void) const; + THashAttributes getAttributes(void) const; + + /// Mutateurs /// + bool goToNextElement(void); + bool goToChildElement(void); + bool goToParentElement(void); + bool getContent(StdString & content); + + /// Accesseurs statiques /// + static const StdString & GetRootName(void); + + private : + + /// Constructeurs /// + CXMLNode(void); // Not implemented yet. + CXMLNode(const CXMLNode & node); // Not implemented yet. + CXMLNode(const CXMLNode * const node); // Not implemented yet. + + rapidxml::xml_node * node; + int level; + + static StdString RootName; + + }; //class CXMLParser + + }// namespace xml +} // namespace xios + +#endif // __XMLIO_CXMLNode__ diff --git a/src/xml_parser.cpp b/src/xml_parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7c9d1b8e773a12c38bf5257af61ec64edddba7f --- /dev/null +++ b/src/xml_parser.cpp @@ -0,0 +1,109 @@ +#include "xml_parser.hpp" + +#include "context.hpp" + +#include "attribute_template.hpp" +#include "object_template.hpp" +#include "group_template.hpp" + +namespace xios +{ + namespace xml + { + /// ////////////////////// Définitions ////////////////////// /// + + void CXMLParser::ParseFile(const StdString & filename) + { + StdIFStream ifs ( filename.c_str() , StdIFStream::in ); + if ( (ifs.rdstate() & std::ifstream::failbit ) != 0 ) + ERROR("void CXMLParser::ParseFile(const StdString & filename)", + < file" ); + + CXMLParser::ParseStream(ifs, filename); + } + + void CXMLParser::ParseString(const StdString & xmlContent) + { + StdIStringStream iss ( xmlContent /*, StdIStringStream::in*/ ); + CXMLParser::ParseStream(iss,"string"); + } + + void CXMLParser::ParseStream(StdIStream & stream, const string& fluxId) + { + if (!stream.good()) + ERROR("CXMLParser::ParseStream(const StdIStream & stream)", + << "Bad xml stream !"); + StdOStringStream oss; + while(!stream.eof() && !stream.fail ()) oss.put(stream.get()); + const StdString xmlcontent( oss.str(), 0, oss.str().size()-1 ); + try + { + rapidxml::xml_document doc; + doc.parse<0>(const_cast(xmlcontent.c_str())); + + CXMLNode node(doc.first_node()); + THashAttributes attributes; + + if (node.getElementName().compare(CXMLNode::GetRootName()) != 0) + ERROR("CXMLParser::ParseStream(StdIStream & stream)", + << "Root element should be named simulation (actual = \'" + << node.getElementName() << "\')!"); + + if (node.goToChildElement()) + { + do + { + CContextGroup* group_context = CContext::getRoot() ; + + attributes = node.getAttributes(); + + if (attributes.end() == attributes.find("id")) + { + DEBUG("The context will not be processed because it is not identified (missing id)"); + continue; + } + + CContext::setCurrent(attributes["id"]) ; + + bool hasctxt = CContext::has(attributes["id"]); + + if(hasctxt) + { + DEBUG("The context will not be processed because it exist an other context with the same id" ); + continue; + } + + CContext* context = CContext::create(attributes["id"]); +// if (!hasctxt) group_context->addChild(context); + context->parse(node); + + attributes.clear(); + + } while (node.goToNextElement()); + } + } + catch (rapidxml::parse_error & exc) + { + const char* ptr = exc.where() ; + const char* begin = xmlcontent.c_str() ; + const char* content=oss.str().c_str() ; + size_t pos=ptr-begin ; + int lineNumber = 1 ; + int columnNumber = 0 ; + const char* line; + const char* endLine; + + for(const char* i=content;i at character "<< pos<<" line "< + static void ParseInclude(StdIStream & stream, const string& fluxId, T & object); + + }; //class CXMLParser +/* + template + void CXMLParser::ParseInclude(StdIStream & stream, T& object) + { + StdOStringStream oss; + while(!stream.eof() && !stream.fail ()) + oss.put(stream.get()); + try + { + const StdString xmlcontent( oss.str(), 0, oss.str().size()-1 ); + rapidxml::xml_document doc; + doc.parse<0>(const_cast(xmlcontent.c_str())); + CXMLNode node(doc.first_node()); + object.parse(node); + } + catch (rapidxml::parse_error & exc) + { + ERROR("CXMLParser::ParseStream(StdIStream & stream)", + << "RapidXML error : " << exc.what() << " !"); + } + } +*/ + }// namespace xml +} // namespace xios + +#endif // __XMLIO_CXMLParser__ diff --git a/src/xml_parser_decl.cpp b/src/xml_parser_decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c3821e511d691e8180201f6037d10123f86328c --- /dev/null +++ b/src/xml_parser_decl.cpp @@ -0,0 +1,28 @@ +#include "xml_parser_impl.hpp" +#include "group_template.hpp" +#include "context.hpp" +#include "axis.hpp" +#include "domain.hpp" +#include "field.hpp" +#include "file.hpp" +#include "variable.hpp" + + +namespace xios +{ + namespace xml + { + template void CXMLParser::ParseInclude(StdIStream & stream, const string& fluxId, CContext& object) ; + + # define macro(T) \ + template void CXMLParser::ParseInclude< CGroupTemplate >(StdIStream & stream, const string& fluxId, CGroupTemplate& object) ; + + macro( Context ) + macro( Axis ) + macro( Domain ) + macro( Grid ) + macro( Field ) + macro( File ) + macro( Variable ) + } +} diff --git a/src/xml_parser_impl.hpp b/src/xml_parser_impl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..46386598d19e5cd5ab3cb2cde9d14068695768c9 --- /dev/null +++ b/src/xml_parser_impl.hpp @@ -0,0 +1,50 @@ +#ifndef __XMLIO_CXML_PARSER_IMPL__ +#define __XMLIO_CXML_PARSER_IMPL__ + +/// xios headers /// +#include "xml_parser.hpp" + +namespace xios +{ + namespace xml + { + template void CXMLParser::ParseInclude(StdIStream & stream, const string& fluxId, T& object) + { + StdOStringStream oss; + while(!stream.eof() && !stream.fail ()) oss.put(stream.get()); + const StdString xmlcontent( oss.str(), 0, oss.str().size()-1 ); + try + { + rapidxml::xml_document doc; + doc.parse<0>(const_cast(xmlcontent.c_str())); + CXMLNode node(doc.first_node()); + object.parse(node); + } + catch (rapidxml::parse_error & exc) + { + const char* ptr = exc.where() ; + const char* begin = xmlcontent.c_str() ; + const char* content=oss.str().c_str() ; + size_t pos=ptr-begin ; + int lineNumber = 1 ; + int columnNumber = 0 ; + const char* line; + const char* endLine; + + for(const char* i=content;i at character "<< pos<<" line "< +#include +#include + +// standard C +#include +#include +#include +#include + +// Conteneurs. +#include +#include +#include +#include +#include +#include +#include +#include +// Flux. +#include +#include +#include + +/// boost headers /// +//#include +#include +#include +/// Map /// +#define xios_map std::map + +/// Macro /// +#define UNUSED(parameter) + +/// Définition de types (issus de la bibliothèque standard)/// +typedef std::ostringstream StdOStringStream; +typedef std::istringstream StdIStringStream; +typedef std::stringstream StdStringStream; +typedef std::ofstream StdOFStream; +typedef std::ifstream StdIFStream; +typedef std::ostream StdOStream; +typedef std::istream StdIStream; +typedef std::string StdString; +typedef std::size_t StdSize; + +typedef unsigned short int ushort; +typedef unsigned int uint; +typedef unsigned long int ulong; + +/// xios headers /// +#include "configure.hpp" +#include "log.hpp" +using namespace std; +using namespace boost ; + + +#endif //__XMLIO_SPL__ diff --git a/tools/archive/FCM.tar.gz b/tools/archive/FCM.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..bca900a68c45bc9e1d99d8b8654a8e086e708820 Binary files /dev/null and b/tools/archive/FCM.tar.gz differ diff --git a/tools/archive/blitz.tar.gz b/tools/archive/blitz.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3ad364bc1c262a189246fc1190ab60e9dba9202f Binary files /dev/null and b/tools/archive/blitz.tar.gz differ diff --git a/tools/archive/boost.tar.gz b/tools/archive/boost.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..13f57cd560eb68e1b8281d43120f7c1e58395dd8 Binary files /dev/null and b/tools/archive/boost.tar.gz differ diff --git a/tools/archive/rapidxml.tar.gz b/tools/archive/rapidxml.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..cd55cf0fb6fd3cd184426d213ab5746aa868f26b Binary files /dev/null and b/tools/archive/rapidxml.tar.gz differ