Advertisement
BigETI

list.inc

Jul 18th, 2013
579
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 22.51 KB | None | 0 0
  1. /*
  2.     Linked lists in PAWN made by BigETI © 2013
  3. */
  4. #if defined _LIST_INCLUDED_
  5.     #endinput
  6. #endif
  7. #define _LIST_INCLUDED_
  8. #include <memory>
  9. #if defined MEM_NULL_EX
  10.     #define LIST_NULL_  MEM_EX::NULL
  11. #else
  12.     #define LIST_NULL_  NULL
  13. #endif
  14. #define LIST_init%1<%0>                 List:%0[LIST_E_base]
  15. #define LIST_begin%1(%0)                (ListIt:%0[LIST_base_begin])
  16. #define LIST_end%1(%0)                  (ListIt:%0[LIST_base_end])
  17. #define LIST_exist%1(%0)                (!!LIST_find(%0))
  18. #define LIST_arr_exist%1(%0)            (!!LIST_find_arr(%0))
  19. #define LIST_IT_data_ptr%1(%0)          (MEM_EX::get_ptr(Pointer:(%0)->LIST_IT_data_data_offset))
  20. #if defined SECURE_MEMORY_PLUGIN
  21.     #define LIST_IT_data_val%2(%0,%1)   (MEM_EX::get_val(Pointer:(%0)->(LIST_IT_data_data_offset+(%1))))
  22. #else
  23.     #define LIST_IT_data_val%2(%0,%1)   (MEM_EX::get_val(LIST_IT_data_ptr(%0)->(%1)))
  24. #endif
  25. #define LIST_IT_next%1(%0)              ListIt:MEM_EX::get_val(Pointer:(%0)->LIST_IT_data_next)
  26. #define LIST_IT_previous%1(%0)          ListIt:MEM_EX::get_val(Pointer:(%0)->LIST_IT_data_previous)
  27. #define LIST_IT_data_size%1(%0)         MEM_EX::get_val(Pointer:(%0)->LIST_IT_data_data_size)
  28. #define LIST_foreach%2<%0>%3(%1)        for(new ListIt:%0 = ListIt:%1[LIST_base_begin]; _:%0 != LIST_NULL_; %0 = ListIt:MEM_EX::get_val(Pointer:(%0)->LIST_IT_data_next))
  29. #define LIST_foreach_rev%2<%0>%3(%1)    for(new ListIt:%0 = ListIt:%1[LIST_base_end]; _:%0 != LIST_NULL_; %0 = ListIt:MEM_EX::get_val(Pointer:(%0)->LIST_IT_data_previous))
  30. MEM::struct LIST_E_base
  31. {
  32.     LIST_base_begin,
  33.     LIST_base_end
  34. }
  35. MEM::struct LIST_IT_data
  36. {
  37.     LIST_IT_data_next,
  38.     LIST_IT_data_previous,
  39.     LIST_IT_data_data_size,
  40.     LIST_IT_data_data_offset
  41. }
  42. static const LIST_file_header[] = {0xD, 0xA, 0x14, 0x15, 0x0, 0x7, 0xA, 0xD, 0x6};
  43. stock ListIt:LIST_push_back(List:list[], value)
  44. {
  45.     new Pointer:next_LIST_ptr = MEM::calloc(LIST_IT_data_data_offset+1);
  46.     if(next_LIST_ptr)
  47.     {
  48.         if(list[LIST_base_end])
  49.         {
  50.             MEM::set_val(Pointer:list[LIST_base_end], LIST_IT_data_next, _:next_LIST_ptr);
  51.             MEM::set_val(next_LIST_ptr, LIST_IT_data_previous, list[LIST_base_end]);
  52.         }
  53.         else if(list[LIST_base_begin] == LIST_NULL_) list[LIST_base_begin] = _:next_LIST_ptr;
  54.         list[LIST_base_end] = _:next_LIST_ptr;
  55.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_size, 1);
  56.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_offset, value);
  57.         return LIST_end(list);
  58.     }
  59.     return ListIt:LIST_NULL_;
  60. }
  61. stock ListIt:LIST_push_back_arr(List:list[], arr[], arr_size = sizeof arr)
  62. {
  63.     if(arr_size < 1) return ListIt:LIST_NULL_;
  64.     new Pointer:next_LIST_ptr = MEM::calloc(arr_size+LIST_IT_data_data_offset);
  65.     if(next_LIST_ptr)
  66.     {
  67.         if(list[LIST_base_end])
  68.         {
  69.             MEM::set_val(Pointer:list[LIST_base_end], LIST_IT_data_next, _:next_LIST_ptr);
  70.             MEM::set_val(next_LIST_ptr, LIST_IT_data_previous, list[LIST_base_end]);
  71.         }
  72.         else if(list[LIST_base_begin] == LIST_NULL_) list[LIST_base_begin] = _:next_LIST_ptr;
  73.         list[LIST_base_end] = _:next_LIST_ptr;
  74.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_size, arr_size);
  75.         MEM::set_arr(next_LIST_ptr, LIST_IT_data_data_offset, arr, arr_size);
  76.         return LIST_end(list);
  77.     }
  78.     return ListIt:LIST_NULL_;
  79. }
  80. stock ListIt:LIST_pop_back(List:list[])
  81. {
  82.     if(list[LIST_base_begin] == LIST_NULL_) return ListIt:LIST_NULL_;
  83.     new last_node = MEM_EX::get_val(Pointer:list[LIST_base_end]->LIST_IT_data_previous);
  84.     if(last_node)
  85.     {
  86.         MEM::set_val(Pointer:last_node, LIST_IT_data_next, LIST_NULL_);
  87.         MEM::free(Pointer:list[LIST_base_end]);
  88.         return ListIt:(list[LIST_base_end] = last_node);
  89.     }
  90.     list[LIST_base_begin] = LIST_NULL_;
  91.     list[LIST_base_end] = LIST_NULL_;
  92.     return ListIt:LIST_NULL_;
  93. }
  94. stock ListIt:LIST_push_front(List:list[], value)
  95. {
  96.     new Pointer:next_LIST_ptr = MEM::calloc(LIST_IT_data_data_offset+1);
  97.     if(next_LIST_ptr)
  98.     {
  99.         if(list[LIST_base_begin])
  100.         {
  101.             MEM::set_val(Pointer:list[LIST_base_begin], LIST_IT_data_previous, _:next_LIST_ptr);
  102.             MEM::set_val(next_LIST_ptr, LIST_IT_data_next, list[LIST_base_begin]);
  103.         }
  104.         else list[LIST_base_end] = _:next_LIST_ptr;
  105.         list[LIST_base_begin] = _:next_LIST_ptr;
  106.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_size, 1);
  107.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_offset, value);
  108.         return LIST_begin(list);
  109.     }
  110.     return ListIt:LIST_NULL_;
  111. }
  112. stock ListIt:LIST_push_front_arr(List:list[], arr[], arr_size = sizeof arr)
  113. {
  114.     new Pointer:next_LIST_ptr = MEM::calloc(LIST_IT_data_data_offset+arr_size);
  115.     if(next_LIST_ptr)
  116.     {
  117.         if(list[LIST_base_begin])
  118.         {
  119.             MEM::set_val(Pointer:list[LIST_base_begin], LIST_IT_data_previous, _:next_LIST_ptr);
  120.             MEM::set_val(next_LIST_ptr, LIST_IT_data_next, list[LIST_base_begin]);
  121.         }
  122.         else list[LIST_base_end] = _:next_LIST_ptr;
  123.         list[LIST_base_begin] = _:next_LIST_ptr;
  124.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_size, arr_size);
  125.         MEM::set_arr(next_LIST_ptr, LIST_IT_data_data_offset, arr, arr_size);
  126.         return LIST_begin(list);
  127.     }
  128.     return ListIt:LIST_NULL_;
  129. }
  130. stock ListIt:LIST_pop_front(List:list[])
  131. {
  132.     if(!list[LIST_base_begin]) return ListIt:LIST_NULL_;
  133.     new Pointer:free_node = Pointer:list[LIST_base_begin];
  134.     if((list[LIST_base_begin] = MEM_EX::get_val(Pointer:list[LIST_base_begin]->LIST_IT_data_next))) MEM::set_val(Pointer:list[LIST_base_begin], LIST_IT_data_previous, LIST_NULL_);
  135.     else list[LIST_base_end] = LIST_NULL_;
  136.     MEM::free(free_node);
  137.     return LIST_begin(list);
  138. }
  139. stock ListIt:LIST_insert(List:list[], ListIt:node, value)
  140. {
  141.     if(_:node == LIST_NULL_) return ListIt:LIST_NULL_;
  142.     new Pointer:next_LIST_ptr = MEM::calloc(LIST_IT_data_data_offset+1);
  143.     if(next_LIST_ptr)
  144.     {
  145.         if(_:node == list[LIST_base_begin]) list[LIST_base_begin] = _:next_LIST_ptr;
  146.         else
  147.         {
  148.             MEM::set_val(next_LIST_ptr, LIST_IT_data_previous, MEM_EX::get_val(Pointer:node->LIST_IT_data_previous));
  149.             MEM::set_val(Pointer:MEM_EX::get_val(Pointer:node->LIST_IT_data_previous), LIST_IT_data_next, _:next_LIST_ptr);
  150.         }
  151.         MEM::set_val(Pointer:node, LIST_IT_data_previous, _:next_LIST_ptr);
  152.         MEM::set_val(next_LIST_ptr, LIST_IT_data_next, _:node);
  153.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_size, 1);
  154.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_offset, value);
  155.         return ListIt:next_LIST_ptr;
  156.     }
  157.     return ListIt:LIST_NULL_;
  158. }
  159. stock ListIt:LIST_insert_arr(List:list[], ListIt:node, arr[], arr_size = sizeof arr)
  160. {
  161.     if(_:node == LIST_NULL_) return ListIt:LIST_NULL_;
  162.     new Pointer:next_LIST_ptr = MEM::calloc(LIST_IT_data_data_offset+arr_size);
  163.     if(next_LIST_ptr)
  164.     {
  165.         if(_:node == list[LIST_base_begin]) list[LIST_base_begin] = _:next_LIST_ptr;
  166.         else
  167.         {
  168.             MEM::set_val(next_LIST_ptr, LIST_IT_data_previous, MEM_EX::get_val(Pointer:node->LIST_IT_data_previous));
  169.             MEM::set_val(Pointer:MEM_EX::get_val(Pointer:node->LIST_IT_data_previous), LIST_IT_data_next, _:next_LIST_ptr);
  170.         }
  171.         MEM::set_val(Pointer:node, LIST_IT_data_previous, _:next_LIST_ptr);
  172.         MEM::set_val(next_LIST_ptr, LIST_IT_data_next, _:node);
  173.         MEM::set_val(next_LIST_ptr, LIST_IT_data_data_size, arr_size);
  174.         MEM::set_arr(next_LIST_ptr, LIST_IT_data_data_offset, arr, arr_size);
  175.         return ListIt:next_LIST_ptr;
  176.     }
  177.     return ListIt:LIST_NULL_;
  178. }
  179. stock ListIt:LIST_erase(List:list[], ListIt:node)
  180. {
  181.     if(_:node == LIST_NULL_) return ListIt:LIST_NULL_;
  182.     new prev_addr = MEM_EX::get_val(Pointer:node->LIST_IT_data_previous), next_addr = MEM_EX::get_val(Pointer:node->LIST_IT_data_next);
  183.     if(list[LIST_base_begin] == _:node)
  184.     {
  185.         if(list[LIST_base_end] == _:node)
  186.         {
  187.             list[LIST_base_begin] = LIST_NULL_;
  188.             list[LIST_base_end] = LIST_NULL_;
  189.             MEM::free(Pointer:node);
  190.             return ListIt:LIST_NULL_;
  191.         }
  192.         MEM::set_val(Pointer:next_addr, LIST_IT_data_previous, LIST_NULL_);
  193.         MEM::free(Pointer:node);
  194.         return ListIt:(list[LIST_base_begin] = next_addr);
  195.     }
  196.     if(list[LIST_base_end] == _:node)
  197.     {
  198.         MEM::set_val(Pointer:prev_addr, LIST_IT_data_next, LIST_NULL_);
  199.         list[LIST_base_end] = prev_addr;
  200.         MEM::free(Pointer:node);
  201.         return ListIt:LIST_NULL_;
  202.     }
  203.     MEM::set_val(Pointer:prev_addr, LIST_IT_data_next, next_addr);
  204.     MEM::set_val(Pointer:next_addr, LIST_IT_data_previous, prev_addr);
  205.     MEM::free(Pointer:node);
  206.     return ListIt:next_addr;
  207. }
  208. stock ListIt:LIST_find(List:list[], value, index = 0, bool:reverse = false, jump = 0)
  209. {
  210.     if(index < 0) return ListIt:LIST_NULL_;
  211.     new do_jump = jump;
  212.     if(reverse)
  213.     {
  214.         for(new Pointer:find_node = Pointer:list[LIST_base_end]; _:find_node != LIST_NULL_; find_node = Pointer:MEM_EX::get_val(find_node->LIST_IT_data_previous))
  215.         {
  216.             if(LIST_IT_data_size(find_node) <= index) continue;
  217.             if(MEM_EX::get_val(find_node->(LIST_IT_data_data_offset+index)) != value) continue;
  218.             if(do_jump-- > 0) continue;
  219.             return ListIt:find_node;
  220.         }
  221.     }
  222.     else
  223.     {
  224.         for(new Pointer:find_node = Pointer:list[LIST_base_begin]; _:find_node != LIST_NULL_; find_node = Pointer:MEM_EX::get_val(find_node->LIST_IT_data_next))
  225.         {
  226.             if(LIST_IT_data_size(find_node) <= index) continue;
  227.             if(MEM_EX::get_val(find_node->(LIST_IT_data_data_offset+index)) != value) continue;
  228.             if(do_jump-- > 0) continue;
  229.             return ListIt:find_node;
  230.         }
  231.     }
  232.     return ListIt:LIST_NULL_;
  233. }
  234. stock ListIt:LIST_find_arr(List:list[], arr[], arr_size = sizeof arr, index = 0, bool:reverse = false, jump = 0)
  235. {
  236.     if(arr_size-index <= 0) return ListIt:LIST_NULL_;
  237.     new arr_i, bool:do_continue = false, do_jump = jump;
  238.     if(reverse)
  239.     {
  240.         for(new Pointer:find_node = Pointer:list[LIST_base_end]; _:find_node != LIST_NULL_; find_node = Pointer:MEM_EX::get_val(find_node->LIST_IT_data_previous))
  241.         {
  242.             for(arr_i = 0; arr_i < arr_size; arr_i++)
  243.             {
  244.                 if(LIST_IT_data_size(find_node) <= (index+arr_i))
  245.                 {
  246.                     do_continue = true;
  247.                     break;
  248.                 }
  249.                 if(MEM_EX::get_val(find_node->(LIST_IT_data_data_offset+(index+arr_i))) != arr[arr_i])
  250.                 {
  251.                     do_continue = true;
  252.                     break;
  253.                 }
  254.             }
  255.             if(do_continue)
  256.             {
  257.                 do_continue = false;
  258.                 continue;
  259.             }
  260.             if(do_jump-- > 0) continue;
  261.             return ListIt:find_node;
  262.         }
  263.     }
  264.     else
  265.     {
  266.         for(new Pointer:find_node = Pointer:list[LIST_base_begin]; _:find_node != LIST_NULL_; find_node = Pointer:MEM_EX::get_val(find_node->LIST_IT_data_next))
  267.         {
  268.             for(arr_i = 0; arr_i < arr_size; arr_i++)
  269.             {
  270.                 if(LIST_IT_data_size(find_node) <= (index+arr_i))
  271.                 {
  272.                     do_continue = true;
  273.                     break;
  274.                 }
  275.                 if(MEM_EX::get_val(find_node->(LIST_IT_data_data_offset+(index+arr_i))) != arr[arr_i])
  276.                 {
  277.                     do_continue = true;
  278.                     break;
  279.                 }
  280.             }
  281.             if(do_continue)
  282.             {
  283.                 do_continue = false;
  284.                 continue;
  285.             }
  286.             if(do_jump-- > 0) continue;
  287.             return ListIt:find_node;
  288.         }
  289.     }
  290.     return ListIt:LIST_NULL_;
  291. }
  292. stock LIST_count_found(List:list[], value, index = 0)
  293. {
  294.     if(index < 0) return 0;
  295.     new count = 0;
  296.     for(new Pointer:find_node = Pointer:list[LIST_base_begin]; _:find_node != LIST_NULL_; find_node = Pointer:MEM_EX::get_val(find_node->LIST_IT_data_next))
  297.     {
  298.         if(LIST_IT_data_size(find_node) <= index) continue;
  299.         if(MEM_EX::get_val(find_node->(LIST_IT_data_data_offset+index)) != value) continue;
  300.         count++;
  301.     }
  302.     return count;
  303. }
  304. stock LIST_count_found_arr(List:list[], arr[], arr_size = sizeof arr, index = 0)
  305. {
  306.     if(arr_size-index <= 0) return 0;
  307.     new count = 0, arr_i, bool:do_continue = false;
  308.     for(new Pointer:find_node = Pointer:list[LIST_base_begin]; _:find_node != LIST_NULL_; find_node = Pointer:MEM_EX::get_val(find_node->LIST_IT_data_next))
  309.     {
  310.         for(arr_i = 0; arr_i < arr_size; arr_i++)
  311.         {
  312.             if(LIST_IT_data_size(find_node) <= (index+arr_i))
  313.             {
  314.                 do_continue = true;
  315.                 break;
  316.             }
  317.             if(MEM_EX::get_val(find_node->(LIST_IT_data_data_offset+(index+arr_i))) != arr[arr_i])
  318.             {
  319.                 do_continue = true;
  320.                 break;
  321.             }
  322.         }
  323.         if(do_continue)
  324.         {
  325.             do_continue = false;
  326.             continue;
  327.         }
  328.         count++;
  329.     }
  330.     return count;
  331. }
  332. stock LIST_sort(List:list[], bool:descending = false)
  333. {
  334.     new bool:allow_repeat = true, Pointer:sort_it, Pointer:next_node, size_1, size_2, cmp_i, Pointer:temp_node, data_1, data_2;
  335.     if(descending)
  336.     {
  337.         while(allow_repeat)
  338.         {
  339.             allow_repeat = false;
  340.             for(sort_it = Pointer:list[LIST_base_begin]; (next_node = Pointer:MEM_EX::get_val(sort_it->LIST_IT_data_next)); sort_it = Pointer:MEM_EX::get_val(sort_it->LIST_IT_data_next))
  341.             {
  342.                 size_1 = LIST_IT_data_size(sort_it);
  343.                 size_2 = LIST_IT_data_size(next_node);
  344.                 for(cmp_i = 0; cmp_i >= 0; cmp_i++)
  345.                 {
  346.                     if(cmp_i >= size_2) break;
  347.                     if(cmp_i >= size_1)
  348.                     {
  349.                         if((temp_node = Pointer:MEM_EX::get_val(sort_it->LIST_IT_data_previous)))
  350.                         {
  351.                             MEM::set_val(temp_node, LIST_IT_data_next, _:next_node);
  352.                             MEM::set_val(next_node, LIST_IT_data_previous, _:temp_node);
  353.                         }
  354.                         else MEM::set_val((Pointer:list[LIST_base_begin] = next_node), LIST_IT_data_previous, LIST_NULL_);
  355.                         if((temp_node = Pointer:MEM_EX::get_val(next_node->LIST_IT_data_next)))
  356.                         {
  357.                             MEM::set_val(temp_node, LIST_IT_data_previous, _:sort_it);
  358.                             MEM::set_val(sort_it, LIST_IT_data_next, _:temp_node);
  359.                         }
  360.                         else MEM::set_val((Pointer:list[LIST_base_end] = sort_it), LIST_IT_data_next, LIST_NULL_);
  361.                         MEM::set_val(sort_it, LIST_IT_data_previous, _:next_node);
  362.                         MEM::set_val(next_node, LIST_IT_data_next, _:sort_it);
  363.                         sort_it = next_node;
  364.                         allow_repeat = true;
  365.                         break;
  366.                     }
  367.                     if((data_1 = MEM_EX::get_val(sort_it->LIST_IT_data_data_offset+cmp_i)) == (data_2 = MEM_EX::get_val(next_node->LIST_IT_data_data_offset+cmp_i))) continue;
  368.                     if(data_1 > data_2) break;
  369.                     if((temp_node = Pointer:MEM_EX::get_val(sort_it->LIST_IT_data_previous)))
  370.                     {
  371.                         MEM::set_val(temp_node, LIST_IT_data_next, _:next_node);
  372.                         MEM::set_val(next_node, LIST_IT_data_previous, _:temp_node);
  373.                     }
  374.                     else MEM::set_val((Pointer:list[LIST_base_begin] = next_node), LIST_IT_data_previous, LIST_NULL_);
  375.                     if((temp_node = Pointer:MEM_EX::get_val(next_node->LIST_IT_data_next)))
  376.                     {
  377.                         MEM::set_val(temp_node, LIST_IT_data_previous, _:sort_it);
  378.                         MEM::set_val(sort_it, LIST_IT_data_next, _:temp_node);
  379.                     }
  380.                     else MEM::set_val((Pointer:list[LIST_base_end] = sort_it), LIST_IT_data_next, LIST_NULL_);
  381.                     MEM::set_val(sort_it, LIST_IT_data_previous, _:next_node);
  382.                     MEM::set_val(next_node, LIST_IT_data_next, _:sort_it);
  383.                     sort_it = next_node;
  384.                     allow_repeat = true;
  385.                     break;
  386.                 }
  387.             }
  388.         }
  389.     }
  390.     else
  391.     {
  392.         while(allow_repeat)
  393.         {
  394.             allow_repeat = false;
  395.             for(sort_it = Pointer:list[LIST_base_begin]; (next_node = Pointer:MEM_EX::get_val(sort_it->LIST_IT_data_next)); sort_it = Pointer:MEM_EX::get_val(sort_it->LIST_IT_data_next))
  396.             {
  397.                 size_1 = LIST_IT_data_size(sort_it);
  398.                 size_2 = LIST_IT_data_size(next_node);
  399.                 for(cmp_i = 0; cmp_i >= 0; cmp_i++)
  400.                 {
  401.                     if(cmp_i >= size_1) break;
  402.                     if(cmp_i >= size_2)
  403.                     {
  404.                         if((temp_node = Pointer:MEM_EX::get_val(sort_it->LIST_IT_data_previous)))
  405.                         {
  406.                             MEM::set_val(temp_node, LIST_IT_data_next, _:next_node);
  407.                             MEM::set_val(next_node, LIST_IT_data_previous, _:temp_node);
  408.                         }
  409.                         else MEM::set_val((Pointer:list[LIST_base_begin] = next_node), LIST_IT_data_previous, LIST_NULL_);
  410.                         if((temp_node = Pointer:MEM_EX::get_val(next_node->LIST_IT_data_next)))
  411.                         {
  412.                             MEM::set_val(temp_node, LIST_IT_data_previous, _:sort_it);
  413.                             MEM::set_val(sort_it, LIST_IT_data_next, _:temp_node);
  414.                         }
  415.                         else MEM::set_val((Pointer:list[LIST_base_end] = sort_it), LIST_IT_data_next, LIST_NULL_);
  416.                         MEM::set_val(sort_it, LIST_IT_data_previous, _:next_node);
  417.                         MEM::set_val(next_node, LIST_IT_data_next, _:sort_it);
  418.                         sort_it = next_node;
  419.                         allow_repeat = true;
  420.                         break;
  421.                     }
  422.                     if((data_1 = MEM_EX::get_val(sort_it->LIST_IT_data_data_offset+cmp_i)) == (data_2 = MEM_EX::get_val(next_node->LIST_IT_data_data_offset+cmp_i))) continue;
  423.                     if(data_1 < data_2) break;
  424.                     if((temp_node = Pointer:MEM_EX::get_val(sort_it->LIST_IT_data_previous)))
  425.                     {
  426.                         MEM::set_val(temp_node, LIST_IT_data_next, _:next_node);
  427.                         MEM::set_val(next_node, LIST_IT_data_previous, _:temp_node);
  428.                     }
  429.                     else MEM::set_val((Pointer:list[LIST_base_begin] = next_node), LIST_IT_data_previous, LIST_NULL_);
  430.                     if((temp_node = Pointer:MEM_EX::get_val(next_node->LIST_IT_data_next)))
  431.                     {
  432.                         MEM::set_val(temp_node, LIST_IT_data_previous, _:sort_it);
  433.                         MEM::set_val(sort_it, LIST_IT_data_next, _:temp_node);
  434.                     }
  435.                     else MEM::set_val((Pointer:list[LIST_base_end] = sort_it), LIST_IT_data_next, LIST_NULL_);
  436.                     MEM::set_val(sort_it, LIST_IT_data_previous, _:next_node);
  437.                     MEM::set_val(next_node, LIST_IT_data_next, _:sort_it);
  438.                     sort_it = next_node;
  439.                     allow_repeat = true;
  440.                     break;
  441.                 }
  442.             }
  443.         }
  444.     }
  445. }
  446. stock LIST_count_nodes(List:list[])
  447. {
  448.     new count = 0;
  449.     for(new Pointer:list_it = Pointer:list[LIST_base_begin]; _:list_it != LIST_NULL_; list_it = Pointer:MEM_EX::get_val(list_it->LIST_IT_data_next)) count++;
  450.     return count;
  451. }
  452. stock LIST_get_data_cell_size(List:list[])
  453. {
  454.     new count = 0;
  455.     for(new Pointer:list_it = Pointer:list[LIST_base_begin]; _:list_it != LIST_NULL_; list_it = Pointer:MEM_EX::get_val(list_it->LIST_IT_data_next)) count += LIST_IT_data_size(list_it);
  456.     return count;
  457. }
  458. stock LIST_get_all_cell_size(List:list[])
  459. {
  460.     new count = 0;
  461.     for(new Pointer:list_it = Pointer:list[LIST_base_begin]; _:list_it != LIST_NULL_; list_it = Pointer:MEM_EX::get_val(list_it->LIST_IT_data_next)) count += (LIST_IT_data_size(list_it)+3);
  462.     return count;
  463. }
  464. stock LIST_clear(List:list[])
  465. {
  466.     if(list[LIST_base_begin] == LIST_NULL_) return;
  467.     new Pointer:last_node = Pointer:list[LIST_base_end], Pointer:free_node;
  468.     while((free_node = last_node))
  469.     {
  470.         last_node = Pointer:MEM_EX::get_val(last_node->LIST_IT_data_previous);
  471.         MEM::free(free_node);
  472.     }
  473.     list[LIST_base_begin] = LIST_NULL_;
  474.     list[LIST_base_end] = LIST_NULL_;
  475. }
  476. stock bool:LIST_copy(List:dest_list[], List:src_list[])
  477. {
  478.     new Pointer:next_LIST_ptr, arr_size;
  479.     LIST_clear(dest_list);
  480.     for(new Pointer:list_it = Pointer:src_list[LIST_base_begin]; _:list_it != LIST_NULL_; list_it = Pointer:MEM_EX::get_val(Pointer:list_it->LIST_IT_data_next))
  481.     {
  482.         if((next_LIST_ptr = MEM::calloc((arr_size = MEM_EX::get_val(Pointer:list_it->LIST_IT_data_data_size))+LIST_IT_data_data_offset)) == Pointer:LIST_NULL_)
  483.         {
  484.             LIST_clear(dest_list);
  485.             return false;
  486.         }
  487.         MEM::copy(next_LIST_ptr, list_it, arr_size+1, LIST_IT_data_data_size, LIST_IT_data_data_size);
  488.         if(dest_list[LIST_base_end])
  489.         {
  490.             MEM::set_val(Pointer:dest_list[LIST_base_end], LIST_IT_data_next, _:next_LIST_ptr);
  491.             MEM::set_val(next_LIST_ptr, LIST_IT_data_previous, dest_list[LIST_base_end]);
  492.         }
  493.         else if(dest_list[LIST_base_begin] == LIST_NULL_) dest_list[LIST_base_begin] = _:next_LIST_ptr;
  494.         dest_list[LIST_base_end] = _:next_LIST_ptr;
  495.     }
  496.     return true;
  497. }
  498. stock bool:LIST_save(List:list[], const file_name[], bool:clear = false)
  499. {
  500.     new File:list_file = fopen(file_name, io_write);
  501.     if(list_file)
  502.     {
  503.         new arr_size, i, buffer
  504. #if !defined SECURE_MEMORY_PLUGIN
  505.             , Pointer:data_ptr
  506. #endif
  507.             ;
  508.         for(i = 0; i < sizeof LIST_file_header; i++) fputchar(list_file, LIST_file_header[i], false);
  509.         for(new Pointer:list_it = Pointer:list[LIST_base_begin]; _:list_it != LIST_NULL_; list_it = Pointer:MEM_EX::get_val(Pointer:list_it->LIST_IT_data_next))
  510.         {
  511.             fputchar(list_file, 1, false);
  512.             fputchar(list_file, (arr_size = MEM_EX::get_val(Pointer:list_it->LIST_IT_data_data_size))&0xFF, false);
  513.             fputchar(list_file, (arr_size>>>8)&0xFF, false);
  514.             fputchar(list_file, (arr_size>>>16)&0xFF, false);
  515.             fputchar(list_file, (arr_size>>>24)&0xFF, false);
  516. #if !defined SECURE_MEMORY_PLUGIN
  517.             data_ptr = MEM_EX::get_ptr(list_it->LIST_IT_data_data_offset);
  518. #endif
  519.             for(i = 0; i < arr_size; i++)
  520.             {
  521. #if defined SECURE_MEMORY_PLUGIN
  522.                 fputchar(list_file, (buffer = LIST_IT_data_val(list_it, i))&0xFF, false);
  523. #else
  524.                 fputchar(list_file, (buffer = MEM_EX::get_val(data_ptr->i))&0xFF, false);
  525. #endif
  526.                 fputchar(list_file, (buffer>>>8)&0xFF, false);
  527.                 fputchar(list_file, (buffer>>>16)&0xFF, false);
  528.                 fputchar(list_file, (buffer>>>24)&0xFF, false);
  529.             }
  530.         }
  531.         fclose(list_file);
  532.         if(clear) LIST_clear(list);
  533.         return true;
  534.     }
  535.     printf(" [LIST] LIST_save(): Failed to open or create file \"%s\".", file_name);
  536.     return false;
  537. }
  538. stock bool:LIST_load(List:list[], const file_name[], bool:rewrite = true)
  539. {
  540.     new File:list_file = fopen(file_name, io_read);
  541.     if(list_file)
  542.     {
  543.         new Pointer:next_LIST_ptr, arr_size, i, j, k, buffer, buffer_temp
  544. #if !defined SECURE_MEMORY_PLUGIN
  545.             , Pointer:data_ptr
  546. #endif
  547.             ;
  548.         for(i = 0; i < sizeof LIST_file_header; i++)
  549.         {
  550.             if(LIST_file_header[i] == fgetchar(list_file, 0, false)) continue;
  551.             fclose(list_file);
  552.             printf(" [LIST] LIST_load(): Invalid file header. \"%s\"", file_name);
  553.             if(rewrite) LIST_clear(list);
  554.             return false;
  555.         }
  556.         if(rewrite) LIST_clear(list);
  557.         for(i = 1; ; i++)
  558.         {
  559.             if(fgetchar(list_file, 0, false) != 1) break;
  560.             for(arr_size = (j = 0); j < 4; j++)
  561.             {
  562.                 if((buffer_temp = fgetchar(list_file, 0, false)) == EOF)
  563.                 {
  564.                     fclose(list_file);
  565.                     printf(" [LIST] LIST_load(): Unexpected end of file. \"%s\"", file_name);
  566.                     if(rewrite) LIST_clear(list);
  567.                     return false;
  568.                 }
  569.                 arr_size |= (buffer_temp&0xFF)<<(j*8);
  570.             }
  571.             if(arr_size < 1)
  572.             {
  573.                 fclose(list_file);
  574.                 printf(" [LIST] LIST_load(): Invalid array size (%d) at %d. node. \"%s\"", arr_size, i, file_name);
  575.                 if(rewrite) LIST_clear(list);
  576.                 return false;
  577.             }
  578.             if((next_LIST_ptr = MEM::calloc(arr_size+LIST_IT_data_data_offset)) == Pointer:LIST_NULL_)
  579.             {
  580.                 fclose(list_file);
  581.                 if(rewrite) LIST_clear(list);
  582.                 return false;
  583.             }
  584.             if(list[LIST_base_end])
  585.             {
  586.                 MEM::set_val(Pointer:list[LIST_base_end], LIST_IT_data_next, _:next_LIST_ptr);
  587.                 MEM::set_val(next_LIST_ptr, LIST_IT_data_previous, list[LIST_base_end]);
  588.             }
  589.             else if(list[LIST_base_begin] == LIST_NULL_) list[LIST_base_begin] = _:next_LIST_ptr;
  590.             list[LIST_base_end] = _:next_LIST_ptr;
  591.             MEM::set_val(next_LIST_ptr, LIST_IT_data_data_size, arr_size);
  592. #if !defined SECURE_MEMORY_PLUGIN
  593.             data_ptr = MEM_EX::get_ptr(next_LIST_ptr->LIST_IT_data_data_offset);
  594. #endif
  595.             for(j = 0; j < arr_size; j++)
  596.             {
  597.                 for(buffer = (k = 0); k < 4; k++)
  598.                 {
  599.                     if((buffer_temp = fgetchar(list_file, 0, false)) == EOF)
  600.                     {
  601.                         fclose(list_file);
  602.                         printf(" [LIST] LIST_load(): Unexpected end of file. \"%s\"", file_name);
  603.                         if(rewrite) LIST_clear(list);
  604.                         return false;
  605.                     }
  606.                     buffer |= (buffer_temp&0xFF)<<(k*8);
  607.                 }
  608. #if defined SECURE_MEMORY_PLUGIN
  609.             MEM::set_val(next_LIST_ptr, LIST_IT_data_data_offset+j, buffer);
  610. #else
  611.             MEM::set_val(data_ptr, j, buffer);
  612. #endif
  613.             }
  614.         }
  615.         fclose(list_file);
  616.         return true;
  617.     }
  618.     printf(" [LIST] LIST_load(): Failed to open file \"%s\".", file_name);
  619.     return false;
  620. }
  621. #define LIST::                          LIST_
  622. #define LIST_IT::                       LIST_IT_
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement