Skip to content

Instantly share code, notes, and snippets.

@pavly-gerges
Last active October 5, 2025 00:01
Show Gist options
  • Save pavly-gerges/8f27443309daf4130cde4257dc88b4d1 to your computer and use it in GitHub Desktop.
Save pavly-gerges/8f27443309daf4130cde4257dc88b4d1 to your computer and use it in GitHub Desktop.

Constructional Design using State Machines

Author: Pavl G.

This document establishes a constructional design for a low-level IO API that operates on filesystems of all types; the constructional design is completely based on the computational automata theory, that focuses particularly on designing machines that automate algorithms with {predefined set of states $$Q$$, initial state $$q$$, transitioning function $$\delta$$, set of input symbols $$\Sigma$$, set of final accepting states $$F$$}. Conceptually, a language $$L$$ could be accepted from these set of final accepting states (e.g., on_eof_reached and on_error_encountered); the language $$L_M$$ is a set of all strings that could be recognized by its machine $$M$$; whose alphabets are the $$\Sigma$$.

Note

In this API; the language could be all the available strings for read/write IO operations from and to a filesystem. In which, the start string (or char depending on the implementation of the state machines) is the

The following is the an example for the implementation of the file_read algorithm that utilizes a dynamic way of determining the number of bytes to read using the file stat attributes:

image
/**
 * @brief A tech=demo for the implementation of the file reading algorithm that provides a dynamic algorithm of determining the number of bytes to read out of a file using the file stat attributes from the Unix Standard library by requesting a call to the file status utility.
 * @author pavl_g.
 * @date 10-2025
 */
#include <electrostatic/electronetsoft/util/filesystem/file_operations.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

static inline void update_file_postprocessor(file_mem *mem) {
    if (NULL == mem || mem->fd < 0) {
        return;
    }
    if (mem->n_bytes <= 0) {
        mem->n_bytes = 1;
    }
    fprintf(stdout, "Size of memory buffer (in bytes) = %zd\n",
            mem->n_bytes);
    mem->buffer = calloc(mem->n_bytes, sizeof (char));

    if (NULL == mem->buffer) {
        return;
    }
}

static inline void on_read_bytes(file_mem *mem, ssize_t bytes) {
    fprintf(stdout, "Read Bytes: %s", mem->buffer);
}

static inline void on_eof_reached(file_mem *mem) {
    fprintf(stdout, "Read Bytes after EOF: %s\n", mem->buffer);
    fprintf(stdout, "EOF Reached!\n");
    // deallocates memory here!
    if (NULL != mem->buffer) {
        free(mem->buffer);
        mem->buffer = NULL;
    }
}

int main() {
    fprintf(stdout, "Hello Fle Read Automata!\n");

    int fd = open("/home/pavl-g/Desktop/Glossary_for_AI", O_RDWR);

    if (fd < 0) {
        fprintf(stderr, "Error Encountered: %s\n", strerror(errno));
        exit(errno);
    }

    file_mem _file_mem = {
            .fd = fd,
            .trailing = '9',
            .buffer = NULL,
            .n_bytes = -1,
            .file_size = -1,
            .file_pos = -1
    };

    file_op_processor __processor = {
        .update_file_postprocessor = &update_file_postprocessor,
        .on_read_bytes = &on_read_bytes,
        .on_eof_reached = &on_eof_reached
    };

    status_code __status = read_into_mem(&_file_mem, &__processor);

    if (PASS != __status) {
        fprintf(stderr, "Error Encountered: %s\n", strerror(__status));
        exit(__status);
    }

    return 0;
}

[file_read.c]

#include <electrostatic/electronetsoft/util/filesystem/file_operations.h>
#include <electrostatic/electronetsoft/util/filesystem/file_status.h>

