/* vim: ts=4 sw=4 sts=4 ff=unix fenc=utf-8 : * ===================================================================== * sc_iterator.c * Copyright (c) 2003 - 2011 sys0tem * LICENSE : * LGPL (GNU Lesser General Public License - Version 3,29 June 2007) * http://www.gnu.org/copyleft/lesser.html * or * EPL (Eclipse Public License - v1.0) * http://www.eclipse.org/legal/epl-v10.html * ===================================================================== */ #include <string.h> #include <sc_os.h> #include <sc_error.h> #include <sc_env.h> #include <sc_mmgr.h> #include <sc_iterator.h> /* --------------------------------------------------------------------- * プロトタイプ宣言 * --------------------------------------------------------------------- */ static bool SC_Iterator_hasNext(SC_Iterator* ite); static const void* SC_Iterator_next(SC_Iterator* ite, size_t* size); static const char* SC_Iterator_nextStr(SC_Iterator* ite); /** * SC_Iterator を生成します。 * メモリ確保に失敗した場合、NULL を返します。 * * @param head Iteratorのエントリの先頭 * @return SC_Iterator */ SC_Iterator* SC_Iterator_new(SC_Iterator_Entry* head) { SC_Iterator* ite = (SC_Iterator*) malloc(sizeof(SC_Iterator)); if (ite == NULL) { /* メモリ確保失敗 */ return NULL; } ite->_head = head; ite->_now = head; ite->hasNext = SC_Iterator_hasNext; ite->next = SC_Iterator_next; ite->nextStr = SC_Iterator_nextStr; return ite; } /** * SC_Iterator を破棄します。 * ここで破棄されるデータは、SC_Iterator のみであり、 * new された際の引数に渡されたデータについては破棄しません。 * new の際渡された各データが malloc 等で確保されている場合、 * 以下のようなコードで破棄する必要があります。 * * <pre> * SC_Iterator_Entry* next; * SC_Iterator_Entry* entry; * * entry = ite->_head; * while (entry != NULL) * { * next = entry->next; * free(entry); * entry = next; * } * </pre> * * @param ite Iterator */ void SC_Iterator_delete(SC_Iterator* ite) { free (ite); } /* --------------------------------------------------------------------- * 以下、内部でのみ利用する関数 * --------------------------------------------------------------------- */ /** * 次の要素が存在するかどうか返します。 * * @param ite Iterator * @return true/false (存在する/しない) */ static bool SC_Iterator_hasNext(SC_Iterator* ite) { if (ite->_now == NULL) { return false; } return true; } /** * 次の要素を取得します。 * 要素が存在しない場合 NULL が返されます。 * size が NULL でない場合、要素のサイズが格納されます。 * * @param ite Iterator * @param size サイズ * @return 値 */ static const void* SC_Iterator_next(SC_Iterator* ite, size_t* size) { SC_Iterator_Entry* entry; if (ite->_now == NULL) { return NULL; } /* 読み出しポインタを進める */ entry = ite->_now; ite->_now = ite->_now->next; if (size != NULL) { *size = entry->size; } return entry->value; } /** * 次の要素を文字列として取得します。 * 要素が存在しない場合 NULL が返されます。 * * @param ite Iterator * @return 値 */ static const char* SC_Iterator_nextStr(SC_Iterator* ite) { return (const char*) SC_Iterator_next(ite, NULL); }