text:
<!DOCTYPE refentry [ <!ENTITY % mathent SYSTEM "math.ent"> %mathent; ]>

<!-- Converted by db4-upgrade version 1.1 -->

<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="glGetInternalformat">
    <info>
        <copyright>
            <year>2011-2014</year>
            <holder>Khronos Group.</holder>
        </copyright>
    </info>
    <refmeta>
        <refentrytitle>glGetInternalformat</refentrytitle>
        <manvolnum>3G</manvolnum>
    </refmeta>
    <refnamediv>
        <refname>glGetInternalformat</refname>
        <refpurpose>retrieve information about implementation-dependent support for internal formats</refpurpose>
    </refnamediv>
    <refsynopsisdiv><title>C Specification</title>
        <funcsynopsis>
            <funcprototype>
                <funcdef>void <function>glGetInternalformativ</function></funcdef>
                <paramdef>GLenum <parameter>target</parameter></paramdef>
                <paramdef>GLenum <parameter>internalformat</parameter></paramdef>
                <paramdef>GLenum <parameter>pname</parameter></paramdef>
                <paramdef>GLsizei <parameter>bufSize</parameter></paramdef>
                <paramdef>GLint *<parameter>params</parameter></paramdef>
            </funcprototype>
            <funcprototype>
                <funcdef>void <function>glGetInternalformati64v</function></funcdef>
                <paramdef>GLenum <parameter>target</parameter></paramdef>
                <paramdef>GLenum <parameter>internalformat</parameter></paramdef>
                <paramdef>GLenum <parameter>pname</parameter></paramdef>
                <paramdef>GLsizei <parameter>bufSize</parameter></paramdef>
                <paramdef>GLint64 *<parameter>params</parameter></paramdef>
            </funcprototype>
        </funcsynopsis>
    </refsynopsisdiv>
    <refsect1 xml:id="parameters"><title>Parameters</title>
        <variablelist>
        <varlistentry>
            <term><parameter>target</parameter></term>
            <listitem>
                <para>
                    Indicates the usage of the internal format. <parameter>target</parameter> must be <constant>GL_TEXTURE_1D</constant>, <constant>GL_TEXTURE_1D_ARRAY</constant>,
                    <constant>GL_TEXTURE_2D</constant>, <constant>GL_TEXTURE_2D_ARRAY</constant>, <constant>GL_TEXTURE_3D</constant>,
                    <constant>GL_TEXTURE_CUBE_MAP</constant>, <constant>GL_TEXTURE_CUBE_MAP_ARRAY</constant>, <constant>GL_TEXTURE_RECTANGLE</constant>,
                    <constant>GL_TEXTURE_BUFFER</constant>,
                    <constant>GL_RENDERBUFFER</constant>, <constant>GL_TEXTURE_2D_MULTISAMPLE</constant> or <constant>GL_TEXTURE_2D_MULTISAMPLE_ARRAY</constant>.
                </para>
            </listitem>
        </varlistentry>
        <varlistentry>
            <term><parameter>internalformat</parameter></term>
            <listitem>
                <para>
                    Specifies the internal format about which to retrieve information.
                </para>
            </listitem>
        </varlistentry>
        <varlistentry>
            <term><parameter>pname</parameter></term>
            <listitem>
                <para>
                    Specifies the type of information to query.
                </para>
            </listitem>
        </varlistentry>
        <varlistentry>
            <term><parameter>bufSize</parameter></term>
            <listitem>
                <para>
                    Specifies the maximum number of basic machine units that may be written to <parameter>params</parameter> by the function.
                </para>
            </listitem>
        </varlistentry>
        <varlistentry>
            <term><parameter>params</parameter></term>
            <listitem>
                <para>
                    Specifies the address of a variable into which to write the retrieved information.
                </para>
            </listitem>
        </varlistentry>
        </variablelist>
    </refsect1>
    <refsect1 xml:id="description"><title>Description</title>
        <para>
            <function>glGetInternalformativ</function> and <function>glGetInternalformati64v</function> retrieve information about implementation-dependent support for
            internal formats. <parameter>target</parameter> indicates the target with which the internal format will
            be used and must be one of <constant>GL_RENDERBUFFER</constant>, <constant>GL_TEXTURE_2D_MULTISAMPLE</constant>,
            or <constant>GL_TEXTURE_2D_MULTISAMPLE_ARRAY</constant>, corresponding to usage as a renderbuffer, two-dimensional
            multisample texture or two-dimensional multisample array texture, respectively.
        </para>
        <para>
            <parameter>internalformat</parameter> specifies the internal format about which to retrieve information and
            must be a color-renderable, depth-renderable or stencil-renderable format.
        </para>
        <para>
            The information retrieved will be written to memory addressed by the pointer specified in <parameter>params</parameter>. No
            more than <parameter>bufSize</parameter> basic machine units will be written to this memory.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_NUM_SAMPLE_COUNTS</constant>, the number of sample counts that would be
            returned by querying <constant>GL_SAMPLES</constant> will be returned in <parameter>params</parameter>.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_SAMPLES</constant>, the sample counts supported for <parameter>internalformat</parameter>
            and <parameter>target</parameter> are written into <parameter>params</parameter> in descending numeric order. Only positive values are returned.
            Querying <constant>GL_SAMPLES</constant> with <parameter>bufSize</parameter> of one will return just the maximum supported number of
            samples for this format. The maximum value in <constant>GL_SAMPLES</constant> is guaranteed to be at least the lowest of the following:
            <itemizedlist>
                <listitem>
                    <para>
                        The value of
                        <constant>GL_MAX_INTEGER_SAMPLES</constant> if
                        <parameter>internalformat</parameter> is a signed or
                        unsigned integer format.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        The value of
                        <constant>GL_MAX_DEPTH_TEXTURE_SAMPLES</constant> if
                        <parameter>internalformat</parameter> is a depth- or
                        stencil-renderable format and
                        <parameter>target</parameter> is
                        <constant>GL_TEXTURE_2D_MULTISAMPLE</constant>,
                        <constant>GL_TEXTURE_2D_MULTISAMPLE_ARRAY</constant>.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        The value of
                        <constant>GL_MAX_COLOR_TEXTURE_SAMPLES</constant> if
                        <parameter>internalformat</parameter> is a
                        color-renderable format and
                        <parameter>target</parameter> is
                        <constant>GL_TEXTURE_2D_MULTISAMPLE</constant> or
                        <constant>GL_TEXTURE_2D_MULTISAMPLE_ARRAY</constant>.
                    </para>
                </listitem>
                <listitem>
                    <para>The value of <constant>GL_MAX_SAMPLES</constant>.</para>
                </listitem>

            </itemizedlist>
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_INTERNALFORMAT_SUPPORTED</constant>, <parameter>params</parameter> is set to <constant>GL_TRUE</constant> if <parameter>internalFormat</parameter>
            is a supported internal format for <parameter>target</parameter> and to <constant>GL_FALSE</constant> otherwise.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_INTERNALFORMAT_PREFERRED</constant>, <parameter>params</parameter> is set to <constant>GL_TRUE</constant> if <parameter>internalFormat</parameter>
            is an format for <parameter>target</parameter> that is preferred by the implementation and to <constant>GL_FALSE</constant> otherwise.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_INTERNALFORMAT_RED_SIZE</constant>, <constant>GL_INTERNALFORMAT_GREEN_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_BLUE_SIZE</constant>, <constant>GL_INTERNALFORMAT_ALPHA_SIZE</constant>, <constant>GL_INTERNALFORMAT_DEPTH_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_STENCIL_SIZE</constant>, or <constant>GL_INTERNALFORMAT_SHARED_SIZE</constant> then
            <parameter>params</parameter> is set to the actual resolutions that would be used for storing image array components
            for the resource for the red, green, blue, alpha, depth, stencil and shared channels respectively. If <parameter>internalFormat</parameter>
            is a compressed internal format, then <parameter>params</parameter> is set to the component resolution of an uncompressed internal format that produces
            an image of roughly the same quality as the compressed algorithm. If the internal format is unsupported, or if a particular component is
            not present in the format, 0 is written to <parameter>params</parameter>.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_INTERNALFORMAT_RED_TYPE</constant>, <constant>GL_INTERNALFORMAT_GREEN_TYPE</constant>,
            <constant>GL_INTERNALFORMAT_BLUE_TYPE</constant>, <constant>GL_INTERNALFORMAT_ALPHA_TYPE</constant>, <constant>GL_INTERNALFORMAT_DEPTH_TYPE</constant>,
            or <constant>GL_INTERNALFORMAT_STENCIL_TYPE</constant> then <parameter>params</parameter> is set to a token identifying the data type used
            to store the respective component. If the <parameter>internalFormat</parameter> represents a compressed internal format then
            the types returned specify how components are interpreted after decompression.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_MAX_WIDTH</constant>, <constant>GL_MAX_HEIGHT</constant>, <constant>GL_MAX_DEPTH</constant>,
            or <constant>GL_MAX_LAYERS</constant> then <parameter>pname</parameter> is filled with the maximum width, height, depth or layer count
            for textures with internal format <parameter>internalFormat</parameter>, respectively. If <parameter>pname</parameter> is <constant>GL_MAX_COMBINED_DIMENSIONS</constant>
            then <parameter>pname</parameter> is filled with the maximum combined dimensions of a texture of the specified internal format.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_COLOR_COMPONENTS</constant> then <parameter>params</parameter> is set to the value <constant>GL_TRUE</constant>
            if the internal format contains any color component (i.e., red, green, blue or alpha) and to <constant>GL_FALSE</constant> otherwise. If
            <parameter>pname</parameter> is <constant>GL_DEPTH_COMPONENTS</constant> or <constant>GL_STENCIL_COMPONENTS</constant> then <parameter>params</parameter>
            is set to <constant>GL_TRUE</constant> if the internal format contains a depth or stencil component, respectively, and to <constant>GL_FALSE</constant>
            otherwise.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_COLOR_RENDERABLE</constant>, <constant>GL_DEPTH_RENDERABLE</constant> or <constant>GL_STENCIL_RENDERABLE</constant>
            then <parameter>params</parameter> is set to <constant>GL_TRUE</constant> if the specified internal format is color, depth or stencil renderable, respectively,
            and to <constant>GL_FALSE</constant> otherwise.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_FRAMEBUFFER_RENDERABLE</constant> or <constant>GL_FRAMEBUFFER_RENDERABLE_LAYERED</constant>
            then <parameter>params</parameter> is set to one of <constant>GL_FULL_SUPPORT</constant>,
            <constant>GL_CAVEAT_SUPPORT</constant> or <constant>GL_NONE</constant> to indicate that framebuffer attachments (layered attachments in the
            case of <constant>GL_FRAMEBUFFER_RENDERABLE_LAYERED</constant>) with that internal format are either
            renderable with no restrictions, renderable with some restrictions or not renderable at all.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_FRAMEBUFFER_BLEND</constant>, <parameter>params</parameter> is set to <constant>GL_TRUE</constant>
            to indicate that the internal format is supported for blending operations when attached to a framebuffer, and to <constant>GL_FALSE</constant> otherwise.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_READ_PIXELS</constant> then <parameter>params</parameter> is set to <constant>GL_FULL_SUPPORT</constant>,
            <constant>GL_CAVEAT_SUPPORT</constant> or <constant>GL_NONE</constant> to that either full support, limited support or no support at all is supplied
            for reading pixels from framebuffer attachments in the specified internal format.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_READ_PIXELS_FORMAT</constant> or <constant>GL_READ_PIXELS_TYPE</constant> then <parameter>params</parameter>
            is filled with the format or type, respectively, most recommended to obtain the highest image quality and performance. For
            <constant>GL_READ_PIXELS_FORMAT</constant>, the value returned in <parameter>params</parameter> is a token that is accepted for
            the <parameter>format</parameter> argument to <citerefentry><refentrytitle>glReadPixels</refentrytitle></citerefentry>. For
            <constant>GL_READ_PIXELS_TYPE</constant>, the value returned in <parameter>params</parameter> is a token that is accepted for
            the <parameter>type</parameter> argument to <citerefentry><refentrytitle>glReadPixels</refentrytitle></citerefentry>.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_TEXTURE_IMAGE_FORMAT</constant> or <constant>GL_TEXTURE_IMAGE_TYPE</constant> then
            <parameter>params</parameter> is filled with the implementation-recommended format or type to be used in calls to
            <citerefentry><refentrytitle>glTexImage2D</refentrytitle></citerefentry> and other similar functions. For <constant>GL_TEXTURE_IMAGE_FORMAT</constant>,
            <parameter>params</parameter> is filled with a token suitable for use as the <parameter>format</parameter> argument to
            <citerefentry><refentrytitle>glTexImage2D</refentrytitle></citerefentry>. For <constant>GL_TEXTURE_IMAGE_TYPE</constant>,
            <parameter>params</parameter> is filled with a token suitable for use as the <parameter>type</parameter> argument to
            <citerefentry><refentrytitle>glTexImage2D</refentrytitle></citerefentry>.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_GET_TEXTURE_IMAGE_FORMAT</constant> or <constant>GL_GET_TEXTURE_IMAGE_TYPE</constant> then
            <parameter>params</parameter> is filled with the implementation-recommended format or type to be used in calls to
            <citerefentry><refentrytitle>glGetTexImage2D</refentrytitle></citerefentry> and other similar functions. For <constant>GL_GET_TEXTURE_IMAGE_FORMAT</constant>,
            <parameter>params</parameter> is filled with a token suitable for use as the <parameter>format</parameter> argument to
            <citerefentry><refentrytitle>glGetTexImage2D</refentrytitle></citerefentry>. For <constant>GL_GET_TEXTURE_IMAGE_TYPE</constant>,
            <parameter>params</parameter> is filled with a token suitable for use as the <parameter>type</parameter> argument to
            <citerefentry><refentrytitle>glGetTexImage2D</refentrytitle></citerefentry>.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_MIPMAP</constant> then <parameter>pname</parameter> is set to <constant>GL_TRUE</constant>
            to indicate that the specified internal format supports mipmaps and to <constant>GL_FALSE</constant> otherwise.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_GENERATE_MIPMAP</constant> or <constant>GL_AUTO_GENERATE_MIPMAP</constant> then <parameter>params</parameter>
            is indicates the level of support for manual or automatic mipmap generation for the specified internal format, respectively. Returned values
            may be one of <constant>GL_FULL_SUPPORT</constant>, <constant>GL_CAVEAT_SUPPORT</constant> and <constant>GL_NONE</constant> to indicate
            either full support, limited support or no support at all.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_COLOR_ENCODING</constant> then the color encoding for the resource is returned in
            <parameter>params</parameter>. Possible values for color buffers are <constant>GL_LINEAR</constant> or <constant>GL_SRGB</constant>,
            for linear or sRGB-encoded color components, respectively. For non-color
            formats (such as depth or stencil), or for unsupported resources,
            the value <constant>GL_NONE</constant> is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_SRGB_READ</constant>, or <constant>GL_SRGB_WRITE</constant> then <parameter>params</parameter>
            indicates the level of support for reading and writing to sRGB encoded images, respectively. For <constant>GL_SRGB_READ</constant>,
            support for converting from sRGB colorspace on read operations is returned in <parameter>params</parameter> and for <constant>GL_SRGB_WRITE</constant>,
            support for converting to sRGB colorspace on write operations to the resource is returned in <parameter>params</parameter>. <parameter>params</parameter> may be
            set to <constant>GL_FULL_SUPPORT</constant>, <constant>GL_CAVEAT_SUPPORT</constant>, or <constant>GL_NONE</constant> to indicate
            full support, limited support or no support at all, respecitively.
        </para>
        <para>
             If <parameter>pname</parameter> is <constant>GL_FILTER</constant> the <parameter>params</parameter> is set to either <constant>GL_TRUE</constant>
             or <constant>GL_FALSE</constant> to indicate support or lack thereof for filter modes other than <constant>GL_NEAREST</constant> or <constant>GL_NEAREST_MIPMAP</constant>
             for the specified internal format.
         </para>
         <para>
            If <parameter>pname</parameter> is <constant>GL_VERTEX_TEXTURE</constant>, <constant>GL_TESS_CONTROL_TEXTURE</constant>, <constant>GL_TESS_EVALUATION_TEXTURE</constant>,
            <constant>GL_GEOMETRY_TEXTURE</constant>, <constant>GL_FRAGMENT_TEXTURE</constant>, or <constant>GL_COMPUTE_TEXTURE</constant>, then the value
            written to <parameter>params</parameter> indicates support for use of the resource as a source of texturing in the vertex, tessellation control,
            tessellation evaluation, geometry, fragment and compute shader stages, respectively. <parameter>params</parameter> may be set to
            <constant>GL_FULL_SUPPORT</constant>, <constant>GL_CAVEAT_SUPPORT</constant> or <constant>GL_NONE</constant> to indicate full support,
            limited support or no support at all, respectively.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_TEXTURE_SHADOW</constant>, <constant>GL_TEXTURE_GATHER</constant> or <constant>GL_TEXTURE_GATHER_SHADOW</constant> then the value written to
            <parameter>params</parameter> indicates the level of support for using the resource with a shadow sampler, in gather operations or as a shadow sampler in gather operations, respectively. Returned values
            may be <constant>GL_FULL_SUPPORT</constant>, <constant>GL_CAVEAT_SUPPORT</constant> or <constant>GL_NONE</constant> to indicate full support,
            limited support or no support at all, respectively.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_SHADER_IMAGE_LOAD</constant>, <constant>GL_SHADER_IMAGE_STORE</constant> or <constant>GL_SHADER_IMAGE_ATOMIC</constant>
            then the value returned in <parameter>params</parameter> indicates the level of support for image loads, stores and atomics for resources of the specified internal
            format. Returned values
            may be <constant>GL_FULL_SUPPORT</constant>, <constant>GL_CAVEAT_SUPPORT</constant> or <constant>GL_NONE</constant> to indicate full support,
            limited support or no support at all, respectively.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_IMAGE_TEXEL_SIZE</constant> then the size of a texel when the resource when used as
            an image texture is returned in <parameter>params</parameter>. If the resource is not supported for image
            textures zero is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_IMAGE_COMPATIBILITY_CLASS</constant> then the compatibility class of the resource when
            used as an image texture is returned in <parameter>params</parameter>. The possible values
            returned are <constant>GL_IMAGE_CLASS_4_X_32</constant>, <constant>GL_IMAGE_CLASS_2_X_32</constant>, <constant>GL_IMAGE_CLASS_1_X_32</constant>,
            <constant>GL_IMAGE_CLASS_4_X_16</constant>, <constant>GL_IMAGE_CLASS_2_X_16</constant>, <constant>GL_IMAGE_CLASS_1_X_16</constant>,
            <constant>GL_IMAGE_CLASS_4_X_8</constant>, <constant>GL_IMAGE_CLASS_2_X_8</constant>, <constant>GL_IMAGE_CLASS_1_X_8</constant>,
            <constant>GL_IMAGE_CLASS_11_11_10</constant>, and <constant>GL_IMAGE_CLASS_10_10_10_2</constant>, which correspond to
            the 4x32, 2x32, 1x32, 4x16, 2x16, 1x16, 4x8, 2x8, 1x8, the class
            (a) 11/11/10 packed floating-point format, and the class (b)
            10/10/10/2 packed formats, respectively.
            If the resource is not supported for image textures, <constant>GL_NONE</constant> is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_IMAGE_PIXEL_FORMAT</constant> or <constant>GL_IMAGE_PIXEL_TYPE</constant> then
            the pixel format or type of the resource when used as an image texture is returned in <parameter>params</parameter>, respectively.
            In either case, the resource is not supported for image textures <constant>GL_NONE</constant> is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_IMAGE_FORMAT_COMPATIBILITY_TYPE</constant>, the matching criteria use for the
            resource when used as an image textures is returned in <parameter>params</parameter>. Possible values returned in <parameter>params</parameter> are
            <constant>GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE</constant> or <constant>GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS</constant>.
            If the resource is not supported for image textures, <constant>GL_NONE</constant> is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST</constant> or <constant>GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST</constant>,
            support for using the resource both as a source for texture sampling while it is bound as a buffer for depth or stencil test, respectively, is written to <parameter>params</parameter>.
            Possible values returned are <constant>GL_FULL_SUPPORT</constant>, <constant>GL_CAVEAT_SUPPORT</constant>, or <constant>GL_NONE</constant> to indicate
            full support, limited support or no support at all. If the resource or operation is not supported, <constant>GL_NONE</constant> is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE</constant> or <constant>GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE</constant>,
            support for using the resource both as a source for texture sampling while performing depth or stencil writes to the resources, respectively, is written to <parameter>params</parameter>.
            Possible values returned are <constant>GL_FULL_SUPPORT</constant>, <constant>GL_CAVEAT_SUPPORT</constant>, or <constant>GL_NONE</constant> to indicate
            full support, limited support or no support at all. If the resource or operation is not supported, <constant>GL_NONE</constant> is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_TEXTURE_COMPRESSED</constant> then <constant>GL_TRUE</constant> is returned in <parameter>params</parameter>
            if <parameter>internalformat</parameter> is a compressed internal format. <constant>GL_FALSE</constant> is returned in <parameter>params</parameter>
            otherwise.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_TEXTURE_COMPRESSED_BLOCK_WIDTH</constant>, <constant>GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT</constant> or
            <constant>GL_TEXTURE_COMPRESSED_BLOCK_SIZE</constant> then the width, height or total size, respectively of a block (in basic machine units) is returned in
            <parameter>params</parameter>. If the internal format is not compressed, or the resource is not supported, 0 is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_CLEAR_BUFFER</constant>, the level of support for using the resource with <citerefentry><refentrytitle>glClearBufferData</refentrytitle></citerefentry>
            and <citerefentry><refentrytitle>glClearBufferSubData</refentrytitle></citerefentry> is returned in <parameter>params</parameter>. Possible values returned are <constant>GL_FULL_SUPPORT</constant>,
            <constant>GL_CAVEAT_SUPPORT</constant>, or <constant>GL_NONE</constant> to indicate
            full support, limited support or no support at all, respectively. If the resource or operation is not supported, <constant>GL_NONE</constant> is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_TEXTURE_VIEW</constant>, the level of support for using the resource with the <citerefentry><refentrytitle>glTextureView</refentrytitle></citerefentry>
            command is returned in <parameter>params</parameter>. Possible values returned are <constant>GL_FULL_SUPPORT</constant>,
            <constant>GL_CAVEAT_SUPPORT</constant>, or <constant>GL_NONE</constant> to indicate
            full support, limited support or no support at all, respectively. If the resource or operation is not supported, <constant>GL_NONE</constant> is returned.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_VIEW_COMPATIBILITY_CLASS</constant> then the compatibility class of the resource when
            used as a texture view is returned in <parameter>params</parameter>. The possible values
            returned are <constant>GL_VIEW_CLASS_128_BITS</constant>, <constant>GL_VIEW_CLASS_96_BITS</constant>,
            <constant>GL_VIEW_CLASS_64_BITS</constant>, <constant>GL_VIEW_CLASS_48_BITS</constant>, <constant>GL_VIEW_CLASS_32_BITS</constant>,
            <constant>GL_VIEW_CLASS_24_BITS</constant>, <constant>GL_VIEW_CLASS_16_BITS</constant>, <constant>GL_VIEW_CLASS_8_BITS</constant>,
            <constant>GL_VIEW_CLASS_S3TC_DXT1_RGB</constant>, <constant>GL_VIEW_CLASS_S3TC_DXT1_RGBA</constant>,
            <constant>GL_VIEW_CLASS_S3TC_DXT3_RGBA</constant>, <constant>GL_VIEW_CLASS_S3TC_DXT5_RGBA</constant>,
            <constant>GL_VIEW_CLASS_RGTC1_RED</constant>, <constant>GL_VIEW_CLASS_RGTC2_RG</constant>, <constant>GL_VIEW_CLASS_BPTC_UNORM</constant>, and
            <constant>GL_VIEW_CLASS_BPTC_FLOAT</constant>.
        </para>
        <para>
            If <parameter>pname</parameter> is <constant>GL_CLEAR_TEXTURE</constant> then the presence of support for using the
            <citerefentry><refentrytitle>glClearTexImage</refentrytitle></citerefentry> and <citerefentry><refentrytitle>glClearTexSubImage</refentrytitle></citerefentry>
            commands with the resource is written to <parameter>params</parameter>. Possible values written are  <constant>GL_FULL_SUPPORT</constant>,
            <constant>GL_CAVEAT_SUPPORT</constant>, or <constant>GL_NONE</constant> to indicate
            full support, limited support or no support at all, respectively. If the resource or operation is not supported, <constant>GL_NONE</constant> is returned.
        </para>
    </refsect1>
    <refsect1 xml:id="notes"><title>Notes</title>
        <para>
            <function>glGetInternalformativ</function> is available only if the
            GL version is 4.2 or higher.
        </para>
        <para>
            The tokens
            <constant>GL_INTERNALFORMAT_SUPPORTED</constant>,
            <constant>GL_INTERNALFORMAT_PREFERRED</constant>,
            <constant>GL_INTERNALFORMAT_RED_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_GREEN_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_BLUE_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_ALPHA_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_DEPTH_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_STENCIL_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_SHARED_SIZE</constant>,
            <constant>GL_INTERNALFORMAT_RED_TYPE</constant>,
            <constant>GL_INTERNALFORMAT_GREEN_TYPE</constant>,
            <constant>GL_INTERNALFORMAT_BLUE_TYPE</constant>,
            <constant>GL_INTERNALFORMAT_ALPHA_TYPE</constant>,
            <constant>GL_INTERNALFORMAT_DEPTH_TYPE</constant>,
            <constant>GL_INTERNALFORMAT_STENCIL_TYPE</constant>,
            <constant>GL_MAX_WIDTH</constant>,
            <constant>GL_MAX_HEIGHT</constant>,
            <constant>GL_MAX_DEPTH</constant>,
            <constant>GL_MAX_LAYERS</constant>,
            <constant>GL_MAX_COMBINED_DIMENSIONS</constant>,
            <constant>GL_COLOR_COMPONENTS</constant>,
            <constant>GL_DEPTH_COMPONENTS</constant>,
            <constant>GL_STENCIL_COMPONENTS</constant>,
            <constant>GL_COLOR_RENDERABLE</constant>,
            <constant>GL_DEPTH_RENDERABLE</constant>,
            <constant>GL_STENCIL_RENDERABLE</constant>,
            <constant>GL_FRAMEBUFFER_RENDERABLE</constant>,
            <constant>GL_FRAMEBUFFER_RENDERABLE_LAYERED</constant>,
            <constant>GL_FRAMEBUFFER_BLEND</constant>,
            <constant>GL_READ_PIXELS</constant>,
            <constant>GL_READ_PIXELS_FORMAT</constant>,
            <constant>GL_READ_PIXELS_TYPE</constant>,
            <constant>GL_TEXTURE_IMAGE_FORMAT</constant>,
            <constant>GL_TEXTURE_IMAGE_TYPE</constant>,
            <constant>GL_GET_TEXTURE_IMAGE_FORMAT</constant>,
            <constant>GL_GET_TEXTURE_IMAGE_TYPE</constant>,
            <constant>GL_MIPMAP</constant>,
            <constant>GL_GENERATE_MIPMAP</constant>,
            <constant>GL_AUTO_GENERATE_MIPMAP</constant>,
            <constant>GL_COLOR_ENCODING</constant>,
            <constant>GL_SRGB_READ</constant>,
            <constant>GL_SRGB_WRITE</constant>,
            <constant>GL_SRGB_DECODE_ARB</constant>,
            <constant>GL_FILTER</constant>,
            <constant>GL_VERTEX_TEXTURE</constant>,
            <constant>GL_TESS_CONTROL_TEXTURE</constant>,
            <constant>GL_TESS_EVALUATION_TEXTURE</constant>,
            <constant>GL_GEOMETRY_TEXTURE</constant>,
            <constant>GL_FRAGMENT_TEXTURE</constant>,
            <constant>GL_COMPUTE_TEXTURE</constant>,
            <constant>GL_TEXTURE_SHADOW</constant>,
            <constant>GL_TEXTURE_GATHER</constant>,
            <constant>GL_TEXTURE_GATHER_SHADOW</constant>,
            <constant>GL_SHADER_IMAGE_LOAD</constant>,
            <constant>GL_SHADER_IMAGE_STORE</constant>,
            <constant>GL_SHADER_IMAGE_ATOMIC</constant>,
            <constant>GL_IMAGE_TEXEL_SIZE</constant>,
            <constant>GL_IMAGE_COMPATIBILITY_CLASS</constant>,
            <constant>GL_IMAGE_PIXEL_FORMAT</constant>,
            <constant>GL_IMAGE_PIXEL_TYPE</constant>,
            <constant>GL_IMAGE_FORMAT_COMPATIBILITY_TYPE</constant>,
            <constant>GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST</constant>,
            <constant>GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST</constant>,
            <constant>GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE</constant>,
            <constant>GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE</constant>,
            <constant>GL_TEXTURE_COMPRESSED</constant>,
            <constant>GL_TEXTURE_COMPRESSED_BLOCK_WIDTH</constant>,
            <constant>GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT</constant>,
            <constant>GL_TEXTURE_COMPRESSED_BLOCK_SIZE</constant>,
            <constant>GL_CLEAR_BUFFER</constant>,
            <constant>GL_TEXTURE_VIEW</constant>, and
            <constant>GL_VIEW_COMPATIBILITY_CLASS</constant> are supported only if the GL
            version is 4.3 or higher.
        </para>
        <para>
            The <constant>GL_CLEAR_TEXTURE</constant> token is accepted for <parameter>pname</parameter> only
            if the GL version is 4.4 or higher.
        </para>
        </refsect1>
    <refsect1 xml:id="errors"><title>Errors</title>
        <para>
            <constant>GL_INVALID_VALUE</constant> is generated if <parameter>bufSize</parameter> is negative.
        </para>
        <para>
            <constant>GL_INVALID_ENUM</constant> is generated if <parameter>pname</parameter> is not <constant>GL_SAMPLES</constant> or <constant>GL_NUM_SAMPLE_COUNTS</constant>.
        </para>
        <para>
            <constant>GL_INVALID_ENUM</constant> is generated if <parameter>internalformat</parameter> is not color-, depth-, or stencil-renderable.
        </para>
        <para>
            <constant>GL_INVALID_ENUM</constant> is generated if <parameter>target</parameter> is not one of <constant>GL_TEXTURE_2D_MULTISAMPLE</constant>,
            <constant>GL_TEXTURE_2D_MULTISAMPLE_ARRAY</constant> or <constant>GL_RENDERBUFFER</constant>.
        </para>
    </refsect1>
    <refsect1 xml:id="versions"><title>Version Support</title>
        <informaltable>
            <tgroup cols="13" align="left">
                <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="apifunchead.xml" xpointer="xpointer(/*/*)"/>
                <tbody>
                    <row>
                        <entry><function>glGetInternalformati64v</function></entry>
                        <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="apiversion.xml" xpointer="xpointer(/*/*[@role='43']/*)"/>
                    </row>
                    <row>
                        <entry><function>glGetInternalformativ</function></entry>
                        <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="apiversion.xml" xpointer="xpointer(/*/*[@role='42']/*)"/>
                    </row>
                </tbody>
            </tgroup>
        </informaltable>
    </refsect1>
    <refsect1 xml:id="seealso"><title>See Also</title>
        <para>
            <citerefentry><refentrytitle>glGet</refentrytitle></citerefentry>
        </para>
    </refsect1>
    <refsect1 xml:id="Copyright"><title>Copyright</title>
        <para>
            Copyright <trademark class="copyright"/> 2011-2014 Khronos Group.
            This material may be distributed subject to the terms and conditions set forth in
            the Open Publication License, v 1.0, 8 June 1999.
            <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://opencontent.org/openpub/">http://opencontent.org/openpub/</link>.
        </para>
    </refsect1>
