]> pd.if.org Git - pdclib/commitdiff
PDCLIB-2 PDCLIB-12: Add Latin-1 codec
authorOwen Shepherd <owen.shepherd@e43.eu>
Sun, 30 Dec 2012 20:37:30 +0000 (20:37 +0000)
committerOwen Shepherd <owen.shepherd@e43.eu>
Sun, 30 Dec 2012 20:37:30 +0000 (20:37 +0000)
opt/basecodecs/_PDCLIB_latin1.c [new file with mode: 0644]

diff --git a/opt/basecodecs/_PDCLIB_latin1.c b/opt/basecodecs/_PDCLIB_latin1.c
new file mode 100644 (file)
index 0000000..73844f4
--- /dev/null
@@ -0,0 +1,108 @@
+/* Latin-1 codec
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdbool.h>
+#ifndef REGTEST
+#include <uchar.h>
+
+static bool latin1toc32(
+    char32_t       **restrict   p_outbuf,
+    size_t          *restrict   p_outsz,
+    const char     **restrict   p_inbuf,
+    size_t          *restrict   p_insz,
+    mbstate_t       *restrict   p_ps
+)
+{
+    while(*p_outsz && *p_insz) {
+        unsigned char c = **p_inbuf;
+        **p_outbuf = c;
+
+        (*p_inbuf)++;
+        (*p_outbuf)++; 
+        (*p_insz)--; 
+        (*p_outsz)--;
+    }
+    return true;
+}
+
+static bool c32tolatin1(
+    char           **restrict  p_outbuf,
+    size_t          *restrict  p_outsz,
+    const char32_t **restrict  p_inbuf,
+    size_t          *restrict  p_insz,
+    mbstate_t       *restrict  p_ps
+)
+{
+    while(*p_outsz && *p_insz) {
+        char32_t c = **p_inbuf;
+        if(c > 255)
+            return false;
+        **p_outbuf = c;
+
+        (*p_inbuf)++;
+        (*p_outbuf)++; 
+        (*p_insz)--; 
+        (*p_outsz)--;        
+    }
+    return true;
+}
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+#ifndef REGTEST
+    // Valid conversion & back
+
+    char32_t c32out[5];
+
+    char32_t *c32ptr = &c32out[0];
+    size_t    c32rem = 5;
+    char     *chrptr = (char*) &abcde[0];
+    size_t    chrrem = 5;
+    mbstate_t mbs = { 0 };
+
+    TESTCASE(latin1toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true);
+    TESTCASE(c32rem == 0);
+    TESTCASE(chrrem == 0);
+    TESTCASE(c32ptr == &c32out[5]);
+    TESTCASE(chrptr == &abcde[5]);
+    TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \
+             c32out[3] == 'd' && c32out[4] == 'e');
+
+    char chrout[5];
+    c32ptr = &c32out[0];
+    c32rem = 5;
+    chrptr = &chrout[0];
+    chrrem = 5;
+
+
+    TESTCASE(c32tolatin1(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true);
+    TESTCASE(c32rem == 0);
+    TESTCASE(chrrem == 0);
+    TESTCASE(c32ptr == &c32out[5]);
+    TESTCASE(chrptr == &chrout[5]);
+    TESTCASE(memcmp(chrout, abcde, 5) == 0);
+
+    // Invalid conversions
+    char32_t baduni = 0xFFFE;
+    c32ptr = &baduni;
+    c32rem = 1;
+    chrptr = &chrout[0];
+    chrrem = 5;
+    TESTCASE(c32tolatin1(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false);
+    TESTCASE(c32ptr == &baduni);
+    TESTCASE(c32rem == 1);
+    TESTCASE(chrptr == &chrout[0]);
+    TESTCASE(chrrem == 5);
+#endif
+    return TEST_RESULTS;
+}
+
+#endif
+