status_code read_into_mem(file_mem *mem, file_op_processor *processor) {
    // pre-processing automata -- Input validation
    if (mem->fd < 0) {
        return EUNDEFINEDBUFFER;
    }

    if (NULL != mem->buffer) {
        return -1;
    }

    // pre-processing automata -- Calculating the file size, current position,
                                // and the number of bytes to read
    status_code ___status = update_file_attrs(mem, processor);
    if (PASS != ___status) {
        return ___status;
    }

    if (NULL == mem->buffer) {
        return EUNDEFINEDBUFFER;
    }

    // processing automata -- Reading n_bytes into heap buffer
    //                        starting from the current file position
    while (1) {
        ssize_t read_bytes = 0;
        read_bytes = read(mem->fd, (mem->buffer + read_bytes), (mem->n_bytes - 1));
        // post processing automata
        if (-1 == read_bytes) {
            // terminated with error; report error!
            if (NULL != processor && NULL != processor->on_error_encountered) {
                processor->on_error_encountered(mem, errno);
            }
            return errno;
        } else if (0 == read_bytes) {
            // EOF terminate!
            mem->buffer[mem->n_bytes - 1] = mem->trailing; /* add a null-terminating character */
            if (NULL != processor && NULL != processor->on_eof_reached) {
                processor->on_eof_reached(mem);
            }
            return PASS;
        } else if (read_bytes > 0) {
            // execute on_read
            if (NULL != processor && NULL != processor->on_read_bytes) {
                processor->on_read_bytes(mem, read_bytes);
            }
        }
    }
    return ASSERTION_FAILURE;
}
digraph FileReadingFSM {
rankdir=LR;
node [shape=circle, style=filled, fillcolor="#e6f2ff"];
// States
S0 [label="S0\nStart"];
S1 [label="S1\nfd < 0?"];
S2 [label="S2\nbuffer != NULL?"];
S3 [label="S3\nupdate_file_attrs"];
S4 [label="S4\nPASS?"];
S5 [label="S5\nbuffer == NULL?"];
S6 [label="S6\nRead Loop"];
S7 [label="S7\nread == -1"];
S8 [label="S8\nread == 0"];
S9 [label="S9\nread > 0"];
S10 [label="S10\nError Terminate", shape=doublecircle, fillcolor="#ffe6e6"];
S11 [label="S11\nEOF Terminate", shape=doublecircle, fillcolor="#e6ffe6"];
S12 [label="S12\nRead Callback"];
S13 [label="S13\nFinal", shape=doublecircle, fillcolor="#ffe6e6"];
// Transitions (pre-processing)
S0 -> S1 [label="entry"];
S1 -> S10 [label="fd < 0"];
S1 -> S2 [label="fd >= 0"];
S2 -> S10 [label="buffer != NULL"];
S2 -> S3 [label="buffer == NULL"];
S3 -> S4 [label="call update_file_attrs"];
S4 -> S10 [label="PASS != status"];
S4 -> S5 [label="PASS == status"];
S5 -> S10 [label="buffer == NULL"];
S5 -> S6 [label="buffer != NULL"];
// Read loop transitions
S6 -> S7 [label="read == -1"];
S6 -> S8 [label="read == 0"];
S6 -> S9 [label="read > 0"];
S7 -> S10 [label="on_error_encountered"];
S8 -> S11 [label="on_eof_reached"];
S9 -> S12 [label="on_read_bytes"];
S12 -> S6 [label="loop"];
// Termination
S10 -> S13 [label="return error"];
S11 -> S13 [label="return PASS"];
S6 -> S13 [label="ASSERTION_FAILURE (unreachable)"];
// Final state
S13 [shape=doublecircle, fillcolor="#ffe6e6"];
}
Display the source blob
Display the rendered blob
Raw
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="2326pt" height="734pt" viewBox="0.00 0.00 2326.00 734.00">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 729.9)">
<title>FileReadingFSM</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-729.9 2321.66,-729.9 2321.66,4 -4,4"/>
<!-- S0 -->
<g id="node1" class="node">
<title>S0</title>
<ellipse fill="#e6f2ff" stroke="black" cx="30.01" cy="-39.44" rx="30.01" ry="30.01"/>
<text xml:space="preserve" text-anchor="middle" x="30.01" y="-43.64" font-family="Times,serif" font-size="14.00">S0</text>
<text xml:space="preserve" text-anchor="middle" x="30.01" y="-26.84" font-family="Times,serif" font-size="14.00">Start</text>
</g>
<!-- S1 -->
<g id="node2" class="node">
<title>S1</title>
<ellipse fill="#e6f2ff" stroke="black" cx="164.22" cy="-39.44" rx="39.44" ry="39.44"/>
<text xml:space="preserve" text-anchor="middle" x="164.22" y="-43.64" font-family="Times,serif" font-size="14.00">S1</text>
<text xml:space="preserve" text-anchor="middle" x="164.22" y="-26.84" font-family="Times,serif" font-size="14.00">fd &lt; 0?</text>
</g>
<!-- S0&#45;&gt;S1 -->
<g id="edge1" class="edge">
<title>S0-&gt;S1</title>
<path fill="none" stroke="black" d="M60.35,-39.44C75.83,-39.44 95.25,-39.44 113.03,-39.44"/>
<polygon fill="black" stroke="black" points="112.91,-42.94 122.91,-39.44 112.91,-35.94 112.91,-42.94"/>
<text xml:space="preserve" text-anchor="middle" x="92.4" y="-43.64" font-family="Times,serif" font-size="14.00">entry</text>
</g>
<!-- S2 -->
<g id="node3" class="node">
<title>S2</title>
<ellipse fill="#e6f2ff" stroke="black" cx="361.23" cy="-131.44" rx="80.11" ry="80.11"/>
<text xml:space="preserve" text-anchor="middle" x="361.23" y="-135.64" font-family="Times,serif" font-size="14.00">S2</text>
<text xml:space="preserve" text-anchor="middle" x="361.23" y="-118.84" font-family="Times,serif" font-size="14.00">buffer != NULL?</text>
</g>
<!-- S1&#45;&gt;S2 -->
<g id="edge3" class="edge">
<title>S1-&gt;S2</title>
<path fill="none" stroke="black" d="M200.09,-55.88C221.84,-66.15 250.82,-79.82 278.14,-92.71"/>
<polygon fill="black" stroke="black" points="276.61,-95.86 287.14,-96.96 279.59,-89.53 276.61,-95.86"/>
<text xml:space="preserve" text-anchor="middle" x="242.39" y="-89.64" font-family="Times,serif" font-size="14.00">fd &gt;= 0</text>
</g>
<!-- S10 -->
<g id="node11" class="node">
<title>S10</title>
<ellipse fill="#ffe6e6" stroke="black" cx="2060.58" cy="-220.44" rx="75.35" ry="75.35"/>
<ellipse fill="none" stroke="black" cx="2060.58" cy="-220.44" rx="79.35" ry="79.35"/>
<text xml:space="preserve" text-anchor="middle" x="2060.58" y="-224.64" font-family="Times,serif" font-size="14.00">S10</text>
<text xml:space="preserve" text-anchor="middle" x="2060.58" y="-207.84" font-family="Times,serif" font-size="14.00">Error Terminate</text>
</g>
<!-- S1&#45;&gt;S10 -->
<g id="edge2" class="edge">
<title>S1-&gt;S10</title>
<path fill="none" stroke="black" d="M203.63,-34.42C242.9,-29.73 305.71,-23.44 360.23,-23.44 360.23,-23.44 360.23,-23.44 1669.96,-23.44 1802.18,-23.44 1852.61,-1 1963.23,-73.44 1987.57,-89.37 2007.15,-113.83 2022.13,-138.25"/>
<polygon fill="black" stroke="black" points="2018.99,-139.81 2027.08,-146.65 2025.02,-136.26 2018.99,-139.81"/>
<text xml:space="preserve" text-anchor="middle" x="1021.93" y="-27.64" font-family="Times,serif" font-size="14.00">fd &lt; 0</text>
</g>
<!-- S3 -->
<g id="node4" class="node">
<title>S3</title>
<ellipse fill="#e6f2ff" stroke="black" cx="649.49" cy="-180.44" rx="77.84" ry="77.84"/>
<text xml:space="preserve" text-anchor="middle" x="649.49" y="-184.64" font-family="Times,serif" font-size="14.00">S3</text>
<text xml:space="preserve" text-anchor="middle" x="649.49" y="-167.84" font-family="Times,serif" font-size="14.00">update_file_attrs</text>
</g>
<!-- S2&#45;&gt;S3 -->
<g id="edge5" class="edge">
<title>S2-&gt;S3</title>
<path fill="none" stroke="black" d="M440.45,-144.83C477.81,-151.22 522.67,-158.9 561.14,-165.49"/>
<polygon fill="black" stroke="black" points="560.4,-168.91 570.85,-167.15 561.58,-162.01 560.4,-168.91"/>
<text xml:space="preserve" text-anchor="middle" x="506.5" y="-167.39" font-family="Times,serif" font-size="14.00">buffer == NULL</text>
</g>
<!-- S2&#45;&gt;S10 -->
<g id="edge4" class="edge">
<title>S2-&gt;S10</title>
<path fill="none" stroke="black" d="M437.51,-105.95C494.69,-88.85 575.64,-69.44 648.49,-69.44 648.49,-69.44 648.49,-69.44 1669.96,-69.44 1785.44,-69.44 1907.96,-127.83 1984.11,-171.99"/>
<polygon fill="black" stroke="black" points="1981.92,-174.76 1992.32,-176.8 1985.47,-168.72 1981.92,-174.76"/>
<text xml:space="preserve" text-anchor="middle" x="1166.4" y="-73.64" font-family="Times,serif" font-size="14.00">buffer != NULL</text>
</g>
<!-- S4 -->
<g id="node5" class="node">
<title>S4</title>
<ellipse fill="#e6f2ff" stroke="black" cx="920.48" cy="-186.44" rx="39.37" ry="39.37"/>
<text xml:space="preserve" text-anchor="middle" x="920.48" y="-190.64" font-family="Times,serif" font-size="14.00">S4</text>
<text xml:space="preserve" text-anchor="middle" x="920.48" y="-173.84" font-family="Times,serif" font-size="14.00">PASS?</text>
</g>
<!-- S3&#45;&gt;S4 -->
<g id="edge6" class="edge">
<title>S3-&gt;S4</title>
<path fill="none" stroke="black" d="M727.57,-182.16C773.21,-183.17 829.71,-184.43 869.55,-185.32"/>
<polygon fill="black" stroke="black" points="869.25,-188.82 879.32,-185.54 869.4,-181.82 869.25,-188.82"/>
<text xml:space="preserve" text-anchor="middle" x="804.22" y="-189.34" font-family="Times,serif" font-size="14.00">call update_file_attrs</text>
</g>
<!-- S5 -->
<g id="node6" class="node">
<title>S5</title>
<ellipse fill="#e6f2ff" stroke="black" cx="1166.4" cy="-186.44" rx="82.4" ry="82.4"/>
<text xml:space="preserve" text-anchor="middle" x="1166.4" y="-190.64" font-family="Times,serif" font-size="14.00">S5</text>
<text xml:space="preserve" text-anchor="middle" x="1166.4" y="-173.84" font-family="Times,serif" font-size="14.00">buffer == NULL?</text>
</g>
<!-- S4&#45;&gt;S5 -->
<g id="edge8" class="edge">
<title>S4-&gt;S5</title>
<path fill="none" stroke="black" d="M960.13,-186.44C990.21,-186.44 1033.23,-186.44 1072.13,-186.44"/>
<polygon fill="black" stroke="black" points="1072,-189.94 1082,-186.44 1072,-182.94 1072,-189.94"/>
<text xml:space="preserve" text-anchor="middle" x="1021.93" y="-190.64" font-family="Times,serif" font-size="14.00">PASS == status</text>
</g>
<!-- S4&#45;&gt;S10 -->
<g id="edge7" class="edge">
<title>S4-&gt;S10</title>
<path fill="none" stroke="black" d="M952.37,-210.14C983.61,-232.5 1034.25,-264.46 1084,-277.44 1154.87,-295.93 1175.6,-280.01 1248.8,-277.44 1511.14,-268.23 1820.35,-242.3 1969.78,-228.82"/>
<polygon fill="black" stroke="black" points="1969.98,-232.32 1979.62,-227.93 1969.34,-225.34 1969.98,-232.32"/>
<text xml:space="preserve" text-anchor="middle" x="1430.91" y="-275.97" font-family="Times,serif" font-size="14.00">PASS != status</text>
</g>
<!-- S6 -->
<g id="node7" class="node">
<title>S6</title>
<ellipse fill="#e6f2ff" stroke="black" cx="1430.91" cy="-437.44" rx="55.03" ry="55.03"/>
<text xml:space="preserve" text-anchor="middle" x="1430.91" y="-441.64" font-family="Times,serif" font-size="14.00">S6</text>
<text xml:space="preserve" text-anchor="middle" x="1430.91" y="-424.84" font-family="Times,serif" font-size="14.00">Read Loop</text>
</g>
<!-- S5&#45;&gt;S6 -->
<g id="edge10" class="edge">
<title>S5-&gt;S6</title>
<path fill="none" stroke="black" d="M1226.64,-243.08C1273.66,-288.04 1338.55,-350.08 1382.25,-391.87"/>
<polygon fill="black" stroke="black" points="1379.69,-394.26 1389.33,-398.64 1384.52,-389.2 1379.69,-394.26"/>
<text xml:space="preserve" text-anchor="middle" x="1312.34" y="-367.47" font-family="Times,serif" font-size="14.00">buffer != NULL</text>
</g>
<!-- S5&#45;&gt;S10 -->
<g id="edge9" class="edge">
<title>S5-&gt;S10</title>
<path fill="none" stroke="black" d="M1248.94,-189.54C1415.86,-195.9 1795.38,-210.37 1969.38,-217"/>
<polygon fill="black" stroke="black" points="1969.16,-220.49 1979.28,-217.38 1969.42,-213.5 1969.16,-220.49"/>
<text xml:space="preserve" text-anchor="middle" x="1551.09" y="-206.85" font-family="Times,serif" font-size="14.00">buffer == NULL</text>
</g>
<!-- S7 -->
<g id="node8" class="node">
<title>S7</title>
<ellipse fill="#e6f2ff" stroke="black" cx="1668.96" cy="-320.44" rx="52.71" ry="52.71"/>
<text xml:space="preserve" text-anchor="middle" x="1668.96" y="-324.64" font-family="Times,serif" font-size="14.00">S7</text>
<text xml:space="preserve" text-anchor="middle" x="1668.96" y="-307.84" font-family="Times,serif" font-size="14.00">read == -1</text>
</g>
<!-- S6&#45;&gt;S7 -->
<g id="edge11" class="edge">
<title>S6-&gt;S7</title>
<path fill="none" stroke="black" d="M1472.04,-400.65C1481.99,-392.69 1492.96,-384.81 1503.93,-378.64 1536.08,-360.53 1574.88,-346.46 1606.67,-336.69"/>
<polygon fill="black" stroke="black" points="1607.57,-340.07 1616.15,-333.85 1605.56,-333.37 1607.57,-340.07"/>
<text xml:space="preserve" text-anchor="middle" x="1551.09" y="-382.84" font-family="Times,serif" font-size="14.00">read == -1</text>
</g>
<!-- S8 -->
<g id="node9" class="node">
<title>S8</title>
<ellipse fill="#e6f2ff" stroke="black" cx="1668.96" cy="-599.44" rx="49.41" ry="49.41"/>
<text xml:space="preserve" text-anchor="middle" x="1668.96" y="-603.64" font-family="Times,serif" font-size="14.00">S8</text>
<text xml:space="preserve" text-anchor="middle" x="1668.96" y="-586.84" font-family="Times,serif" font-size="14.00">read == 0</text>
</g>
<!-- S6&#45;&gt;S8 -->
<g id="edge12" class="edge">
<title>S6-&gt;S8</title>
<path fill="none" stroke="black" d="M1474.02,-471.91C1483.71,-479.52 1494.07,-487.4 1503.93,-494.44 1540.77,-520.7 1583.9,-548.19 1616.69,-568.45"/>
<polygon fill="black" stroke="black" points="1614.44,-571.18 1624.79,-573.44 1618.11,-565.22 1614.44,-571.18"/>
<text xml:space="preserve" text-anchor="middle" x="1551.09" y="-559.94" font-family="Times,serif" font-size="14.00">read == 0</text>
</g>
<!-- S9 -->
<g id="node10" class="node">
<title>S9</title>
<ellipse fill="#e6f2ff" stroke="black" cx="1668.96" cy="-488.44" rx="43.83" ry="43.83"/>
<text xml:space="preserve" text-anchor="middle" x="1668.96" y="-492.64" font-family="Times,serif" font-size="14.00">S9</text>
<text xml:space="preserve" text-anchor="middle" x="1668.96" y="-475.84" font-family="Times,serif" font-size="14.00">read &gt; 0</text>
</g>
<!-- S6&#45;&gt;S9 -->
<g id="edge13" class="edge">
<title>S6-&gt;S9</title>
<path fill="none" stroke="black" d="M1485.18,-448.95C1523.91,-457.31 1576.13,-468.6 1614.83,-476.96"/>
<polygon fill="black" stroke="black" points="1613.88,-480.33 1624.4,-479.02 1615.36,-473.49 1613.88,-480.33"/>
<text xml:space="preserve" text-anchor="middle" x="1551.09" y="-477.57" font-family="Times,serif" font-size="14.00">read &gt; 0</text>
</g>
<!-- S13 -->
<g id="node14" class="node">
<title>S13</title>
<ellipse fill="#ffe6e6" stroke="black" cx="2281.99" cy="-573.44" rx="31.66" ry="31.66"/>
<ellipse fill="none" stroke="black" cx="2281.99" cy="-573.44" rx="35.66" ry="35.66"/>
<text xml:space="preserve" text-anchor="middle" x="2281.99" y="-577.64" font-family="Times,serif" font-size="14.00">S13</text>
<text xml:space="preserve" text-anchor="middle" x="2281.99" y="-560.84" font-family="Times,serif" font-size="14.00">Final</text>
</g>
<!-- S6&#45;&gt;S13 -->
<g id="edge20" class="edge">
<title>S6-&gt;S13</title>
<path fill="none" stroke="black" d="M1451.6,-488.84C1463.9,-516.7 1481.65,-550.61 1503.93,-576.44 1544.15,-623.03 1557.73,-638.36 1616.25,-657.44 1837.54,-729.58 1915.85,-722.36 2139.93,-659.44 2178.96,-648.48 2217.89,-623.41 2244.94,-603.14"/>
<polygon fill="black" stroke="black" points="2246.98,-605.99 2252.79,-597.13 2242.72,-600.43 2246.98,-605.99"/>
<text xml:space="preserve" text-anchor="middle" x="1851.45" y="-713.3" font-family="Times,serif" font-size="14.00">ASSERTION_FAILURE (unreachable)</text>
</g>
<!-- S7&#45;&gt;S10 -->
<g id="edge14" class="edge">
<title>S7-&gt;S10</title>
<path fill="none" stroke="black" d="M1720.97,-310.48C1779.8,-298.61 1879.22,-277.35 1963.23,-253.44 1966.96,-252.38 1970.75,-251.25 1974.58,-250.09"/>
<polygon fill="black" stroke="black" points="1975.45,-253.49 1983.95,-247.17 1973.36,-246.8 1975.45,-253.49"/>
<text xml:space="preserve" text-anchor="middle" x="1851.45" y="-310.34" font-family="Times,serif" font-size="14.00">on_error_encountered</text>
</g>
<!-- S11 -->
<g id="node12" class="node">
<title>S11</title>
<ellipse fill="#e6ffe6" stroke="black" cx="2060.58" cy="-573.44" rx="73.17" ry="73.17"/>
<ellipse fill="none" stroke="black" cx="2060.58" cy="-573.44" rx="77.17" ry="77.17"/>
<text xml:space="preserve" text-anchor="middle" x="2060.58" y="-577.64" font-family="Times,serif" font-size="14.00">S11</text>
<text xml:space="preserve" text-anchor="middle" x="2060.58" y="-560.84" font-family="Times,serif" font-size="14.00">EOF Terminate</text>
</g>
<!-- S8&#45;&gt;S11 -->
<g id="edge15" class="edge">
<title>S8-&gt;S11</title>
<path fill="none" stroke="black" d="M1718.52,-596.2C1781.8,-591.97 1893.62,-584.51 1971.92,-579.29"/>
<polygon fill="black" stroke="black" points="1971.96,-582.79 1981.71,-578.63 1971.5,-575.81 1971.96,-582.79"/>
<text xml:space="preserve" text-anchor="middle" x="1851.45" y="-598.66" font-family="Times,serif" font-size="14.00">on_eof_reached</text>
</g>
<!-- S12 -->
<g id="node13" class="node">
<title>S12</title>
<ellipse fill="#e6f2ff" stroke="black" cx="2060.58" cy="-409.44" rx="69.31" ry="69.31"/>
<text xml:space="preserve" text-anchor="middle" x="2060.58" y="-413.64" font-family="Times,serif" font-size="14.00">S12</text>
<text xml:space="preserve" text-anchor="middle" x="2060.58" y="-396.84" font-family="Times,serif" font-size="14.00">Read Callback</text>
</g>
<!-- S9&#45;&gt;S12 -->
<g id="edge16" class="edge">
<title>S9-&gt;S12</title>
<path fill="none" stroke="black" d="M1712.4,-479.83C1776.73,-466.79 1899.99,-441.8 1980.99,-425.37"/>
<polygon fill="black" stroke="black" points="1981.54,-428.83 1990.65,-423.41 1980.15,-421.97 1981.54,-428.83"/>
<text xml:space="preserve" text-anchor="middle" x="1851.45" y="-477.52" font-family="Times,serif" font-size="14.00">on_read_bytes</text>
</g>
<!-- S10&#45;&gt;S13 -->
<g id="edge18" class="edge">
<title>S10-&gt;S13</title>
<path fill="none" stroke="black" d="M2108.12,-284.35C2118.83,-299.61 2129.99,-315.96 2139.93,-331.44 2184.36,-400.57 2231.6,-483.87 2258.58,-532.52"/>
<polygon fill="black" stroke="black" points="2255.38,-533.98 2263.29,-541.04 2261.51,-530.59 2255.38,-533.98"/>
<text xml:space="preserve" text-anchor="middle" x="2193.13" y="-478.31" font-family="Times,serif" font-size="14.00">return error</text>
</g>
<!-- S11&#45;&gt;S13 -->
<g id="edge19" class="edge">
<title>S11-&gt;S13</title>
<path fill="none" stroke="black" d="M2138.01,-573.44C2170.15,-573.44 2206.5,-573.44 2234.51,-573.44"/>
<polygon fill="black" stroke="black" points="2234.45,-576.94 2244.45,-573.44 2234.45,-569.94 2234.45,-576.94"/>
<text xml:space="preserve" text-anchor="middle" x="2193.13" y="-577.64" font-family="Times,serif" font-size="14.00">return PASS</text>
</g>
<!-- S12&#45;&gt;S6 -->
<g id="edge17" class="edge">
<title>S12-&gt;S6</title>
<path fill="none" stroke="black" d="M1990.78,-409.14C1903.56,-409.17 1748.61,-410.53 1616.25,-418.64 1576.55,-421.07 1532.21,-425.54 1496.96,-429.51"/>
<polygon fill="black" stroke="black" points="1496.9,-425.99 1487.36,-430.6 1497.69,-432.94 1496.9,-425.99"/>
<text xml:space="preserve" text-anchor="middle" x="1668.96" y="-422.84" font-family="Times,serif" font-size="14.00">loop</text>
</g>
</g>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment