Want more features on Pastebin? Sign Up, it's FREE!

list.inc

By: BigETI on Jul 18th, 2013  |  syntax: PAWN  |  size: 22.51 KB  |  views: 255  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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_
clone this paste RAW Paste Data