code: def read_data_block(darray, fname, data, mmap):
      """Parses data from a <Data> element, or loads from an external file.
  
      Parameters
      ----------
      darray : GiftiDataArray
           GiftiDataArray object representing the parent <DataArray> of this
           <Data> element
  
      fname : str or None
           Name of GIFTI file being loaded, or None if in-memory
  
      data : str or None
           Data to parse, or None if data is in an external file
  
      mmap : {True, False, 'c', 'r', 'r+'}
          Controls the use of numpy memory mapping for reading data.  Only has
          an effect when loading GIFTI images with data stored in external files
          (``DataArray`` elements with an ``Encoding`` equal to
          ``ExternalFileBinary``).  If ``False``, do not try numpy ``memmap``
          for data array.  If one of ``{'c', 'r', 'r+'}``, try numpy ``memmap``
          with ``mode=mmap``.  A `mmap` value of ``True`` gives the same
          behavior as ``mmap='c'``.  If the file cannot be memory-mapped, ignore
          `mmap` value and read array from file.
  
      Returns
      -------
      ``numpy.ndarray`` or ``numpy.memmap`` containing the parsed data
      """
      if mmap not in (True, False, "c", "r", "r+"):
          raise ValueError(
              "mmap value should be one of True, False, 'c', 'r', 'r+'"
          )
      if mmap is True:
          mmap = "c"
      enclabel = gifti_encoding_codes.label[darray.encoding]
      dtype = data_type_codes.type[darray.datatype]
  
      if enclabel == "ASCII":
          # GIFTI_ENCODING_ASCII
          c = StringIO(data)
          da = np.loadtxt(c, dtype=dtype)
          return da  # independent of the endianness
      elif enclabel not in ("B64BIN", "B64GZ", "External"):
          return 0
  
      # GIFTI_ENCODING_EXTBIN
      # We assume that the external data file is raw uncompressed binary, with
      # the data type/endianness/ordering specified by the other DataArray
      # attributes
      if enclabel == "External":
          if fname is None:
              raise GiftiParseError(
                  "ExternalFileBinary is not supported when loading from in-memory XML"
              )
          ext_fname = op.join(op.dirname(fname), darray.ext_fname)
          if not op.exists(ext_fname):
              raise GiftiParseError(
                  "Cannot locate external file " + ext_fname
              )
          # We either create a memmap, or load into memory
          newarr = None
          if mmap:
              try:
                  newarr = np.memmap(
                      ext_fname,
                      dtype=dtype,
                      mode=mmap,
                      offset=darray.ext_offset,
                      shape=tuple(darray.dims),
                  )
              # If the memmap fails, we ignore the error and load the data into
              # memory below
              except (AttributeError, TypeError, ValueError):
                  pass
          # mmap=False or np.memmap failed
          if newarr is None:
              # We can replace this with a call to np.fromfile in numpy>=1.17,
              # as an "offset" parameter was added in that version.
              with open(ext_fname, "rb") as f:
                  f.seek(darray.ext_offset)
                  nbytes = np.prod(darray.dims) * dtype().itemsize
                  buff = f.read(nbytes)
                  newarr = np.frombuffer(buff, dtype=dtype)
  
      # Numpy arrays created from bytes objects are read-only.
      # Neither b64decode nor decompress will return bytearrays, and there
      # are not equivalents to fobj.readinto to allow us to pass them, so
      # there is not a simple way to avoid making copies.
      # If this becomes a problem, we should write a decoding interface with
      # a tunable chunk size.
      else:
          dec = base64.b64decode(data.encode("ascii"))
          if enclabel == "B64BIN":
              # GIFTI_ENCODING_B64BIN
              buff = bytearray(dec)
          else:
              # GIFTI_ENCODING_B64GZ
              buff = bytearray(zlib.decompress(dec))
          del dec
          newarr = np.frombuffer(buff, dtype=dtype)
  
      sh = tuple(darray.dims)
      if len(newarr.shape) != len(sh):
          newarr = newarr.reshape(
              sh, order=array_index_order_codes.npcode[darray.ind_ord]
          )
  
      # check if we need to byteswap
      required_byteorder = gifti_endian_codes.byteorder[darray.endian]
      if (
          required_byteorder in ("big", "little")
          and required_byteorder != sys.byteorder
      ):
          newarr = newarr.byteswap()
      return newarr
  
imports: import base64
  import os.path
  import sys
  import warnings
  import zlib
  from io import StringIO
  from xml.parsers.expat import ExpatError
  import numpy
  from ..nifti1 import data_type_codes, intent_codes, xform_codes
  from ..xmlutils import XmlParser
  from .gifti import GiftiCoordSystem, GiftiDataArray, GiftiImage, GiftiLabel, GiftiLabelTable, GiftiMetaData
  from .util import array_index_order_codes, gifti_encoding_codes, gifti_endian_codes
label_desc: Use image node_id 1 for calling a global function with example usage: read_data_block(darray, fname, data, mmap) and returns: newarr, da, int