/*
 * src/po.c
 * https://gitlab.com/bztsrc/assetpack
 *
 * Copyright (C) 2024 bzt, MIT license
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
 * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @brief Handle PO files
 */

#include "main.h"

/**
 * Decode a PO string into an UTF-8 string list
 */
uint8_t *po_decode(uint8_t *buf, uint64_t size, uint64_t *len)
{
    uint8_t *ret = NULL, *end = buf + size, *src, *dst;

    if(!buf || !size || !len || !(ret = (uint8_t*)malloc(size))) return NULL;

    for(src = buf, dst = ret; src < end && *src; src++) {
        if(*src == '#')
            while(src < end && *src && *src != '\n') src++;
        else
        if(!memcmp(src, "msgid", 5) || !memcmp(src, "msgstr", 6)) { if(dst != ret) *dst++ = 0; } else
        if(*src == '\"') {
            for(src++; src < end && *src && *src != '\"'; src++) {
                if(*src == '\\') {
                    src++;
                    switch(*src) {
                        case 'n': *dst++ = '\n'; break;
                        case 't': *dst++ = '\t'; break;
                        case '\'': *dst++ = '\''; break;
                        case '\"': *dst++ = '\"'; break;
                    }
                } else
                    *dst++ = *src;
            }
        }
    }
    *dst++ = 0;
    *len = (uintptr_t)dst - (uintptr_t)ret;
    return ret;
}

/**
 * Encode an UTF-8 string list into PO string
 */
uint8_t *po_encode(uint8_t *buf, uint64_t len, uint64_t *size)
{
    uint8_t *ret = NULL, *end = buf + len, *src, *dst, id = 1;

    if(!buf || !size || !len) return NULL;
    for(src = buf; src < end; src++) {
        if(*src == '\t' || *src == '\'' || *src == '\"') len++;
        if(*src == '\n') len += 6;
        if(!*src) len += 14;
    }
    if(!(ret = (uint8_t*)malloc(len))) return NULL;
    for(src = buf, dst = ret; src < end; src++, id ^= 1) {
        if(id) { memcpy(dst, "msgid \"", 7); dst += 7; }
        else { memcpy(dst, "msgstr \"", 8); dst += 8; }
        for(; src < end && *src; src++)
            switch(*src) {
                case '\n': memcpy(dst, "\\n\"\r\n \"", 7); dst += 7; break;
                case '\t': *dst++ = '\\'; *dst++ = 't'; break;
                case '\'': *dst++ = '\\'; *dst++ = '\''; break;
                case '\"': *dst++ = '\\'; *dst++ = '\"'; break;
                default: *dst++ = *src; break;
            }
        memcpy(dst, "\"\r\n", 3); dst += 3;
        if(!id) { memcpy(dst, "\r\n", 2); dst += 2; }
    }
    *dst = 0;
    *size = (uintptr_t)dst - (uintptr_t)ret;
    return ret;
}

