Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
SNBTLib - write.c

write.c

Caricato da: ZioCrocifisso
Scarica il programma completo

  1. /*
  2.  * Copyright (c) 2013, ZioCrocifisso
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright notice, this
  9.  *    list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright notice,
  11.  *    this list of conditions and the following disclaimer in the documentation
  12.  *    and/or other materials provided with the distribution.
  13.  *
  14.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17.  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  18.  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24.  */
  25.  
  26. #include <zlib.h>
  27.  
  28. #include "nbt.h"
  29.  
  30. static int nbt_write_payload(gzFile file, nbt_byte id, nbt_payload *payload);
  31. static int nbt_write_tag(gzFile file, nbt_tag *tag);
  32. static int nbt_write_byte(gzFile file, nbt_byte *payload);
  33. static int nbt_write_short(gzFile file, nbt_short *payload);
  34. static int nbt_write_int(gzFile file, nbt_int *payload);
  35. static int nbt_write_long(gzFile file, nbt_long *payload);
  36. static int nbt_write_float(gzFile file, nbt_float *payload);
  37. static int nbt_write_double(gzFile file, nbt_double *payload);
  38. static int nbt_write_byte_array(gzFile file, nbt_byte_array *payload);
  39. static int nbt_write_string(gzFile file, nbt_string *payload);
  40. static int nbt_write_list(gzFile file, nbt_list *payload);
  41. static int nbt_write_compound(gzFile file, nbt_compound *payload);
  42. static int nbt_write_int_array(gzFile file, nbt_int_array *payload);
  43.  
  44. int nbt_write(nbt_tag *tag, char *path)
  45. {
  46.         int res;
  47.         gzFile file;
  48.  
  49.         if (!tag) {
  50.                 return NBT_ERR_INVALID_ARG;
  51.         }
  52.  
  53.         file = gzopen(path, "wb");
  54.  
  55.         if (!file) {
  56.                 return NBT_ERR_FILE;
  57.         }
  58.  
  59.         res = nbt_write_tag(file, tag);
  60.         gzclose(file);
  61.  
  62.         return res;
  63. }
  64.  
  65. static int nbt_write_payload(gzFile file, nbt_byte id, nbt_payload *payload)
  66. {
  67.         switch (id) {
  68.                 case NBT_TAG_END:
  69.                         return 0;
  70.  
  71.                 case NBT_TAG_BYTE:
  72.                         return nbt_write_byte(file, (nbt_byte *) payload);
  73.  
  74.                 case NBT_TAG_SHORT:
  75.                         return nbt_write_short(file, (nbt_short *) payload);
  76.  
  77.                 case NBT_TAG_INT:
  78.                         return nbt_write_int(file, (nbt_int *) payload);
  79.  
  80.                 case NBT_TAG_LONG:
  81.                         return nbt_write_long(file, (nbt_long *) payload);
  82.  
  83.                 case NBT_TAG_FLOAT:
  84.                         return nbt_write_float(file, (nbt_float *) payload);
  85.  
  86.                 case NBT_TAG_DOUBLE:
  87.                         return nbt_write_double(file, (nbt_double *) payload);
  88.  
  89.                 case NBT_TAG_BYTE_ARRAY:
  90.                         return nbt_write_byte_array(file, (nbt_byte_array *) payload);
  91.  
  92.                 case NBT_TAG_STRING:
  93.                         return nbt_write_string(file, (nbt_string *) payload);
  94.  
  95.                 case NBT_TAG_LIST:
  96.                         return nbt_write_list(file, (nbt_list *) payload);
  97.  
  98.                 case NBT_TAG_COMPOUND:
  99.                         return nbt_write_compound(file, (nbt_compound *) payload);
  100.  
  101.                 case NBT_TAG_INT_ARRAY:
  102.                         return nbt_write_int_array(file, (nbt_int_array *) payload);
  103.  
  104.                 default:
  105.                         return NBT_ERR_INVALID_ID;
  106.         }
  107. }
  108.  
  109. static int nbt_write_tag(gzFile file, nbt_tag *tag)
  110. {
  111.         int written = 0;
  112.  
  113.         if (!tag) {
  114.                 return NBT_ERR_NULL_PTR;
  115.         }
  116.  
  117.         written += nbt_write_byte(file, &tag->id);
  118.  
  119.         if (tag->id != NBT_TAG_END) {
  120.                 written += nbt_write_string(file, &tag->name);
  121.                 written += nbt_write_payload(file, tag->id, &tag->payload);
  122.         }
  123.  
  124.         return written;
  125. }
  126.  
  127. static int nbt_write_byte(gzFile file, nbt_byte *payload)
  128. {
  129.         return payload ? gzwrite(file, payload, 1) : NBT_ERR_NULL_PTR;
  130. }
  131.  
  132. static int nbt_write_short(gzFile file, nbt_short *payload)
  133. {
  134.         int written = 0;
  135.  
  136.         if (!payload) {
  137.                 return NBT_ERR_NULL_PTR;
  138.         }
  139.  
  140.         written += gzwrite(file, ((nbt_byte *) payload) + 1, 1);
  141.         written += gzwrite(file, ((nbt_byte *) payload), 1);
  142.  
  143.         return written;
  144. }
  145.  
  146. static int nbt_write_int(gzFile file, nbt_int *payload)
  147. {
  148.         int written = 0;
  149.  
  150.         if (!payload) {
  151.                 return NBT_ERR_NULL_PTR;
  152.         }
  153.  
  154.         written += gzwrite(file, ((nbt_byte *) payload) + 3, 1);
  155.         written += gzwrite(file, ((nbt_byte *) payload) + 2, 1);
  156.         written += gzwrite(file, ((nbt_byte *) payload) + 1, 1);
  157.         written += gzwrite(file, ((nbt_byte *) payload), 1);
  158.  
  159.         return written;
  160. }
  161.  
  162. static int nbt_write_long(gzFile file, nbt_long *payload)
  163. {
  164.         int written = 0;
  165.  
  166.         if (!payload) {
  167.                 return NBT_ERR_NULL_PTR;
  168.         }
  169.  
  170.         written += gzwrite(file, ((nbt_byte *) payload) + 7, 1);
  171.         written += gzwrite(file, ((nbt_byte *) payload) + 6, 1);
  172.         written += gzwrite(file, ((nbt_byte *) payload) + 5, 1);
  173.         written += gzwrite(file, ((nbt_byte *) payload) + 4, 1);
  174.         written += gzwrite(file, ((nbt_byte *) payload) + 3, 1);
  175.         written += gzwrite(file, ((nbt_byte *) payload) + 2, 1);
  176.         written += gzwrite(file, ((nbt_byte *) payload) + 1, 1);
  177.         written += gzwrite(file, ((nbt_byte *) payload), 1);
  178.  
  179.         return written;
  180. }
  181.  
  182. static int nbt_write_float(gzFile file, nbt_float *payload)
  183. {
  184.         int written = 0;
  185.  
  186.         if (!payload) {
  187.                 return NBT_ERR_NULL_PTR;
  188.         }
  189.  
  190.         written += gzwrite(file, ((nbt_byte *) payload) + 3, 1);
  191.         written += gzwrite(file, ((nbt_byte *) payload) + 2, 1);
  192.         written += gzwrite(file, ((nbt_byte *) payload) + 1, 1);
  193.         written += gzwrite(file, ((nbt_byte *) payload), 1);
  194.  
  195.         return written;
  196. }
  197.  
  198. static int nbt_write_double(gzFile file, nbt_double *payload)
  199. {
  200.         int written = 0;
  201.  
  202.         if (!payload) {
  203.                 return NBT_ERR_NULL_PTR;
  204.         }
  205.  
  206.         written += gzwrite(file, ((nbt_byte *) payload) + 7, 1);
  207.         written += gzwrite(file, ((nbt_byte *) payload) + 6, 1);
  208.         written += gzwrite(file, ((nbt_byte *) payload) + 5, 1);
  209.         written += gzwrite(file, ((nbt_byte *) payload) + 4, 1);
  210.         written += gzwrite(file, ((nbt_byte *) payload) + 3, 1);
  211.         written += gzwrite(file, ((nbt_byte *) payload) + 2, 1);
  212.         written += gzwrite(file, ((nbt_byte *) payload) + 1, 1);
  213.         written += gzwrite(file, ((nbt_byte *) payload), 1);
  214.  
  215.         return written;
  216. }
  217.  
  218. static int nbt_write_byte_array(gzFile file, nbt_byte_array *payload)
  219. {
  220.         int i, res, written = 0;
  221.  
  222.         if (!payload) {
  223.                 return NBT_ERR_NULL_PTR;
  224.         }
  225.  
  226.         res = nbt_write_int(file, &payload->size);
  227.  
  228.         if (!res) {
  229.                 return written;
  230.         }
  231.  
  232.         written += res;
  233.  
  234.         for (i = 0; i < payload->size; i++) {
  235.                 res = gzwrite(file, payload->bytes + i, 1);
  236.  
  237.                 if (res) {
  238.                         written += res;
  239.                 }
  240.         }
  241.  
  242.         return written;
  243. }
  244.  
  245. static int nbt_write_string(gzFile file, nbt_string *payload)
  246. {
  247.         int i, res, written = 0;
  248.  
  249.         if (!payload) {
  250.                 return NBT_ERR_NULL_PTR;
  251.         }
  252.  
  253.         res = nbt_write_short(file, &payload->length);
  254.  
  255.         if (!res) {
  256.                 return written;
  257.         }
  258.  
  259.         written += res;
  260.  
  261.         for (i = 0; i < payload->length; i++) {
  262.                 res = gzwrite(file, payload->chars + i, 1);
  263.  
  264.                 if (res) {
  265.                         written += res;
  266.                 }
  267.         }
  268.  
  269.         return written;
  270. }
  271.  
  272. static int nbt_write_list(gzFile file, nbt_list *payload)
  273. {
  274.         int i, res, written = 0;
  275.  
  276.         if (!payload) {
  277.                 return NBT_ERR_NULL_PTR;
  278.         }
  279.  
  280.         res = nbt_write_byte(file, &payload->tag_id);
  281.  
  282.         if (!res) {
  283.                 return written;
  284.         }
  285.  
  286.         written += res;
  287.         res = nbt_write_int(file, &payload->size);
  288.  
  289.         if (!res) {
  290.                 return written;
  291.         }
  292.  
  293.         written += res;
  294.  
  295.         for (i = 0; i < payload->size; i++) {
  296.                 res = nbt_write_payload(file, payload->tag_id, (nbt_payload *) (payload->tags + i));
  297.  
  298.                 if (res) {
  299.                         written += res;
  300.                 }
  301.         }
  302.  
  303.         return written;
  304. }
  305.  
  306. static int nbt_write_compound(gzFile file, nbt_compound *payload)
  307. {
  308.         int res, written = 0;
  309.         nbt_tag *curr;
  310.  
  311.         if (!payload) {
  312.                 return NBT_ERR_NULL_PTR;
  313.         }
  314.  
  315.         for (curr = * (nbt_tag **) payload;; curr++) {
  316.                 res = nbt_write_tag(file, curr);
  317.  
  318.                 if (res) {
  319.                         written += res;
  320.                 }
  321.  
  322.                 if (curr->id == NBT_TAG_END) {
  323.                         break;
  324.                 }
  325.         }
  326.  
  327.         return written;
  328. }
  329.  
  330. static int nbt_write_int_array(gzFile file, nbt_int_array *payload)
  331. {
  332.         int i, res, written = 0;
  333.  
  334.         if (!payload) {
  335.                 return NBT_ERR_NULL_PTR;
  336.         }
  337.  
  338.         res = nbt_write_int(file, &payload->size);
  339.  
  340.         if (!res) {
  341.                 return written;
  342.         }
  343.  
  344.         written += res;
  345.  
  346.         for (i = 0; i < payload->size; i++) {
  347.                 res = nbt_write_int(file, payload->ints + i);
  348.  
  349.                 if (res) {
  350.                         written += res;
  351.                 }
  352.         }
  353.  
  354.         return written;
  355. }