</refentry>


text:
extern struct crypto_stream_chacha20_implementation
    crypto_stream_chacha20_dolbeau_ssse3_implementation;

redpajama_set_name: RedPajamaGithub


text:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <script/standard.h>

#include <crypto/sha256.h>
#include <hash.h>
#include <pubkey.h>
#include <script/interpreter.h>
#include <script/script.h>
#include <util/strencodings.h>

#include <qtum/qtumstate.h>
#include <qtum/qtumDGP.h>
#include <qtum/qtumtransaction.h>
#include <validation.h>
#include <streams.h>

#include <string>
#include <variant>

typedef std::vector<unsigned char> valtype;

bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;

CScriptID::CScriptID(const CScript& in) : BaseHash(Hash160(in)) {}
CScriptID::CScriptID(const ScriptHash& in) : BaseHash(static_cast<uint160>(in)) {}

ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {}
ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {}

PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}

WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash(static_cast<uint160>(pubkey_hash)) {}

CKeyID ToKeyID(const PKHash& key_hash)
{
    return CKeyID{static_cast<uint160>(key_hash)};
}

CKeyID ToKeyID(const WitnessV0KeyHash& key_hash)
{
    return CKeyID{static_cast<uint160>(key_hash)};
}

WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
{
    CSHA256().Write(in.data(), in.size()).Finalize(begin());
}

