1
0

Cloner.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "benc/serialization/cloner/Cloner.h"
  16. #include "memory/Allocator.h"
  17. #include "benc/List.h"
  18. #include "benc/Dict.h"
  19. #include "benc/String.h"
  20. static Object* clone(Object* orig, struct Allocator* alloc);
  21. static struct List_Item* cloneList(struct List_Item* orig, struct Allocator* alloc)
  22. {
  23. if (!orig) { return NULL; }
  24. struct List_Item* out = Allocator_malloc(alloc, sizeof(struct List_Item));
  25. out->elem = clone(orig->elem, alloc);
  26. out->next = cloneList(orig->next, alloc);
  27. return out;
  28. }
  29. static struct Dict_Entry* cloneDict(struct Dict_Entry* orig, struct Allocator* alloc)
  30. {
  31. if (!orig) { return NULL; }
  32. struct Dict_Entry* out = Allocator_malloc(alloc, sizeof(struct Dict_Entry));
  33. out->key = String_clone(orig->key, alloc);
  34. out->val = clone(orig->val, alloc);
  35. out->next = cloneDict(orig->next, alloc);
  36. return out;
  37. }
  38. static Object* clone(Object* orig, struct Allocator* alloc)
  39. {
  40. Object* out = Allocator_malloc(alloc, sizeof(Object));
  41. out->type = orig->type;
  42. switch (orig->type) {
  43. case Object_INTEGER: out->as.number = orig->as.number; break;
  44. case Object_STRING: out->as.string = String_clone(orig->as.string, alloc); break;
  45. case Object_LIST: out->as.list = Cloner_cloneList(orig->as.list, alloc); break;
  46. case Object_DICT: out->as.dictionary = Cloner_cloneDict(orig->as.dictionary, alloc); break;
  47. default: Assert_true(0);
  48. }
  49. return out;
  50. }
  51. Dict* Cloner_cloneDict(Dict* orig, struct Allocator* alloc)
  52. {
  53. Dict* out = Allocator_malloc(alloc, sizeof(Dict));
  54. *out = cloneDict(*orig, alloc);
  55. return out;
  56. }
  57. List* Cloner_cloneList(List* orig, struct Allocator* alloc)
  58. {
  59. List* out = Allocator_malloc(alloc, sizeof(List));
  60. *out = cloneList(*orig, alloc);
  61. return out;
  62. }