Newer
Older
snipet / libsc / trunk / src / sc_iterator.c
  1. /* vim: ts=4 sw=4 sts=4 ff=unix fenc=utf-8 :
  2. * =====================================================================
  3. * sc_iterator.c
  4. * Copyright (c) 2003 - 2011 sys0tem
  5. * LICENSE :
  6. * LGPL (GNU Lesser General Public License - Version 3,29 June 2007)
  7. * http://www.gnu.org/copyleft/lesser.html
  8. * or
  9. * EPL (Eclipse Public License - v1.0)
  10. * http://www.eclipse.org/legal/epl-v10.html
  11. * =====================================================================
  12. */
  13. #include <string.h>
  14. #include <sc_os.h>
  15. #include <sc_error.h>
  16. #include <sc_env.h>
  17. #include <sc_mmgr.h>
  18. #include <sc_iterator.h>
  19.  
  20.  
  21. /* ---------------------------------------------------------------------
  22. * プロトタイプ宣言
  23. * ---------------------------------------------------------------------
  24. */
  25. static bool SC_Iterator_hasNext(SC_Iterator* ite);
  26. static const void* SC_Iterator_next(SC_Iterator* ite, size_t* size);
  27. static const char* SC_Iterator_nextStr(SC_Iterator* ite);
  28.  
  29. /**
  30. * SC_Iterator を生成します。
  31. * メモリ確保に失敗した場合、NULL を返します。
  32. *
  33. * @param head Iteratorのエントリの先頭
  34. * @return SC_Iterator
  35. */
  36. SC_Iterator* SC_Iterator_new(SC_Iterator_Entry* head)
  37. {
  38. SC_Iterator* ite = (SC_Iterator*) malloc(sizeof(SC_Iterator));
  39. if (ite == NULL)
  40. { /* メモリ確保失敗 */
  41. return NULL;
  42. }
  43. ite->_head = head;
  44. ite->_now = head;
  45.  
  46. ite->hasNext = SC_Iterator_hasNext;
  47. ite->next = SC_Iterator_next;
  48. ite->nextStr = SC_Iterator_nextStr;
  49. return ite;
  50. }
  51.  
  52.  
  53. /**
  54. * SC_Iterator を破棄します。
  55. * ここで破棄されるデータは、SC_Iterator のみであり、
  56. * new された際の引数に渡されたデータについては破棄しません。
  57. * new の際渡された各データが malloc 等で確保されている場合、
  58. * 以下のようなコードで破棄する必要があります。
  59. *
  60. * <pre>
  61. * SC_Iterator_Entry* next;
  62. * SC_Iterator_Entry* entry;
  63. *
  64. * entry = ite->_head;
  65. * while (entry != NULL)
  66. * {
  67. * next = entry->next;
  68. * free(entry);
  69. * entry = next;
  70. * }
  71. * </pre>
  72. *
  73. * @param ite Iterator
  74. */
  75. void SC_Iterator_delete(SC_Iterator* ite)
  76. {
  77. free (ite);
  78. }
  79.  
  80.  
  81. /* ---------------------------------------------------------------------
  82. * 以下、内部でのみ利用する関数
  83. * ---------------------------------------------------------------------
  84. */
  85.  
  86.  
  87. /**
  88. * 次の要素が存在するかどうか返します。
  89. *
  90. * @param ite Iterator
  91. * @return true/false (存在する/しない)
  92. */
  93. static
  94. bool SC_Iterator_hasNext(SC_Iterator* ite)
  95. {
  96. if (ite->_now == NULL)
  97. {
  98. return false;
  99. }
  100. return true;
  101. }
  102.  
  103.  
  104. /**
  105. * 次の要素を取得します。
  106. * 要素が存在しない場合 NULL が返されます。
  107. * size が NULL でない場合、要素のサイズが格納されます。
  108. *
  109. * @param ite Iterator
  110. * @param size サイズ
  111. * @return 値
  112. */
  113. static
  114. const void* SC_Iterator_next(SC_Iterator* ite, size_t* size)
  115. {
  116. SC_Iterator_Entry* entry;
  117. if (ite->_now == NULL)
  118. {
  119. return NULL;
  120. }
  121. /* 読み出しポインタを進める */
  122. entry = ite->_now;
  123. ite->_now = ite->_now->next;
  124. if (size != NULL)
  125. {
  126. *size = entry->size;
  127. }
  128. return entry->value;
  129. }
  130.  
  131.  
  132. /**
  133. * 次の要素を文字列として取得します。
  134. * 要素が存在しない場合 NULL が返されます。
  135. *
  136. * @param ite Iterator
  137. * @return 値
  138. */
  139. static
  140. const char* SC_Iterator_nextStr(SC_Iterator* ite)
  141. {
  142. return (const char*) SC_Iterator_next(ite, NULL);
  143. }
  144.