std::string GetTxnOutputType(TxoutType t)
{
    switch (t) {
    case TxoutType::NONSTANDARD: return "nonstandard";
    case TxoutType::PUBKEY: return "pubkey";
    case TxoutType::PUBKEYHASH: return "pubkeyhash";
    case TxoutType::SCRIPTHASH: return "scripthash";
    case TxoutType::MULTISIG: return "multisig";
    case TxoutType::NULL_DATA: return "nulldata";
    case TxoutType::WITNESS_V0_KEYHASH: return "witness_v0_keyhash";
    case TxoutType::WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
    case TxoutType::WITNESS_V1_TAPROOT: return "witness_v1_taproot";
    case TxoutType::WITNESS_UNKNOWN: return "witness_unknown";
    case TxoutType::CREATE_SENDER: return "create_sender";
    case TxoutType::CALL_SENDER: return "call_sender";
    case TxoutType::CREATE: return "create";
    case TxoutType::CALL: return "call";
    } // no default case, so the compiler can warn about missing cases
    assert(false);
}

static bool MatchPayToPubkey(const CScript& script, valtype& pubkey)
{
    if (script.size() == CPubKey::SIZE + 2 && script[0] == CPubKey::SIZE && script.back() == OP_CHECKSIG) {
        pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::SIZE + 1);
        return CPubKey::ValidSize(pubkey);
    }
    if (script.size() == CPubKey::COMPRESSED_SIZE + 2 && script[0] == CPubKey::COMPRESSED_SIZE && script.back() == OP_CHECKSIG) {
        pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::COMPRESSED_SIZE + 1);
        return CPubKey::ValidSize(pubkey);
    }
    return false;
}

static bool MatchPayToPubkeyHash(const CScript& script, valtype& pubkeyhash)
{
    if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) {
        pubkeyhash = valtype(script.begin () + 3, script.begin() + 23);
        return true;
    }
    return false;
}

/** Test for "small positive integer" script opcodes - OP_1 through OP_16. */
static constexpr bool IsSmallInteger(opcodetype opcode)
{
    return opcode >= OP_1 && opcode <= OP_16;
}

static constexpr bool IsPushdataOp(opcodetype opcode)
{
    return opcode > OP_FALSE && opcode <= OP_PUSHDATA4;
}

static constexpr bool IsValidMultisigKeyCount(int n_keys)
{
    return n_keys > 0 && n_keys <= MAX_PUBKEYS_PER_MULTISIG;
}

static bool GetMultisigKeyCount(opcodetype opcode, valtype data, int& count)
{
    if (IsSmallInteger(opcode)) {
        count = CScript::DecodeOP_N(opcode);
        return IsValidMultisigKeyCount(count);
    }

    if (IsPushdataOp(opcode)) {
        if (!CheckMinimalPush(data, opcode)) return false;
        try {
            count = CScriptNum(data, /* fRequireMinimal = */ true).getint();
            return IsValidMultisigKeyCount(count);
        } catch (const scriptnum_error&) {
            return false;
        }
    }

    return false;
}

static bool MatchMultisig(const CScript& script, int& required_sigs, std::vector<valtype>& pubkeys)
{
    opcodetype opcode;
    valtype data;
    int num_keys;

    CScript::const_iterator it = script.begin();
    if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false;

    if (!script.GetOp(it, opcode, data) || !GetMultisigKeyCount(opcode, data, required_sigs)) return false;
    while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) {
        pubkeys.emplace_back(std::move(data));
    }
    if (!GetMultisigKeyCount(opcode, data, num_keys)) return false;

    if (pubkeys.size() != static_cast<unsigned long>(num_keys) || num_keys < required_sigs) return false;

    return (it + 1 == script.end());
}

static bool MatchContract(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet, bool contractConsensus, bool allowEmptySenderSig, TxoutType& typeRet )
{
    //contractConsesus is true when evaluating if a contract tx is "standard" for consensus purposes
    //It is false in all other cases, so to prevent a particular contract tx from being broadcast on mempool, but allowed in blocks,
    //one should ensure that contractConsensus is false

    // Templates
    static std::multimap<TxoutType, CScript> mTemplates;
    if (mTemplates.empty())
    {
        // Contract creation tx with sender
        mTemplates.insert(std::make_pair(TxoutType::CREATE_SENDER, CScript() << OP_ADDRESS_TYPE << OP_ADDRESS << OP_SCRIPT_SIG << OP_SENDER << OP_VERSION << OP_GAS_LIMIT << OP_GAS_PRICE << OP_DATA << OP_CREATE));

        // Call contract tx with sender
        mTemplates.insert(std::make_pair(TxoutType::CALL_SENDER, CScript() << OP_ADDRESS_TYPE << OP_ADDRESS << OP_SCRIPT_SIG << OP_SENDER << OP_VERSION << OP_GAS_LIMIT << OP_GAS_PRICE << OP_DATA << OP_PUBKEYHASH << OP_CALL));

        // Contract creation tx
        mTemplates.insert(std::make_pair(TxoutType::CREATE, CScript() << OP_VERSION << OP_GAS_LIMIT << OP_GAS_PRICE << OP_DATA << OP_CREATE));

        // Call contract tx
        mTemplates.insert(std::make_pair(TxoutType::CALL, CScript() << OP_VERSION << OP_GAS_LIMIT << OP_GAS_PRICE << OP_DATA << OP_PUBKEYHASH << OP_CALL));
    }

    // Scan templates
    typeRet = TxoutType::NONSTANDARD;
    const CScript& script1 = scriptPubKey;
    for (const std::pair<TxoutType, CScript>& tplate : mTemplates)
    {
        const CScript& script2 = tplate.second;
        vSolutionsRet.clear();

        opcodetype opcode1, opcode2;
        std::vector<unsigned char> vch1, vch2;

        uint64_t addressType = 0;
        VersionVM version;
        version.rootVM=20; //set to some invalid value

        // Compare
        CScript::const_iterator pc1 = script1.begin();
        CScript::const_iterator pc2 = script2.begin();
        while (true)
        {
            if (pc1 == script1.end() && pc2 == script2.end())
            {
                // Found a match
                typeRet =  tplate.first;
                return true;
            }
            if (!script1.GetOp(pc1, opcode1, vch1))
                break;
            if (!script2.GetOp(pc2, opcode2, vch2))
                break;

            // Template matching opcodes:
            if (opcode2 == OP_PUBKEYS)
            {
                while (vch1.size() >= 33 && vch1.size() <= 65)
                {
                    vSolutionsRet.push_back(vch1);
                    if (!script1.GetOp(pc1, opcode1, vch1))
                        break;
                }
                if (!script2.GetOp(pc2, opcode2, vch2))
                    break;
                // Normal situation is to fall through
                // to other if/else statements
            }

            if (opcode2 == OP_PUBKEY)
            {
                if (vch1.size() < 33 || vch1.size() > 65)
                    break;
                vSolutionsRet.push_back(vch1);
            }
            else if (opcode2 == OP_PUBKEYHASH)
            {
                if (vch1.size() != sizeof(uint160))
                    break;
                vSolutionsRet.push_back(vch1);
            }
            else if (opcode2 == OP_SMALLINTEGER)
            {   // Single-byte small integer pushed onto vSolutions
                if (opcode1 == OP_0 ||
                    (opcode1 >= OP_1 && opcode1 <= OP_16))
                {
                    char n = (char)CScript::DecodeOP_N(opcode1);
                    vSolutionsRet.push_back(valtype(1, n));
                }
                else
                    break;
            }
            else if (opcode2 == OP_VERSION)
            {
                if(0 <= opcode1 && opcode1 <= OP_PUSHDATA4)
                {
                    if(vch1.empty() || vch1.size() > 4 || (vch1.back() & 0x80))
                        return false;

                    version = VersionVM::fromRaw(CScriptNum::vch_to_uint64(vch1));
                    if(!(version.toRaw() == VersionVM::GetEVMDefault().toRaw() || version.toRaw() == VersionVM::GetNoExec().toRaw())){
                        // only allow standard EVM and no-exec transactions to live in mempool
                        return false;
                    }
                }
            }
            else if(opcode2 == OP_GAS_LIMIT) {
                try {
                    uint64_t val = CScriptNum::vch_to_uint64(vch1);
                    if(contractConsensus) {
                        //consensus rules (this is checked more in depth later using DGP)
                        if (version.rootVM != 0 && val < 1) {
                            return false;
                        }
                        if (val > MAX_BLOCK_GAS_LIMIT_DGP) {
                            //do not allow transactions that could use more gas than is in a block
                            return false;
                        }
                    }else{
                        //standard mempool rules for contracts
                        //consensus rules for contracts
                        if (version.rootVM != 0 && val < STANDARD_MINIMUM_GAS_LIMIT) {
                            return false;
                        }
                        if (val > DEFAULT_BLOCK_GAS_LIMIT_DGP / 2) {
                            //don't allow transactions that use more than 1/2 block of gas to be broadcast on the mempool
                            return false;
                        }

                    }
                }
                catch (const scriptnum_error &err) {
                    return false;
                }
            }
            else if(opcode2 == OP_GAS_PRICE) {
                try {
                    uint64_t val = CScriptNum::vch_to_uint64(vch1);
                    if(contractConsensus) {
                        //consensus rules (this is checked more in depth later using DGP)
                        if (version.rootVM != 0 && val < 1) {
                            return false;
                        }
                    }else{
                        //standard mempool rules
                        if (version.rootVM != 0 && val < STANDARD_MINIMUM_GAS_PRICE) {
                            return false;
                        }
                    }
                }
                catch (const scriptnum_error &err) {
                    return false;
                }
            }
            else if(opcode2 == OP_DATA)
            {
                if(0 <= opcode1 && opcode1 <= OP_PUSHDATA4)
                {
                    if(vch1.empty())
                        break;
                }
            }
            else if(opcode2 == OP_ADDRESS_TYPE)
            {
                try {
                    uint64_t val = CScriptNum::vch_to_uint64(vch1);
                    if(val < addresstype::PUBKEYHASH || val > addresstype::NONSTANDARD)
                        break;

                    addressType = val;
                }
                catch (const scriptnum_error &err) {
                    break;
                }
            }
            else if(opcode2 == OP_ADDRESS)
            {
                // Get the destination
                CTxDestination dest;
                if(addressType == addresstype::PUBKEYHASH && vch1.size() == sizeof(PKHash))
                {
                    dest = PKHash(uint160(vch1));
                }
                else
                    break;

                // Get the public key for the destination
                CScript senderPubKey = GetScriptForDestination(dest);
                CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                ss << senderPubKey;
                vSolutionsRet.push_back(std::vector<unsigned char>(ss.begin(), ss.end()));
            }
            else if(opcode2 == OP_SCRIPT_SIG)
            {
                if(0 <= opcode1 && opcode1 <= OP_PUSHDATA4)
                {
                    if(!allowEmptySenderSig && vch1.empty())
                        break;

                    // Check the max size of the signature script
                    if(vch1.size() > MAX_BASE_SCRIPT_SIZE)
                        return false;

                    vSolutionsRet.push_back(vch1);
                }
            }
            else if (opcode1 != opcode2 || vch1 != vch2)
            {
                // Others must match exactly
                break;
            }
        }
    }

    return false;
}

TxoutType Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet, bool contractConsensus, bool allowEmptySenderSig)
{
    vSolutionsRet.clear();

    // Shortcut for pay-to-script-hash, which are more constrained than the other types:
    // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
    if (scriptPubKey.IsPayToScriptHash())
    {
        std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
        vSolutionsRet.push_back(hashBytes);
        return TxoutType::SCRIPTHASH;
    }

    int witnessversion;
    std::vector<unsigned char> witnessprogram;
    if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
        if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) {
            vSolutionsRet.push_back(std::move(witnessprogram));
            return TxoutType::WITNESS_V0_KEYHASH;
        }
        if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
            vSolutionsRet.push_back(std::move(witnessprogram));
            return TxoutType::WITNESS_V0_SCRIPTHASH;
        }
        if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE) {
            vSolutionsRet.push_back(std::move(witnessprogram));
            return TxoutType::WITNESS_V1_TAPROOT;
        }
        if (witnessversion != 0) {
            vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion});
            vSolutionsRet.push_back(std::move(witnessprogram));
            return TxoutType::WITNESS_UNKNOWN;
        }
        return TxoutType::NONSTANDARD;
    }

    // Provably prunable, data-carrying output
    //
    // So long as script passes the IsUnspendable() test and all but the first
    // byte passes the IsPushOnly() test we don't care what exactly is in the
    // script.
    if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
        return TxoutType::NULL_DATA;
    }

    std::vector<unsigned char> data;
    if (MatchPayToPubkey(scriptPubKey, data)) {
        vSolutionsRet.push_back(std::move(data));
        return TxoutType::PUBKEY;
    }

    if (MatchPayToPubkeyHash(scriptPubKey, data)) {
        vSolutionsRet.push_back(std::move(data));
        return TxoutType::PUBKEYHASH;
    }

    int required;
    std::vector<std::vector<unsigned char>> keys;
    if (MatchMultisig(scriptPubKey, required, keys)) {
        vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..20
        vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
        vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..20
        return TxoutType::MULTISIG;
    }

    TxoutType typeContract = TxoutType::NONSTANDARD;
    if(MatchContract(scriptPubKey, vSolutionsRet, contractConsensus, allowEmptySenderSig, typeContract))
    {
        return typeContract;
    }

    vSolutionsRet.clear();
    return TxoutType::NONSTANDARD;
}

bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet, TxoutType *typeRet)
{
    std::vector<valtype> vSolutions;
    TxoutType whichType = Solver(scriptPubKey, vSolutions);

    if(typeRet){
        *typeRet = whichType;
    }

    switch (whichType) {
    case TxoutType::PUBKEY: {
        CPubKey pubKey(vSolutions[0]);
        if (!pubKey.IsValid())
            return false;

        addressRet = PKHash(pubKey);
        return true;
    }
    case TxoutType::PUBKEYHASH: {
        addressRet = PKHash(uint160(vSolutions[0]));
        return true;
    }
    case TxoutType::SCRIPTHASH: {
        addressRet = ScriptHash(uint160(vSolutions[0]));
        return true;
    }
    case TxoutType::WITNESS_V0_KEYHASH: {
        WitnessV0KeyHash hash;
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
        addressRet = hash;
        return true;
    }
    case TxoutType::WITNESS_V0_SCRIPTHASH: {
        WitnessV0ScriptHash hash;
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
        addressRet = hash;
        return true;
    }
    case TxoutType::WITNESS_V1_TAPROOT: {
        WitnessV1Taproot tap;
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());
        addressRet = tap;
        return true;
    }
    case TxoutType::WITNESS_UNKNOWN: {
        WitnessUnknown unk;
        unk.version = vSolutions[0][0];
        std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
        unk.length = vSolutions[1].size();
        addressRet = unk;
        return true;
    }
    case TxoutType::MULTISIG:
    case TxoutType::NULL_DATA:
    case TxoutType::NONSTANDARD:
    case TxoutType::CREATE_SENDER:
    case TxoutType::CALL_SENDER:
    case TxoutType::CREATE:
    case TxoutType::CALL:
        return false;
    } // no default case, so the compiler can warn about missing cases
    assert(false);
}

// TODO: from v23 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed
bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet, bool contractConsensus)
{
    addressRet.clear();
    std::vector<valtype> vSolutions;
    typeRet = Solver(scriptPubKey, vSolutions, contractConsensus);
    if (typeRet == TxoutType::NONSTANDARD) {
        return false;
    } else if (typeRet == TxoutType::NULL_DATA) {
        // This is data, not addresses
        return false;
    }

    if (typeRet == TxoutType::MULTISIG)
    {
        nRequiredRet = vSolutions.front()[0];
        for (unsigned int i = 1; i < vSolutions.size()-1; i++)
        {
            CPubKey pubKey(vSolutions[i]);
            if (!pubKey.IsValid())
                continue;

            CTxDestination address = PKHash(pubKey);
            addressRet.push_back(address);
        }

        if (addressRet.empty())
            return false;
    }
    else
    {
        nRequiredRet = 1;
        CTxDestination address;
        if (!ExtractDestination(scriptPubKey, address))
           return false;
        addressRet.push_back(address);
    }

    return true;
}

namespace {
class CScriptVisitor
{
public:
    CScript operator()(const CNoDestination& dest) const
    {
        return CScript();
    }

    CScript operator()(const PKHash& keyID) const
    {
        return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
    }

    CScript operator()(const ScriptHash& scriptID) const
    {
        return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
    }

    CScript operator()(const WitnessV0KeyHash& id) const
    {
        return CScript() << OP_0 << ToByteVector(id);
    }

    CScript operator()(const WitnessV0ScriptHash& id) const
    {
        return CScript() << OP_0 << ToByteVector(id);
    }

    CScript operator()(const WitnessV1Taproot& tap) const
    {
        return CScript() << OP_1 << ToByteVector(tap);
    }

    CScript operator()(const WitnessUnknown& id) const
    {
        return CScript() << CScript::EncodeOP_N(id.version) << std::vector<unsigned char>(id.program, id.program + id.length);
    }
};
} // namespace

CScript GetScriptForDestination(const CTxDestination& dest)
{
    return std::visit(CScriptVisitor(), dest);
}

CScript GetScriptForRawPubKey(const CPubKey& pubKey)
{
    return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG;
}

CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
{
    CScript script;

    script << nRequired;
    for (const CPubKey& key : keys)
        script << ToByteVector(key);
    script << keys.size() << OP_CHECKMULTISIG;

    return script;
}

bool IsValidDestination(const CTxDestination& dest) {
    return dest.index() != 0;
}

/*static*/ TaprootBuilder::NodeInfo TaprootBuilder::Combine(NodeInfo&& a, NodeInfo&& b)
{
    NodeInfo ret;
    /* Iterate over all tracked leaves in a, add b's hash to their Merkle branch, and move them to ret. */
    for (auto& leaf : a.leaves) {
        leaf.merkle_branch.push_back(b.hash);
        ret.leaves.emplace_back(std::move(leaf));
    }
    /* Iterate over all tracked leaves in b, add a's hash to their Merkle branch, and move them to ret. */
    for (auto& leaf : b.leaves) {
        leaf.merkle_branch.push_back(a.hash);
        ret.leaves.emplace_back(std::move(leaf));
    }
    /* Lexicographically sort a and b's hash, and compute parent hash. */
    if (a.hash < b.hash) {
        ret.hash = (CHashWriter(HASHER_TAPBRANCH) << a.hash << b.hash).GetSHA256();
    } else {
        ret.hash = (CHashWriter(HASHER_TAPBRANCH) << b.hash << a.hash).GetSHA256();
    }
    return ret;
}

void TaprootSpendData::Merge(TaprootSpendData other)
{
    // TODO: figure out how to better deal with conflicting information
    // being merged.
    if (internal_key.IsNull() && !other.internal_key.IsNull()) {
        internal_key = other.internal_key;
    }
    if (merkle_root.IsNull() && !other.merkle_root.IsNull()) {
        merkle_root = other.merkle_root;
    }
    for (auto& [key, control_blocks] : other.scripts) {
        // Once P0083R3 is supported by all our targeted platforms,
        // this loop body can be replaced with:
        // scripts[key].merge(std::move(control_blocks));
        auto& target = scripts[key];
        for (auto& control_block: control_blocks) {
            target.insert(std::move(control_block));
        }
    }
}

void TaprootBuilder::Insert(TaprootBuilder::NodeInfo&& node, int depth)
{
    assert(depth >= 0 && (size_t)depth <= TAPROOT_CONTROL_MAX_NODE_COUNT);
    /* We cannot insert a leaf at a lower depth while a deeper branch is unfinished. Doing
     * so would mean the Add() invocations do not correspond to a DFS traversal of a
     * binary tree. */
    if ((size_t)depth + 1 < m_branch.size()) {
        m_valid = false;
        return;
    }
    /* As long as an entry in the branch exists at the specified depth, combine it and propagate up.
     * The 'node' variable is overwritten here with the newly combined node. */
    while (m_valid && m_branch.size() > (size_t)depth && m_branch[depth].has_value()) {
        node = Combine(std::move(node), std::move(*m_branch[depth]));
        m_branch.pop_back();
        if (depth == 0) m_valid = false; /* Can't propagate further up than the root */
        --depth;
    }
    if (m_valid) {
        /* Make sure the branch is big enough to place the new node. */
        if (m_branch.size() <= (size_t)depth) m_branch.resize((size_t)depth + 1);
        assert(!m_branch[depth].has_value());
        m_branch[depth] = std::move(node);
    }
}

/*static*/ bool TaprootBuilder::ValidDepths(const std::vector<int>& depths)
{
    std::vector<bool> branch;
    for (int depth : depths) {
        // This inner loop corresponds to effectively the same logic on branch
        // as what Insert() performs on the m_branch variable. Instead of
        // storing a NodeInfo object, just remember whether or not there is one
        // at that depth.
        if (depth < 0 || (size_t)depth > TAPROOT_CONTROL_MAX_NODE_COUNT) return false;
        if ((size_t)depth + 1 < branch.size()) return false;
        while (branch.size() > (size_t)depth && branch[depth]) {
            branch.pop_back();
            if (depth == 0) return false;
            --depth;
        }
        if (branch.size() <= (size_t)depth) branch.resize((size_t)depth + 1);
        assert(!branch[depth]);
        branch[depth] = true;
    }
    // And this check corresponds to the IsComplete() check on m_branch.
    return branch.size() == 0 || (branch.size() == 1 && branch[0]);
}

TaprootBuilder& TaprootBuilder::Add(int depth, const CScript& script, int leaf_version, bool track)
{
    assert((leaf_version & ~TAPROOT_LEAF_MASK) == 0);
    if (!IsValid()) return *this;
    /* Construct NodeInfo object with leaf hash and (if track is true) also leaf information. */
    NodeInfo node;
    node.hash = (CHashWriter{HASHER_TAPLEAF} << uint8_t(leaf_version) << script).GetSHA256();
    if (track) node.leaves.emplace_back(LeafInfo{script, leaf_version, {}});
    /* Insert into the branch. */
    Insert(std::move(node), depth);
    return *this;
}

TaprootBuilder& TaprootBuilder::AddOmitted(int depth, const uint256& hash)
{
    if (!IsValid()) return *this;
    /* Construct NodeInfo object with the hash directly, and insert it into the branch. */
    NodeInfo node;
    node.hash = hash;
    Insert(std::move(node), depth);
    return *this;
}

TaprootBuilder& TaprootBuilder::Finalize(const XOnlyPubKey& internal_key)
{
    /* Can only call this function when IsComplete() is true. */
    assert(IsComplete());
    m_internal_key = internal_key;
    auto ret = m_internal_key.CreateTapTweak(m_branch.size() == 0 ? nullptr : &m_branch[0]->hash);
    assert(ret.has_value());
    std::tie(m_output_key, m_parity) = *ret;
    return *this;
}

WitnessV1Taproot TaprootBuilder::GetOutput() { return WitnessV1Taproot{m_output_key}; }

TaprootSpendData TaprootBuilder::GetSpendData() const
{
    TaprootSpendData spd;
    spd.merkle_root = m_branch.size() == 0 ? uint256() : m_branch[0]->hash;
    spd.internal_key = m_internal_key;
    if (m_branch.size()) {
        // If any script paths exist, they have been combined into the root m_branch[0]
        // by now. Compute the control block for each of its tracked leaves, and put them in
        // spd.scripts.
        for (const auto& leaf : m_branch[0]->leaves) {
            std::vector<unsigned char> control_block;
            control_block.resize(TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * leaf.merkle_branch.size());
            control_block[0] = leaf.leaf_version | (m_parity ? 1 : 0);
            std::copy(m_internal_key.begin(), m_internal_key.end(), control_block.begin() + 1);
            if (leaf.merkle_branch.size()) {
                std::copy(leaf.merkle_branch[0].begin(),
                          leaf.merkle_branch[0].begin() + TAPROOT_CONTROL_NODE_SIZE * leaf.merkle_branch.size(),
                          control_block.begin() + TAPROOT_CONTROL_BASE_SIZE);
            }
            spd.scripts[{leaf.script, leaf.leaf_version}].insert(std::move(control_block));
        }
    }
    return spd;
}

std::optional<std::vector<std::tuple<int, CScript, int>>> InferTaprootTree(const TaprootSpendData& spenddata, const XOnlyPubKey& output)
{
    // Verify that the output matches the assumed Merkle root and internal key.
    auto tweak = spenddata.internal_key.CreateTapTweak(spenddata.merkle_root.IsNull() ? nullptr : &spenddata.merkle_root);
    if (!tweak || tweak->first != output) return std::nullopt;
    // If the Merkle root is 0, the tree is empty, and we're done.
    std::vector<std::tuple<int, CScript, int>> ret;
    if (spenddata.merkle_root.IsNull()) return ret;

    /** Data structure to represent the nodes of the tree we're going to build. */
    struct TreeNode {
        /** Hash of this node, if known; 0 otherwise. */
        uint256 hash;
        /** The left and right subtrees (note that their order is irrelevant). */
        std::unique_ptr<TreeNode> sub[2];
        /** If this is known to be a leaf node, a pointer to the (script, leaf_ver) pair.
         *  nullptr otherwise. */
        const std::pair<CScript, int>* leaf = nullptr;
        /** Whether or not this node has been explored (is known to be a leaf, or known to have children). */
        bool explored = false;
        /** Whether or not this node is an inner node (unknown until explored = true). */
        bool inner;
        /** Whether or not we have produced output for this subtree. */
        bool done = false;
    };

    // Build tree from the provided branches.
    TreeNode root;
    root.hash = spenddata.merkle_root;
    for (const auto& [key, control_blocks] : spenddata.scripts) {
        const auto& [script, leaf_ver] = key;
        for (const auto& control : control_blocks) {
            // Skip script records with nonsensical leaf version.
            if (leaf_ver < 0 || leaf_ver >= 0x100 || leaf_ver & 1) continue;
            // Skip script records with invalid control block sizes.
            if (control.size() < TAPROOT_CONTROL_BASE_SIZE || control.size() > TAPROOT_CONTROL_MAX_SIZE ||
                ((control.size() - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE) != 0) continue;
            // Skip script records that don't match the control block.
            if ((control[0] & TAPROOT_LEAF_MASK) != leaf_ver) continue;
            // Skip script records that don't match the provided Merkle root.
            const uint256 leaf_hash = ComputeTapleafHash(leaf_ver, script);
            const uint256 merkle_root = ComputeTaprootMerkleRoot(control, leaf_hash);
            if (merkle_root != spenddata.merkle_root) continue;

            TreeNode* node = &root;
            size_t levels = (control.size() - TAPROOT_CONTROL_BASE_SIZE) / TAPROOT_CONTROL_NODE_SIZE;
            for (size_t depth = 0; depth < levels; ++depth) {
                // Can't descend into a node which we already know is a leaf.
                if (node->explored && !node->inner) return std::nullopt;

                // Extract partner hash from Merkle branch in control block.
                uint256 hash;
                std::copy(control.begin() + TAPROOT_CONTROL_BASE_SIZE + (levels - 1 - depth) * TAPROOT_CONTROL_NODE_SIZE,
                          control.begin() + TAPROOT_CONTROL_BASE_SIZE + (levels - depth) * TAPROOT_CONTROL_NODE_SIZE,
                          hash.begin());

                if (node->sub[0]) {
                    // Descend into the existing left or right branch.
                    bool desc = false;
                    for (int i = 0; i < 2; ++i) {
                        if (node->sub[i]->hash == hash || (node->sub[i]->hash.IsNull() && node->sub[1-i]->hash != hash)) {
                            node->sub[i]->hash = hash;
                            node = &*node->sub[1-i];
                            desc = true;
                            break;
                        }
                    }
                    if (!desc) return std::nullopt; // This probably requires a hash collision to hit.
                } else {
                    // We're in an unexplored node. Create subtrees and descend.
                    node->explored = true;
                    node->inner = true;
                    node->sub[0] = std::make_unique<TreeNode>();
                    node->sub[1] = std::make_unique<TreeNode>();
                    node->sub[1]->hash = hash;
                    node = &*node->sub[0];
                }
            }
            // Cannot turn a known inner node into a leaf.
            if (node->sub[0]) return std::nullopt;
            node->explored = true;
            node->inner = false;
            node->leaf = &key;
            node->hash = leaf_hash;
        }
    }

    // Recursive processing to turn the tree into flattened output. Use an explicit stack here to avoid
    // overflowing the call stack (the tree may be 128 levels deep).
    std::vector<TreeNode*> stack{&root};
    while (!stack.empty()) {
        TreeNode& node = *stack.back();
        if (!node.explored) {
            // Unexplored node, which means the tree is incomplete.
            return std::nullopt;
        } else if (!node.inner) {
            // Leaf node; produce output.
            ret.emplace_back(stack.size() - 1, node.leaf->first, node.leaf->second);
            node.done = true;
            stack.pop_back();
        } else if (node.sub[0]->done && !node.sub[1]->done && !node.sub[1]->explored && !node.sub[1]->hash.IsNull() &&
                   (CHashWriter{HASHER_TAPBRANCH} << node.sub[1]->hash << node.sub[1]->hash).GetSHA256() == node.hash) {
            // Whenever there are nodes with two identical subtrees under it, we run into a problem:
            // the control blocks for the leaves underneath those will be identical as well, and thus
            // they will all be matched to the same path in the tree. The result is that at the location
            // where the duplicate occurred, the left child will contain a normal tree that can be explored
            // and processed, but the right one will remain unexplored.
            //
            // This situation can be detected, by encountering an inner node with unexplored right subtree
            // with known hash, and H_TapBranch(hash, hash) is equal to the parent node (this node)'s hash.
            //
            // To deal with this, simply process the left tree a second time (set its done flag to false;
            // noting that the done flag of its children have already been set to false after processing
            // those). To avoid ending up in an infinite loop, set the done flag of the right (unexplored)
            // subtree to true.
            node.sub[0]->done = false;
            node.sub[1]->done = true;
        } else if (node.sub[0]->done && node.sub[1]->done) {
            // An internal node which we're finished with.
            node.sub[0]->done = false;
            node.sub[1]->done = false;
            node.done = true;
            stack.pop_back();
        } else if (!node.sub[0]->done) {
            // An internal node whose left branch hasn't been processed yet. Do so first.
            stack.push_back(&*node.sub[0]);
        } else if (!node.sub[1]->done) {
            // An internal node whose right branch hasn't been processed yet. Do so first.
            stack.push_back(&*node.sub[1]);
        }
    }

    return ret;
}

bool IsValidContractSenderAddress(const CTxDestination &dest)
{
    return std::holds_alternative<PKHash>(dest);
}

bool ExtractSenderData(const CScript &outputPubKey, CScript *senderPubKey, CScript *senderSig)
{
    if(outputPubKey.HasOpSender())
    {
        try
        {
            // Solve the contract with or without contract consensus
            std::vector<valtype> vSolutions;
            if (TxoutType::NONSTANDARD == Solver(outputPubKey, vSolutions, true) &&
                    TxoutType::NONSTANDARD == Solver(outputPubKey, vSolutions, false))
                return false;

            // Check the size of the returned data
            if(vSolutions.size() < 2)
                return false;

            // Get the sender public key
            if(senderPubKey)
            {
                CDataStream ss(vSolutions[0], SER_NETWORK, PROTOCOL_VERSION);
                ss >> *senderPubKey;
            }

            // Get the sender signature
            if(senderSig)
            {
                CDataStream ss(vSolutions[1], SER_NETWORK, PROTOCOL_VERSION);
                ss >> *senderSig;
            }
        }
        catch(...)
        {
            return false;
        }

        return true;
    }
    return false;
}

bool GetSenderPubKey(const CScript &outputPubKey, CScript &senderPubKey)
{
    if(outputPubKey.HasOpSender())
    {
        try
        {
            // Solve the contract with or without contract consensus
            std::vector<valtype> vSolutions;
            if (TxoutType::NONSTANDARD == Solver(outputPubKey, vSolutions, true, true) &&
                    TxoutType::NONSTANDARD == Solver(outputPubKey, vSolutions, false, true))
                return false;

            // Check the size of the returned data
            if(vSolutions.size() < 1)
                return false;

            // Get the sender public key
            CDataStream ss(vSolutions[0], SER_NETWORK, PROTOCOL_VERSION);
            ss >> senderPubKey;
        }
        catch(...)
        {
            return false;
        }

        return true;
    }
    return false;
}

PKHash ExtractPublicKeyHash(const CScript& scriptPubKey, bool* OK)
{
    if(OK) *OK = false;
    CTxDestination address;
    TxoutType txType=TxoutType::NONSTANDARD;
    if(ExtractDestination(scriptPubKey, address, &txType)){
        if ((txType == TxoutType::PUBKEY || txType == TxoutType::PUBKEYHASH) && std::holds_alternative<PKHash>(address)) {
            if(OK) *OK = true;
            return std::get<PKHash>(address);
        }
    }

    return PKHash();
}

valtype DataVisitor::operator()(const CNoDestination& noDest) const { return valtype(); }
valtype DataVisitor::operator()(const PKHash& keyID) const { return valtype(keyID.begin(), keyID.end()); }
valtype DataVisitor::operator()(const ScriptHash& scriptID) const { return valtype(scriptID.begin(), scriptID.end()); }
valtype DataVisitor::operator()(const WitnessV0ScriptHash& witnessScriptHash) const { return valtype(witnessScriptHash.begin(), witnessScriptHash.end()); }
valtype DataVisitor::operator()(const WitnessV0KeyHash& witnessKeyHash) const { return valtype(witnessKeyHash.begin(), witnessKeyHash.end()); }
valtype DataVisitor::operator()(const WitnessV1Taproot& witnessTaproot) const { return valtype(witnessTaproot.begin(), witnessTaproot.end()); }
valtype DataVisitor::operator()(const WitnessUnknown&) const { return valtype(); }

bool ExtractDestination(const COutPoint& prevout, const CScript& scriptPubKey, CTxDestination& addressRet, TxoutType* typeRet)
{
    std::vector<valtype> vSolutions;
    TxoutType whichType = Solver(scriptPubKey, vSolutions);

    if(typeRet){
        *typeRet = whichType;
    }

    if (whichType == TxoutType::PUBKEY)
    {
        CPubKey pubKey(vSolutions[0]);
        if (!pubKey.IsValid())
            return false;

        addressRet = PKHash(pubKey);
        return true;
    }
    else if (whichType == TxoutType::PUBKEYHASH)
    {
        addressRet = PKHash(uint160(vSolutions[0]));
        return true;
    }
    else if (whichType == TxoutType::SCRIPTHASH)
    {
        addressRet = ScriptHash(uint160(vSolutions[0]));
        return true;
    }
    else if(whichType == TxoutType::CALL){
        addressRet = PKHash(uint160(vSolutions[0]));
        return true;
    }
    else if(whichType == TxoutType::WITNESS_V0_KEYHASH)
    {
        addressRet = WitnessV0KeyHash(uint160(vSolutions[0]));
        return true;
    }
    else if(whichType == TxoutType::WITNESS_V0_SCRIPTHASH)
    {
        addressRet = WitnessV0ScriptHash(uint256(vSolutions[0]));
        return true;
    }
    else if(whichType == TxoutType::WITNESS_V1_TAPROOT)
    {
        WitnessV1Taproot tap;
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());
        addressRet = tap;
        return true;
    }
    else if (whichType == TxoutType::WITNESS_UNKNOWN) {
        WitnessUnknown unk;
        unk.version = vSolutions[0][0];
        std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
        unk.length = vSolutions[1].size();
        addressRet = unk;
        return true;
    }
    else if (whichType == TxoutType::CREATE) {
        addressRet = PKHash(uint160(QtumState::createQtumAddress(uintToh256(prevout.hash), prevout.n).asBytes()));
        return true;
    }
    return false;
}


text:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Machine.Specifications;

namespace Snooze
{

    public class TestUrl : Url
    {
        public int Param { get; set; }
    }

    public class TestSubUrl : SubUrl<TestUrl>
    {
        public int Param2 { get; set; }
    }

    [Subject("Xml resource serialization")]
    public class XmlResourceSerializationSpecs
    {
        public class When_serializing_a_resource_with_a_url
        {
            static StringBuilder str;
            static XmlSerializer serializer;

            public class TestResource
            {
                public TestUrl Url { get; set; }
            }

            Establish context = () => serializer = new XmlSerializer(typeof (TestResource));

            Because of = () => serializer.Serialize(new StringWriter(str = new StringBuilder()), new TestResource {Url = new TestUrl()});

            It Has_serialized = () => str.ToString().ShouldNotBeEmpty();
        }

        public class When_serializing_a_resource_with_a_sub_url
        {
            static StringBuilder str;
            static XmlSerializer serializer;

            public class TestResource
            {
                public TestSubUrl Url { get; set; }
            }

            Establish context = () => serializer = new XmlSerializer(typeof(TestResource));

            Because of = () => serializer.Serialize(new StringWriter(str = new StringBuilder()), new TestResource { Url = new TestSubUrl{Parent = new TestUrl()} });

            It Has_serialized = () => str.ToString().ShouldNotBeEmpty();
        }

    }
}


text:
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace POGOProtos.Networking.Responses {

  /// Holder for reflection information generated from POGOProtos/Networking/Responses/UseItemXpBoostResponse.proto
  public static partial class UseItemXpBoostResponseReflection {

    #region Descriptor
    /// File descriptor for POGOProtos/Networking/Responses/UseItemXpBoostResponse.proto
    public static pbr::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static UseItemXpBoostResponseReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "CjxQT0dPUHJvdG9zL05ldHdvcmtpbmcvUmVzcG9uc2VzL1VzZUl0ZW1YcEJv",
            "b3N0UmVzcG9uc2UucHJvdG8SH1BPR09Qcm90b3MuTmV0d29ya2luZy5SZXNw",
            "b25zZXMaJ1BPR09Qcm90b3MvSW52ZW50b3J5L0FwcGxpZWRJdGVtcy5wcm90",
            "byK+AgoWVXNlSXRlbVhwQm9vc3RSZXNwb25zZRJOCgZyZXN1bHQYASABKA4y",
            "Pi5QT0dPUHJvdG9zLk5ldHdvcmtpbmcuUmVzcG9uc2VzLlVzZUl0ZW1YcEJv",
            "b3N0UmVzcG9uc2UuUmVzdWx0EjkKDWFwcGxpZWRfaXRlbXMYAiABKAsyIi5Q",
            "T0dPUHJvdG9zLkludmVudG9yeS5BcHBsaWVkSXRlbXMimAEKBlJlc3VsdBIJ",
            "CgVVTlNFVBAAEgsKB1NVQ0NFU1MQARIbChdFUlJPUl9JTlZBTElEX0lURU1f",
            "VFlQRRACEiEKHUVSUk9SX1hQX0JPT1NUX0FMUkVBRFlfQUNUSVZFEAMSHAoY",
            "RVJST1JfTk9fSVRFTVNfUkVNQUlOSU5HEAQSGAoURVJST1JfTE9DQVRJT05f",
            "VU5TRVQQBWIGcHJvdG8z"));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { global::POGOProtos.Inventory.AppliedItemsReflection.Descriptor, },
          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::POGOProtos.Networking.Responses.UseItemXpBoostResponse), global::POGOProtos.Networking.Responses.UseItemXpBoostResponse.Parser, new[]{ "Result", "AppliedItems" }, null, new[]{ typeof(global::POGOProtos.Networking.Responses.UseItemXpBoostResponse.Types.Result) }, null)
          }));
    }
    #endregion

  }
  #region Messages
  public sealed partial class UseItemXpBoostResponse : pb::IMessage<UseItemXpBoostResponse> {
    private static readonly pb::MessageParser<UseItemXpBoostResponse> _parser = new pb::MessageParser<UseItemXpBoostResponse>(() => new UseItemXpBoostResponse());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<UseItemXpBoostResponse> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::POGOProtos.Networking.Responses.UseItemXpBoostResponseReflection.Descriptor.MessageTypes[0]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public UseItemXpBoostResponse() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public UseItemXpBoostResponse(UseItemXpBoostResponse other) : this() {
      result_ = other.result_;
      AppliedItems = other.appliedItems_ != null ? other.AppliedItems.Clone() : null;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public UseItemXpBoostResponse Clone() {
      return new UseItemXpBoostResponse(this);
    }

    /// Field number for the "result" field.
    public const int ResultFieldNumber = 1;
    private global::POGOProtos.Networking.Responses.UseItemXpBoostResponse.Types.Result result_ = 0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::POGOProtos.Networking.Responses.UseItemXpBoostResponse.Types.Result Result {
      get { return result_; }
      set {
        result_ = value;
      }
    }

    /// Field number for the "applied_items" field.
    public const int AppliedItemsFieldNumber = 2;
    private global::POGOProtos.Inventory.AppliedItems appliedItems_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::POGOProtos.Inventory.AppliedItems AppliedItems {
      get { return appliedItems_; }
      set {
        appliedItems_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as UseItemXpBoostResponse);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(UseItemXpBoostResponse other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Result != other.Result) return false;
      if (!object.Equals(AppliedItems, other.AppliedItems)) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Result != 0) hash ^= Result.GetHashCode();
      if (appliedItems_ != null) hash ^= AppliedItems.GetHashCode();
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Result != 0) {
        output.WriteRawTag(8);
        output.WriteEnum((int) Result);
      }
      if (appliedItems_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(AppliedItems);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Result != 0) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Result);
      }
      if (appliedItems_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(AppliedItems);
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(UseItemXpBoostResponse other) {
      if (other == null) {
        return;
      }
      if (other.Result != 0) {
        Result = other.Result;
      }
      if (other.appliedItems_ != null) {
        if (appliedItems_ == null) {
          appliedItems_ = new global::POGOProtos.Inventory.AppliedItems();
        }
        AppliedItems.MergeFrom(other.AppliedItems);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            result_ = (global::POGOProtos.Networking.Responses.UseItemXpBoostResponse.Types.Result) input.ReadEnum();
            break;
          }
          case 18: {
            if (appliedItems_ == null) {
              appliedItems_ = new global::POGOProtos.Inventory.AppliedItems();
            }
            input.ReadMessage(appliedItems_);
            break;
          }
        }
      }
    }

    #region Nested types
    /// Container for nested types declared in the UseItemXpBoostResponse message type.
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      public enum Result {
        [pbr::OriginalName("UNSET")] Unset = 0,
        [pbr::OriginalName("SUCCESS")] Success = 1,
        [pbr::OriginalName("ERROR_INVALID_ITEM_TYPE")] ErrorInvalidItemType = 2,
        [pbr::OriginalName("ERROR_XP_BOOST_ALREADY_ACTIVE")] ErrorXpBoostAlreadyActive = 3,
        [pbr::OriginalName("ERROR_NO_ITEMS_REMAINING")] ErrorNoItemsRemaining = 4,
        [pbr::OriginalName("ERROR_LOCATION_UNSET")] ErrorLocationUnset = 5,
      }

    }
    #endregion

  }

  #endregion

}

#endregion Designer generated code


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.11"/>
<title>VO808X: testing::gmock_matchers_test::DerivedClass Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

VO808X

Main Page

Related Pages

Namespaces

Classes

Files

          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Class List

Class Index

Class Hierarchy

Class Members

Public Member Functions |
List of all members

testing::gmock_matchers_test::DerivedClass Class Reference

Inheritance diagram for testing::gmock_matchers_test::DerivedClass:

[legend]

Collaboration diagram for testing::gmock_matchers_test::DerivedClass:

[legend]

Public Member Functions

int 	k () const

 Public Member Functions inherited from testing::gmock_matchers_test::AClass

 	AClass ()

int 	n () const

void 	set_n (int new_n)

const string & 	s () const

void 	set_s (const string &new_s)

double & 	x () const

Detailed Description

Definition at line 3604 of file gmock-matchers_test.cc.

Member Function Documentation

          int testing::gmock_matchers_test::DerivedClass::k
          (
          	)
           const

inline

Definition at line 3606 of file gmock-matchers_test.cc.

The documentation for this class was generated from the following file:

/home/bhargavi/Documents/SDR/Copy_Exam_808X/vendor/googletest/googlemock/test/gmock-matchers_test.cc

testing

gmock_matchers_test

DerivedClass

Generated by

     1.8.11


text:
<?xml version="1.0" encoding="UTF-8"?>
<test-data>
    <test-code>
        <description><![CDATA[
TEST1
     ]]></description>
        <expected-problems>1</expected-problems>
        <![CDATA[
public class Foo {
    synchronized void foo () {}
}
     ]]>
    </test-code>
    <test-code>
        <description><![CDATA[
TEST2
     ]]></description>
        <expected-problems>0</expected-problems>
        <![CDATA[
public class Foo {
    void foo () {
        synchronized(mutex) {}
    }
}
     ]]>
    </test-code>

    <test-code>
        <description>#991 AvoidSynchronizedAtMethodLevel for static methods - bad case</description>
        <expected-problems>1</expected-problems>
        <![CDATA[
public class Test {
    public static synchronized void foo() {
        // complete method is synchronized on Test.class
    }
}
        ]]>
    </test-code>

    <test-code>
        <description>#991 AvoidSynchronizedAtMethodLevel for static methods - good case</description>
        <expected-problems>0</expected-problems>
        <![CDATA[
public class Test {
    public static void foo() {
        synchronized(Test.class) {
            // only a block is synchronized on Test.class
        }
    }
}
        ]]>
    </test-code>
</test-data>


text:
module TestTypeclasses (test_typeclasses) where

import Data.Word

import Test.Framework (testGroup)
import Test.Framework.Providers.QuickCheck2 (testProperty)

import System.Random.Random123.Types

test_li1x32_bijection initial = initial == mapped initial where
    types = initial :: Word32
    mapped = liFromInteger . liToInteger

test_li2x32_bijection initial = initial == mapped initial where
    types = initial :: Array2 Word32
    mapped = liFromInteger . liToInteger

test_li4x32_bijection initial = initial == mapped initial where
    types = initial :: Array4 Word32
    mapped = liFromInteger . liToInteger

test_li1x64_bijection initial = initial == mapped initial where
    types = initial :: Word64
    mapped = liFromInteger . liToInteger

test_li2x64_bijection initial = initial == mapped initial where
    types = initial :: Array2 Word64
    mapped = liFromInteger . liToInteger

test_li4x64_bijection initial = initial == mapped initial where
    types = initial :: Array4 Word64
    mapped = liFromInteger . liToInteger

test_li1x32_bitsize li = liToInteger li < 2 ^ liBitSize li where
    types = li :: Word32

test_li2x32_bitsize li = liToInteger li < 2 ^ liBitSize li where
    types = li :: Array2 Word32

test_li4x32_bitsize li = liToInteger li < 2 ^ liBitSize li where
    types = li :: Array4 Word32

test_li1x64_bitsize li = liToInteger li < 2 ^ liBitSize li where
    types = li :: Word64

test_li2x64_bitsize li = liToInteger li < 2 ^ liBitSize li where
    types = li :: Array2 Word64

test_li4x64_bitsize li = liToInteger li < 2 ^ liBitSize li where
    types = li :: Array4 Word64

test_ctr2x32_skip ctr i = liFromInteger (liToInteger ctr + i) == skip i ctr where
    types = (ctr :: Array2 Word32, i :: Integer)

test_ctr4x32_skip ctr i = liFromInteger (liToInteger ctr + i) == skip i ctr where
    types = (ctr :: Array4 Word32, i :: Integer)

test_ctr2x64_skip ctr i = liFromInteger (liToInteger ctr + i) == skip i ctr where
    types = (ctr :: Array2 Word64, i :: Integer)

test_ctr4x64_skip ctr i = liFromInteger (liToInteger ctr + i) == skip i ctr where
    types = (ctr :: Array4 Word64, i :: Integer)

test_ctr2x32_increment ctr = increment ctr == skip 1 ctr where
    types = ctr :: Array2 Word32

test_ctr4x32_increment ctr = increment ctr == skip 1 ctr where
    types = ctr :: Array4 Word32

test_ctr2x64_increment ctr = increment ctr == skip 1 ctr where
    types = ctr :: Array2 Word64

test_ctr4x64_increment ctr = increment ctr == skip 1 ctr where
    types = ctr :: Array4 Word64

test_typeclasses = testGroup "Typeclasses" [
    testGroup "LimitedInteger" [
        testGroup "liFromInteger . liToInteger == id" [
            testProperty "1x32" test_li1x32_bijection,
            testProperty "2x32" test_li2x32_bijection,
            testProperty "4x32" test_li4x32_bijection,
            testProperty "1x64" test_li1x64_bijection,
            testProperty "2x64" test_li2x64_bijection,
            testProperty "4x64" test_li4x64_bijection
            ],
        testGroup "liToInteger < 2 ^ liBitSize" [
            testProperty "1x32" test_li1x32_bitsize,
            testProperty "2x32" test_li2x32_bitsize,
            testProperty "4x32" test_li4x32_bitsize,
            testProperty "1x64" test_li1x64_bitsize,
            testProperty "2x64" test_li2x64_bitsize,
            testProperty "4x64" test_li4x64_bitsize
            ]
        ],
    testGroup "Counter" [
        testGroup "skip behaves like the default implementation" [
            testProperty "2x32" test_ctr2x32_skip,
            testProperty "4x32" test_ctr4x32_skip,
            testProperty "2x64" test_ctr2x64_skip,
            testProperty "4x64" test_ctr4x64_skip
            ],
        testGroup "increment == skip 1" [
            testProperty "2x32" test_ctr2x32_increment,
            testProperty "4x32" test_ctr4x32_increment,
            testProperty "2x64" test_ctr2x64_increment,
            testProperty "4x64" test_ctr4x64_increment
            ]
        ]
    ]


text:
/*****************************************************
 *  FORUM PHPBB STYLE                                *
 *****************************************************/
.forum.table>tbody>tr>td {
	vertical-align: middle;
}

.forum .fa {
	width: 1em;
	text-align: center;
}

.forum.table .btn-action-toolbar, .forum.media-list .btn-action-toolbar
	{
	margin-bottom: 0px;
}

.forum.table .btn-action-toolbar .btn, .forum.media-list .btn-action-toolbar .btn
	{
	padding: 0px 3px;
}

.forum.table .forum-row-icon {
	font-size: 150%;
}

.forum .forum-post-panel {
	margin-bottom: 1em;
}

.forum.media-list li img.avatar {
	display: block;
	margin: 0 auto;
}

.forum.media-list li .user-info {
	text-align: center;
	width: 8em;
}

@media ( max-width : 760px) {
	.forum.media-list li .user-info {
		float: none;
		width: 100%;
		margin-bottom: 1em;
	}
}

.forum.media-list .media-body .media-body-title {
	margin-top: 0px;
	margin-bottom: 5px;
	text-transform: uppercase;
}

ul.tree-menu li div a.forum, ul.tree-menu li div a.type_forum, ul.tree-menu li div a.type_forum_default,
.fancytree-custom-icon.type_forum,
.fancytree-custom-icon.type_forum_default,
	.treeview .list-group .list-group-item .icon.node-icon.type_forum,
	.treeview .list-group .list-group-item .icon.node-icon.type_forum_default
	{
	background-image: url(../../Images/Aqua/Logo/16.png);
}

ul.tree-menu li div a.forum.type_completed, ul.tree-menu li div a.type_forum.type_completed, ul.tree-menu li div a.type_forum_default.type_completed,
.fancytree-custom-icon.type_forum.type_completed,
.fancytree-custom-icon.type_forum_default.type_completed,
.treeview .list-group .list-group-item .icon.node-icon.type_forum.type_completed,
.treeview .list-group .list-group-item .icon.node-icon.type_forum_default.type_completed
{
	background-image: url(../../Images/Aqua/Logo/16Completed.png);
}


text:
package io.wearbook.wlist;

import android.content.Context;
import android.support.wearable.view.WearableListView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

public class MyWearableListViewAdapter extends WearableListView.Adapter {

    private  Context context ;
    private  LayoutInflater layoutInflater ;
    private List<String> listItems ;

    public MyWearableListViewAdapter(Context aContext, LayoutInflater aLayoutInflater, List<String> aListOfItems) {
        this.context = aContext;
        this.layoutInflater = aLayoutInflater;
        this.listItems = aListOfItems ;
    }

    @Override
    public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        WearableListView.ViewHolder retVal = null ;

        retVal = new WearableListView.ViewHolder( layoutInflater.inflate(R.layout.list_item, null));

        return retVal ;
    }

    @Override
    public void onBindViewHolder(WearableListView.ViewHolder holder, int position) {

        TextView view = (TextView) holder.itemView.findViewById(R.id.item_text);
        view.setText(listItems.get(position).toString());
        holder.itemView.setTag(position);

    }

    @Override
    public int getItemCount() {
        return listItems.size();
    }

    private static  final String TAG = MyWearableListViewAdapter.class.toString() ;

}


text:
<resources>
    <string name="app_name">AsposeCloudWordsAndroid</string>
    <string name="action_settings">Settings</string>
</resources>