MOBI_RET mobi_flow_to_link(char *link, const MOBIRawml *rawml, const char *value) {
    /* "kindle:flow:0000?mime=" */
    *link = '\0';
    if (strlen(value) < (sizeof("kindle:flow:0000?mime=") - 1)) {
        debug_print("Skipping too short link: %s\n", value);
        return MOBI_SUCCESS;
    }
    value += (sizeof("kindle:flow:") - 1);
    if (value[4] != '?') {
        debug_print("Skipping broken link: kindle:flow:%s\n", value);
        return MOBI_SUCCESS;
    }
    char str_fid[4 + 1];
    strncpy(str_fid, value, 4);
    str_fid[4] = '\0';
    
    MOBIPart *flow = mobi_get_flow_by_fid(rawml, str_fid);
    if (flow == NULL) {
        debug_print("Skipping broken link (missing resource): kindle:flow:%s\n", value);
        return MOBI_SUCCESS;
    }
    MOBIFileMeta meta = mobi_get_filemeta_by_type(flow->type);
    char *extension = meta.extension;
    snprintf(link, MOBI_ATTRVALUE_MAXSIZE + 1, "\"flow%05zu.%s\"", flow->uid, extension);
    return MOBI_SUCCESS;
}
MOBI_RET mobi_flow_to_link(char *link, const MOBIRawml *rawml, const char *value) {
     
    *link = '\0';
    if (strlen(value) < (sizeof("kindle:flow:0000?mime=") - 1)) {
        debug_print("Skipping too short link: %s\n", value);
        return MOBI_SUCCESS;
    }
    value += (sizeof("kindle:flow:") - 1);
    if (value[4] != '?') {
        debug_print("Skipping broken link: kindle:flow:%s\n", value);
        return MOBI_SUCCESS;
    }
    char str_fid[4 + 1];
    strncpy(str_fid, value, 4);
    str_fid[4] = '\0';
    
    MOBIPart *flow = mobi_get_flow_by_fid(rawml, str_fid);
    if (flow == NULL) {
        debug_print("Skipping broken link (missing resource): kindle:flow:%s\n", value);
        return MOBI_SUCCESS;
    }
    MOBIFileMeta meta = mobi_get_filemeta_by_type(flow->type);
    char *extension = meta.extension;
    snprintf(link, MOBI_ATTRVALUE_MAXSIZE + 1, "\"flow%05zu.%s\"", flow->uid, extension);
    return MOBI_SUCCESS;
}