--- /dev/null
+/**
+ * @file fifo.h
+ * @author Shinichiro Nakamura
+ * @brief FIFOモジュールの実装。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Logger (NT-Logger)
+ * ===============================================================
+ * Copyright (c) 2010-2012 Shinichiro Nakamura
+ *
+ * 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 THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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.
+ * ===============================================================
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "fifo.h"
+
+/**
+ * @brief FIFOハンドラの実装。
+ */
+struct FIFO {
+ int depth; /**< FIFOの深さ。 */
+ int count; /**< 格納されているオブジェクト数。 */
+ int rp; /**< リードポインタ。 */
+ int wp; /**< ライトポインタ。 */
+ void **objlist; /**< オブジェクトリスト。 */
+};
+
+/**
+ * @brief FIFOモジュールをオープンする。
+ *
+ * @param depth FIFOの深さ。
+ *
+ * @retval !NULL FIFOハンドラ。
+ * @retval NULL 失敗。
+ */
+FIFO *fifo_open(const int depth)
+{
+ FIFO *p = (FIFO *)malloc(sizeof(FIFO));
+ if (p == NULL) {
+ return NULL;
+ }
+ /*
+ * ユーザが示したdepthは、格納できる長さなので、+1した値が本当に格納可能なオブジェクト数。
+ */
+ p->depth = depth + 1;
+ p->count = 0;
+ p->rp = 0;
+ p->wp = 0;
+ p->objlist = (void **)malloc(sizeof(void *) * p->depth);
+ if (p->objlist == NULL) {
+ free(p);
+ return NULL;
+ }
+ return p;
+}
+
+/**
+ * @brief FIFOが一杯かどうかを検査する。
+ *
+ * @param p FIFOハンドラ。
+ *
+ * @retval 1 FIFOが一杯である。
+ * @retval 0 FIFOが一杯でない。
+ */
+int fifo_full(FIFO *p)
+{
+ return (p->rp == ((p->wp + 1) % p->depth)) ? 1 : 0;
+}
+
+/**
+ * @brief FIFOが空かどうかを検査する。
+ *
+ * @param p FIFOハンドラ。
+ *
+ * @retval 1 FIFOが空である。
+ * @retval 0 FIFOが空でない。
+ */
+int fifo_empty(FIFO *p)
+{
+ return (p->rp == p->wp) ? 1 : 0;
+}
+
+/**
+ * @brief FIFOに格納されているオブジェクト数を取得する。
+ *
+ * @param p FIFOハンドラ。
+ *
+ * @return オブジェクト数。
+ */
+int fifo_count(FIFO *p)
+{
+ return p->count;
+}
+
+/**
+ * @brief FIFOにオブジェクトをプッシュする。
+ * @details
+ * このモジュールはオブジェクトへのポインタのみを保持する。
+ * このため、スタック上に置いたオブジェクトなどをプッシュする事はできない。
+ * 必ずヒープ上のオブジェクトへのポインタを渡すこと。
+ *
+ * @param p FIFOハンドラ。
+ * @param obj オブジェクト。
+ *
+ * @retval 1 成功。
+ * @retval 0 失敗。
+ */
+int fifo_push(FIFO *p, void *obj)
+{
+ if (fifo_full(p)) {
+ return 0;
+ }
+ *(p->objlist + p->wp) = obj;
+ p->wp = (p->wp + 1) % p->depth;
+ p->count = p->count + 1;
+ return 1;
+}
+
+/**
+ * @brief FIFOからオブジェクトをプルする。
+ *
+ * @param p FIFOハンドラ。
+ * @param obj オブジェクト。
+ *
+ * @retval 1 成功。
+ * @retval 0 失敗。
+ */
+int fifo_pull(FIFO *p, void **obj)
+{
+ if (fifo_empty(p)) {
+ return 0;
+ }
+ *obj = *(p->objlist + p->rp);
+ p->rp = (p->rp + 1) % p->depth;
+ p->count = p->count - 1;
+ return 1;
+}
+
+/**
+ * @brief FIFOモジュールをクローズする。
+ *
+ * @param p FIFOハンドラ。
+ *
+ * @retval 1 成功。
+ * @retval 0 失敗。
+ */
+int fifo_close(FIFO *p)
+{
+ if (p == NULL) {
+ return 0;
+ }
+ free(p->objlist);
+ free(p);
+ return 0;
+}
+