OSDN Git Service

implement x-www-form-urlencoded encoder.
authorornse01 <ornse01@users.sourceforge.jp>
Wed, 18 Mar 2015 15:42:59 +0000 (15:42 +0000)
committerornse01 <ornse01@users.sourceforge.jp>
Wed, 18 Mar 2015 15:42:59 +0000 (15:42 +0000)
git-svn-id: http://svn.sourceforge.jp/svnroot/bchan/bchanf/trunk@665 20a0b8eb-f62a-4a12-8fe1-b598822500fb

src/coding/htmlform_urlencoder.c [new file with mode: 0644]
src/coding/htmlform_urlencoder.h [new file with mode: 0644]
src/coding/test_htmlform_urlencoder.c [new file with mode: 0644]

diff --git a/src/coding/htmlform_urlencoder.c b/src/coding/htmlform_urlencoder.c
new file mode 100644 (file)
index 0000000..abe780d
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * htmlform_urlencoder.c
+ *
+ * Copyright (c) 2015 project bchan
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ *    distribution.
+ *
+ */
+
+#include "htmlform_urlencoder.h"
+
+#include       <basic.h>
+#include       <bctype.h>
+
+#ifdef BCHAN_CONFIG_DEBUG
+# define DP(arg) printf arg
+# define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
+#else
+# define DP(arg) /**/
+# define DP_ER(msg, err) /**/
+#endif
+
+#if 0
+# define DP_STATE(state) printf("%s\n", state)
+#else
+# define DP_STATE(state) /**/
+#endif
+
+LOCAL VOID htmlform_urlencoder_convert(htmlform_urlencoder_t *encoder, UB ch, UB **str, W *len)
+{
+       static UB num[] = "0123456789ABCDEF";
+       UB *buffer = encoder->buf;
+
+       if (ch == 0x2E) { /* '.' */
+               buffer[0] = ch;
+               *len = 1;
+       } else if (ch == 0x2D) { /* '-' */
+               buffer[0] = ch;
+               *len = 1;
+       } else if (ch == 0x5F) { /* '_' */
+               buffer[0] = ch;
+               *len = 1;
+       } else if (ch == 0x20) { /* ' ' */
+               buffer[0] = 0x2B; /* '+' */
+               *len = 1;
+       } else if (isalnum(ch)) {
+               buffer[0] = ch;
+               *len = 1;
+       } else {
+               buffer[0] = 0x25; /* '%' */
+               buffer[1] = num[ch >> 4];
+               buffer[2] = num[ch & 0xF];
+               *len = 3;
+       }
+
+       *str = buffer;
+}
+
+LOCAL UB equal[] = "=";
+LOCAL UB amp[] = "&";
+
+EXPORT Bool htmlform_urlencoder_next(htmlform_urlencoder_t *encoder, UB **str, W *len)
+{
+       htmlform_field *field;
+
+       if (encoder->field_index == encoder->fields_len) {
+               return False;
+       }
+
+       field = encoder->fields + encoder->field_index;
+
+       switch (encoder->state) {
+       case HTMLFORM_URLENCODER_STATE_NAME:
+               DP_STATE("NAME");
+               htmlform_urlencoder_convert(encoder, field->name[encoder->src_pos], str, len);
+               encoder->src_pos++;
+               if (encoder->src_pos == field->name_len) {
+                       encoder->state = HTMLFORM_URLENCODER_STATE_EQUAL;
+               }
+               return True;
+       case HTMLFORM_URLENCODER_STATE_EQUAL:
+               DP_STATE("EQUAL");
+               *str = equal;
+               *len = 1;
+               encoder->state = HTMLFORM_URLENCODER_STATE_VALUE;
+               encoder->src_pos = 0;
+               return True;
+       case HTMLFORM_URLENCODER_STATE_VALUE:
+               DP_STATE("VALUE");
+               htmlform_urlencoder_convert(encoder, field->value[encoder->src_pos], str, len);
+               encoder->src_pos++;
+               if (encoder->src_pos == field->value_len) {
+                       encoder->state = HTMLFORM_URLENCODER_STATE_AMP;
+                       encoder->field_index++;
+               }
+               return True;
+       case HTMLFORM_URLENCODER_STATE_AMP:
+               DP_STATE("AMP");
+               *str = amp;
+               *len = 1;
+               encoder->state = HTMLFORM_URLENCODER_STATE_NAME;
+               encoder->src_pos = 0;
+               return True;
+       }
+
+       return False;
+}
+
+EXPORT VOID htmlform_urlencoder_initialize(htmlform_urlencoder_t *encoder, htmlform_field *fields, W fields_len)
+{
+       encoder->fields = fields;
+       encoder->fields_len = fields_len;
+       encoder->state = HTMLFORM_URLENCODER_STATE_NAME;
+       encoder->field_index = 0;
+       encoder->src_pos = 0;
+}
+
+EXPORT VOID htmlform_urlencoder_finalize(htmlform_urlencoder_t *encoder)
+{
+}
diff --git a/src/coding/htmlform_urlencoder.h b/src/coding/htmlform_urlencoder.h
new file mode 100644 (file)
index 0000000..b2a666f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * htmlform_urlencoder.h
+ *
+ * Copyright (c) 2015 project bchan
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ *    distribution.
+ *
+ */
+
+/* http://tools.ietf.org/html/rfc1866#section-8.2.1 */
+
+/* Vendor name: */
+/* Functionality name: htmlform */
+/* Detail name: urnencoder */
+
+#include    <basic.h>
+
+#ifndef __HTMLFORM_URLENCODER_H__
+#define __HTMLFORM_URLENCODER_H__
+
+/* Functionality name: htmlform */
+/* Detail name: */
+/* Data structure identifier: field */
+struct htmlform_field_ {
+       UB *name;
+       W name_len;
+       UB *value;
+       W value_len;
+};
+typedef struct htmlform_field_ htmlform_field;
+
+/* Functionality name: htmlform */
+/* Detail name: urlencoder */
+struct htmlform_urlencoder_t_ {
+       htmlform_field *fields;
+       W fields_len;
+       enum {
+               HTMLFORM_URLENCODER_STATE_NAME,
+               HTMLFORM_URLENCODER_STATE_EQUAL,
+               HTMLFORM_URLENCODER_STATE_VALUE,
+               HTMLFORM_URLENCODER_STATE_AMP
+       } state;
+       W field_index;
+       W src_pos;
+       UB buf[3];
+};
+typedef struct htmlform_urlencoder_t_ htmlform_urlencoder_t;
+
+IMPORT VOID htmlform_urlencoder_initialize(htmlform_urlencoder_t *encoder, htmlform_field *fields, W fields_len);
+IMPORT VOID htmlform_urlencoder_finalize(htmlform_urlencoder_t *encoder);
+IMPORT Bool htmlform_urlencoder_next(htmlform_urlencoder_t *encoder, UB **str, W *len);
+
+#endif
diff --git a/src/coding/test_htmlform_urlencoder.c b/src/coding/test_htmlform_urlencoder.c
new file mode 100644 (file)
index 0000000..15a4717
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * test_htmlform_urlencoder.c
+ *
+ * Copyright (c) 2015 project bchan
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ *    distribution.
+ *
+ */
+
+#include    "test_coding.h"
+
+#include    "htmlform_urlencoder.h"
+
+#include    <btron/btron.h>
+#include       <bstdio.h>
+#include       <bstring.h>
+#include       <bstdlib.h>
+
+#include    <unittest_driver.h>
+
+typedef struct urlencoder_testdata_t_ {
+       htmlform_field *src;
+       W src_len;
+       UB *expected;
+       W expected_len;
+} urlencoder_testdata_t;
+
+LOCAL UNITTEST_RESULT test_htmlform_urlencoder_common(urlencoder_testdata_t *testdata)
+{
+       htmlform_urlencoder_t encoder;
+       Bool cont;
+       UB *str, *result;
+       W len, result_len;
+       UNITTEST_RESULT ret = UNITTEST_RESULT_PASS;
+
+       result = (UB*)malloc(sizeof(UB));
+       if (result == NULL) {
+               return UNITTEST_RESULT_FAIL;
+       }
+       result[0] = '\0';
+       result_len = 0;
+
+       htmlform_urlencoder_initialize(&encoder, testdata->src, testdata->src_len);
+
+       for (;;) {
+               cont = htmlform_urlencoder_next(&encoder, &str, &len);
+               if (cont == False) {
+                       break;
+               }
+               result = realloc(result, result_len + len + 1);
+               if (result == NULL) {
+                       ret = UNITTEST_RESULT_FAIL;
+                       break;
+               }
+               strncat(result, str, len);
+               result_len += len;
+       }
+
+       htmlform_urlencoder_finalize(&encoder);
+
+       if (result != NULL) {
+               if (testdata->expected_len != result_len) {
+                       printf("length failure: expected = %d, result = %d\n", testdata->expected_len, result_len);
+                       ret = UNITTEST_RESULT_FAIL;
+               }
+               if (strncmp(testdata->expected, result, result_len) != 0) {
+                       printf("encoded string failure: %s\n", result);
+                       ret = UNITTEST_RESULT_FAIL;
+               }
+
+               free(result);
+       }
+
+       return ret;
+}
+
+LOCAL UNITTEST_RESULT test_htmlform_urlencoder_1()
+{
+       htmlform_field src[] = {
+               (htmlform_field){"aaa", 3, "bbb", 3},
+               (htmlform_field){"cc", 2, "dd", 2},
+       };
+       W src_len = 2;
+       UB expected[] = "aaa=bbb&cc=dd";
+       W expected_len = strlen(expected);
+       urlencoder_testdata_t testdata = {
+               src, src_len, expected, expected_len
+       };
+       return test_htmlform_urlencoder_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_htmlform_urlencoder_2()
+{
+       htmlform_field src[] = {
+               (htmlform_field){"aaa", 3, "bb", 2},
+               (htmlform_field){"cc", 2, "ddd", 3},
+       };
+       W src_len = 2;
+       UB expected[] = "aaa=bb&cc=ddd";
+       W expected_len = strlen(expected);
+       urlencoder_testdata_t testdata = {
+               src, src_len, expected, expected_len
+       };
+       return test_htmlform_urlencoder_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_htmlform_urlencoder_3()
+{
+       htmlform_field src[] = {
+               (htmlform_field){"a a", 3, "b b", 3},
+       };
+       W src_len = 1;
+       UB expected[] = "a+a=b+b";
+       W expected_len = strlen(expected);
+       urlencoder_testdata_t testdata = {
+               src, src_len, expected, expected_len
+       };
+       return test_htmlform_urlencoder_common(&testdata);
+}
+
+LOCAL UNITTEST_RESULT test_htmlform_urlencoder_4()
+{
+       htmlform_field src[] = {
+               (htmlform_field){(UB[]){0xA0, 0xA1, 0xA2}, 3, (UB[]){0xB3, 0xB4, 0xB5}, 3},
+       };
+       W src_len = 1;
+       UB expected[] = "%A0%A1%A2=%B3%B4%B5";
+       W expected_len = strlen(expected);
+       urlencoder_testdata_t testdata = {
+               src, src_len, expected, expected_len
+       };
+       return test_htmlform_urlencoder_common(&testdata);
+}
+
+EXPORT VOID test_htmlform_urlencoder_main(unittest_driver_t *driver)
+{
+       UNITTEST_DRIVER_REGIST(driver, test_htmlform_urlencoder_1);
+       UNITTEST_DRIVER_REGIST(driver, test_htmlform_urlencoder_2);
+       UNITTEST_DRIVER_REGIST(driver, test_htmlform_urlencoder_3);
+       UNITTEST_DRIVER_REGIST(driver, test_htmlform_urlencoder_4);
+}