diff options
Diffstat (limited to 'core/io')
69 files changed, 1843 insertions, 6526 deletions
diff --git a/core/io/SCsub b/core/io/SCsub index 5aecb4b915..3ff9b355a4 100644 --- a/core/io/SCsub +++ b/core/io/SCsub @@ -5,5 +5,3 @@ env.add_source_files(env.core_sources,"*.c") #env.core_sources.append("io/fastlz.c") Export('env') - - diff --git a/core/io/aes256.cpp b/core/io/aes256.cpp index 69a5091f1d..cfdac0214d 100644 --- a/core/io/aes256.cpp +++ b/core/io/aes256.cpp @@ -1,359 +1,399 @@ -/*
-* Byte-oriented AES-256 implementation.
-* All lookup tables replaced with 'on the fly' calculations.
-*
-* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
-* Other contributors: Hal Finney
-*
-* Permission to use, copy, modify, and distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-#include "aes256.h"
-
-#define F(x) (((x)<<1) ^ ((((x)>>7) & 1) * 0x1b))
-#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))
-
-// #define BACK_TO_TABLES
-#ifdef BACK_TO_TABLES
-
-const uint8_t sbox[256] = {
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
- 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
- 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
- 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
- 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
- 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
- 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
- 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
- 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
- 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
- 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
- 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
- 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
- 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
- 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
- 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
- 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-const uint8_t sboxinv[256] = {
- 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
- 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
- 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
- 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
- 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
- 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
- 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
- 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
- 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
- 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
- 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
- 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
- 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
- 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
- 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
- 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
- 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
- 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
- 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
- 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
- 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
- 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
- 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
- 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
- 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
- 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
- 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
- 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
- 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
- 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
- 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
- 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-};
-
-#define rj_sbox(x) sbox[(x)]
-#define rj_sbox_inv(x) sboxinv[(x)]
-
-#else /* tableless subroutines */
-
-/* -------------------------------------------------------------------------- */
-uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3
-{
- uint8_t atb = 1, z;
-
- while (x--) {z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;}
-
- return atb;
-} /* gf_alog */
-
-/* -------------------------------------------------------------------------- */
-uint8_t gf_log(uint8_t x) // calculate logarithm gen 3
-{
- uint8_t atb = 1, i = 0, z;
-
- do {
- if (atb == x) break;
- z = atb; atb <<= 1; if (z & 0x80) atb^= 0x1b; atb ^= z;
- } while (++i > 0);
-
- return i;
-} /* gf_log */
-
-
-/* -------------------------------------------------------------------------- */
-uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse
-{
- return (x) ? gf_alog(255 - gf_log(x)) : 0;
-} /* gf_mulinv */
-
-/* -------------------------------------------------------------------------- */
-uint8_t rj_sbox(uint8_t x)
-{
- uint8_t y, sb;
-
- sb = y = gf_mulinv(x);
- y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y;
- y = (y<<1)|(y>>7); sb ^= y; y = (y<<1)|(y>>7); sb ^= y;
-
- return (sb ^ 0x63);
-} /* rj_sbox */
-
-/* -------------------------------------------------------------------------- */
-uint8_t rj_sbox_inv(uint8_t x)
-{
- uint8_t y, sb;
-
- y = x ^ 0x63;
- sb = y = (y<<1)|(y>>7);
- y = (y<<2)|(y>>6); sb ^= y; y = (y<<3)|(y>>5); sb ^= y;
-
- return gf_mulinv(sb);
-} /* rj_sbox_inv */
-
-#endif
-
-/* -------------------------------------------------------------------------- */
-uint8_t rj_xtime(uint8_t x)
-{
- return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);
-} /* rj_xtime */
-
-/* -------------------------------------------------------------------------- */
-void aes_subBytes(uint8_t *buf)
-{
- register uint8_t i = 16;
-
- while (i--) buf[i] = rj_sbox(buf[i]);
-} /* aes_subBytes */
-
-/* -------------------------------------------------------------------------- */
-void aes_subBytes_inv(uint8_t *buf)
-{
- register uint8_t i = 16;
-
- while (i--) buf[i] = rj_sbox_inv(buf[i]);
-} /* aes_subBytes_inv */
-
-/* -------------------------------------------------------------------------- */
-void aes_addRoundKey(uint8_t *buf, uint8_t *key)
-{
- register uint8_t i = 16;
-
- while (i--) buf[i] ^= key[i];
-} /* aes_addRoundKey */
-
-/* -------------------------------------------------------------------------- */
-void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk)
-{
- register uint8_t i = 16;
-
- while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16+i] = key[16 + i];
-} /* aes_addRoundKey_cpy */
-
-
-/* -------------------------------------------------------------------------- */
-void aes_shiftRows(uint8_t *buf)
-{
- register uint8_t i, j; /* to make it potentially parallelable :) */
-
- i = buf[1]; buf[1] = buf[5]; buf[5] = buf[9]; buf[9] = buf[13]; buf[13] = i;
- i = buf[10]; buf[10] = buf[2]; buf[2] = i;
- j = buf[3]; buf[3] = buf[15]; buf[15] = buf[11]; buf[11] = buf[7]; buf[7] = j;
- j = buf[14]; buf[14] = buf[6]; buf[6] = j;
-
-} /* aes_shiftRows */
-
-/* -------------------------------------------------------------------------- */
-void aes_shiftRows_inv(uint8_t *buf)
-{
- register uint8_t i, j; /* same as above :) */
-
- i = buf[1]; buf[1] = buf[13]; buf[13] = buf[9]; buf[9] = buf[5]; buf[5] = i;
- i = buf[2]; buf[2] = buf[10]; buf[10] = i;
- j = buf[3]; buf[3] = buf[7]; buf[7] = buf[11]; buf[11] = buf[15]; buf[15] = j;
- j = buf[6]; buf[6] = buf[14]; buf[14] = j;
-
-} /* aes_shiftRows_inv */
-
-/* -------------------------------------------------------------------------- */
-void aes_mixColumns(uint8_t *buf)
-{
- register uint8_t i, a, b, c, d, e;
-
- for (i = 0; i < 16; i += 4)
- {
- a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3];
- e = a ^ b ^ c ^ d;
- buf[i] ^= e ^ rj_xtime(a^b); buf[i+1] ^= e ^ rj_xtime(b^c);
- buf[i+2] ^= e ^ rj_xtime(c^d); buf[i+3] ^= e ^ rj_xtime(d^a);
- }
-} /* aes_mixColumns */
-
-/* -------------------------------------------------------------------------- */
-void aes_mixColumns_inv(uint8_t *buf)
-{
- register uint8_t i, a, b, c, d, e, x, y, z;
-
- for (i = 0; i < 16; i += 4)
- {
- a = buf[i]; b = buf[i + 1]; c = buf[i + 2]; d = buf[i + 3];
- e = a ^ b ^ c ^ d;
- z = rj_xtime(e);
- x = e ^ rj_xtime(rj_xtime(z^a^c)); y = e ^ rj_xtime(rj_xtime(z^b^d));
- buf[i] ^= x ^ rj_xtime(a^b); buf[i+1] ^= y ^ rj_xtime(b^c);
- buf[i+2] ^= x ^ rj_xtime(c^d); buf[i+3] ^= y ^ rj_xtime(d^a);
- }
-} /* aes_mixColumns_inv */
-
-/* -------------------------------------------------------------------------- */
-void aes_expandEncKey(uint8_t *k, uint8_t *rc)
-{
- register uint8_t i;
-
- k[0] ^= rj_sbox(k[29]) ^ (*rc);
- k[1] ^= rj_sbox(k[30]);
- k[2] ^= rj_sbox(k[31]);
- k[3] ^= rj_sbox(k[28]);
- *rc = F( *rc);
-
- for(i = 4; i < 16; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
- k[16] ^= rj_sbox(k[12]);
- k[17] ^= rj_sbox(k[13]);
- k[18] ^= rj_sbox(k[14]);
- k[19] ^= rj_sbox(k[15]);
-
- for(i = 20; i < 32; i += 4) k[i] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
-
-} /* aes_expandEncKey */
-
-/* -------------------------------------------------------------------------- */
-void aes_expandDecKey(uint8_t *k, uint8_t *rc)
-{
- uint8_t i;
-
- for(i = 28; i > 16; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
-
- k[16] ^= rj_sbox(k[12]);
- k[17] ^= rj_sbox(k[13]);
- k[18] ^= rj_sbox(k[14]);
- k[19] ^= rj_sbox(k[15]);
-
- for(i = 12; i > 0; i -= 4) k[i+0] ^= k[i-4], k[i+1] ^= k[i-3],
- k[i+2] ^= k[i-2], k[i+3] ^= k[i-1];
-
- *rc = FD(*rc);
- k[0] ^= rj_sbox(k[29]) ^ (*rc);
- k[1] ^= rj_sbox(k[30]);
- k[2] ^= rj_sbox(k[31]);
- k[3] ^= rj_sbox(k[28]);
-} /* aes_expandDecKey */
-
-
-/* -------------------------------------------------------------------------- */
-void aes256_init(aes256_context *ctx, uint8_t *k)
-{
- uint8_t rcon = 1;
- register uint8_t i;
-
- for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];
- for (i = 8;--i;) aes_expandEncKey(ctx->deckey, &rcon);
-} /* aes256_init */
-
-/* -------------------------------------------------------------------------- */
-void aes256_done(aes256_context *ctx)
-{
- register uint8_t i;
-
- for (i = 0; i < sizeof(ctx->key); i++)
- ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;
-} /* aes256_done */
-
-/* -------------------------------------------------------------------------- */
-void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf)
-{
- uint8_t i, rcon;
-
- aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
- for(i = 1, rcon = 1; i < 14; ++i)
- {
- aes_subBytes(buf);
- aes_shiftRows(buf);
- aes_mixColumns(buf);
- if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]);
- else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
- }
- aes_subBytes(buf);
- aes_shiftRows(buf);
- aes_expandEncKey(ctx->key, &rcon);
- aes_addRoundKey(buf, ctx->key);
-} /* aes256_encrypt */
-
-/* -------------------------------------------------------------------------- */
-void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf)
-{
- uint8_t i, rcon;
-
- aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
- aes_shiftRows_inv(buf);
- aes_subBytes_inv(buf);
-
- for (i = 14, rcon = 0x80; --i;)
- {
- if( ( i & 1 ) )
- {
- aes_expandDecKey(ctx->key, &rcon);
- aes_addRoundKey(buf, &ctx->key[16]);
- }
- else aes_addRoundKey(buf, ctx->key);
- aes_mixColumns_inv(buf);
- aes_shiftRows_inv(buf);
- aes_subBytes_inv(buf);
- }
- aes_addRoundKey( buf, ctx->key);
-} /* aes256_decrypt */
+/* +* Byte-oriented AES-256 implementation. +* All lookup tables replaced with 'on the fly' calculations. +* +* Copyright (c) 2007-2011 Ilya O. Levin, http://www.literatecode.com +* Other contributors: Hal Finney +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +#include "aes256.h" + +#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0)) + +#define BACK_TO_TABLES + +static uint8_t rj_xtime(uint8_t); +static void aes_subBytes(uint8_t *); +static void aes_subBytes_inv(uint8_t *); +static void aes_addRoundKey(uint8_t *, uint8_t *); +static void aes_addRoundKey_cpy(uint8_t *, uint8_t *, uint8_t *); +static void aes_shiftRows(uint8_t *); +static void aes_shiftRows_inv(uint8_t *); +static void aes_mixColumns(uint8_t *); +static void aes_mixColumns_inv(uint8_t *); +static void aes_expandEncKey(uint8_t *, uint8_t *); +static void aes_expandDecKey(uint8_t *, uint8_t *); +#ifndef BACK_TO_TABLES +static uint8_t gf_alog(uint8_t); +static uint8_t gf_log(uint8_t); +static uint8_t gf_mulinv(uint8_t); +static uint8_t rj_sbox(uint8_t); +static uint8_t rj_sbox_inv(uint8_t); +#endif + +#ifdef BACK_TO_TABLES + +static const uint8_t sbox[256] = +{ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; +static const uint8_t sboxinv[256] = +{ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +}; + +#define rj_sbox(x) sbox[(x)] +#define rj_sbox_inv(x) sboxinv[(x)] + +#else /* tableless subroutines */ + +/* -------------------------------------------------------------------------- */ +static uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3 +{ + uint8_t y = 1, i; + + for (i = 0; i < x; i++) y ^= rj_xtime(y); + + return y; +} /* gf_alog */ + +/* -------------------------------------------------------------------------- */ +static uint8_t gf_log(uint8_t x) // calculate logarithm gen 3 +{ + uint8_t y, i = 0; + + if (x) + for (i = 1, y = 1; i > 0; i++ ) + { + y ^= rj_xtime(y); + if (y == x) break; + } + + return i; +} /* gf_log */ + + +/* -------------------------------------------------------------------------- */ +static uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse +{ + return (x) ? gf_alog(255 - gf_log(x)) : 0; +} /* gf_mulinv */ + +/* -------------------------------------------------------------------------- */ +static uint8_t rj_sbox(uint8_t x) +{ + uint8_t y, sb; + + sb = y = gf_mulinv(x); + y = (uint8_t)(y << 1) | (y >> 7), sb ^= y; + y = (uint8_t)(y << 1) | (y >> 7), sb ^= y; + y = (uint8_t)(y << 1) | (y >> 7), sb ^= y; + y = (uint8_t)(y << 1) | (y >> 7), sb ^= y; + + return (sb ^ 0x63); +} /* rj_sbox */ + +/* -------------------------------------------------------------------------- */ +static uint8_t rj_sbox_inv(uint8_t x) +{ + uint8_t y, sb; + + y = x ^ 0x63; + sb = y = (uint8_t)(y << 1) | (y >> 7); + y = (uint8_t)(y << 2) | (y >> 6); + sb ^= y; + y = (uint8_t)(y << 3) | (y >> 5); + sb ^= y; + + return gf_mulinv(sb); +} /* rj_sbox_inv */ + +#endif + +/* -------------------------------------------------------------------------- */ +static uint8_t rj_xtime(uint8_t x) +{ + uint8_t y = (uint8_t)(x << 1); + return (x & 0x80) ? (y ^ 0x1b) : y; +} /* rj_xtime */ + +/* -------------------------------------------------------------------------- */ +static void aes_subBytes(uint8_t *buf) +{ + register uint8_t i = 16; + + while (i--) buf[i] = rj_sbox(buf[i]); +} /* aes_subBytes */ + +/* -------------------------------------------------------------------------- */ +static void aes_subBytes_inv(uint8_t *buf) +{ + register uint8_t i = 16; + + while (i--) buf[i] = rj_sbox_inv(buf[i]); +} /* aes_subBytes_inv */ + +/* -------------------------------------------------------------------------- */ +static void aes_addRoundKey(uint8_t *buf, uint8_t *key) +{ + register uint8_t i = 16; + + while (i--) buf[i] ^= key[i]; +} /* aes_addRoundKey */ + +/* -------------------------------------------------------------------------- */ +static void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk) +{ + register uint8_t i = 16; + + while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i]; +} /* aes_addRoundKey_cpy */ + + +/* -------------------------------------------------------------------------- */ +static void aes_shiftRows(uint8_t *buf) +{ + register uint8_t i, j; /* to make it potentially parallelable :) */ + + i = buf[1], buf[1] = buf[5], buf[5] = buf[9], buf[9] = buf[13], buf[13] = i; + i = buf[10], buf[10] = buf[2], buf[2] = i; + j = buf[3], buf[3] = buf[15], buf[15] = buf[11], buf[11] = buf[7], buf[7] = j; + j = buf[14], buf[14] = buf[6], buf[6] = j; + +} /* aes_shiftRows */ + +/* -------------------------------------------------------------------------- */ +static void aes_shiftRows_inv(uint8_t *buf) +{ + register uint8_t i, j; /* same as above :) */ + + i = buf[1], buf[1] = buf[13], buf[13] = buf[9], buf[9] = buf[5], buf[5] = i; + i = buf[2], buf[2] = buf[10], buf[10] = i; + j = buf[3], buf[3] = buf[7], buf[7] = buf[11], buf[11] = buf[15], buf[15] = j; + j = buf[6], buf[6] = buf[14], buf[14] = j; + +} /* aes_shiftRows_inv */ + +/* -------------------------------------------------------------------------- */ +static void aes_mixColumns(uint8_t *buf) +{ + register uint8_t i, a, b, c, d, e; + + for (i = 0; i < 16; i += 4) + { + a = buf[i]; + b = buf[i + 1]; + c = buf[i + 2]; + d = buf[i + 3]; + e = a ^ b ^ c ^ d; + buf[i] ^= e ^ rj_xtime(a ^ b); + buf[i + 1] ^= e ^ rj_xtime(b ^ c); + buf[i + 2] ^= e ^ rj_xtime(c ^ d); + buf[i + 3] ^= e ^ rj_xtime(d ^ a); + } +} /* aes_mixColumns */ + +/* -------------------------------------------------------------------------- */ +void aes_mixColumns_inv(uint8_t *buf) +{ + register uint8_t i, a, b, c, d, e, x, y, z; + + for (i = 0; i < 16; i += 4) + { + a = buf[i]; + b = buf[i + 1]; + c = buf[i + 2]; + d = buf[i + 3]; + e = a ^ b ^ c ^ d; + z = rj_xtime(e); + x = e ^ rj_xtime(rj_xtime(z ^ a ^ c)); + y = e ^ rj_xtime(rj_xtime(z ^ b ^ d)); + buf[i] ^= x ^ rj_xtime(a ^ b); + buf[i + 1] ^= y ^ rj_xtime(b ^ c); + buf[i + 2] ^= x ^ rj_xtime(c ^ d); + buf[i + 3] ^= y ^ rj_xtime(d ^ a); + } +} /* aes_mixColumns_inv */ + +/* -------------------------------------------------------------------------- */ +static void aes_expandEncKey(uint8_t *k, uint8_t *rc) +{ + register uint8_t i; + + k[0] ^= rj_sbox(k[29]) ^ (*rc); + k[1] ^= rj_sbox(k[30]); + k[2] ^= rj_sbox(k[31]); + k[3] ^= rj_sbox(k[28]); + *rc = rj_xtime( *rc); + + for(i = 4; i < 16; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3], + k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1]; + k[16] ^= rj_sbox(k[12]); + k[17] ^= rj_sbox(k[13]); + k[18] ^= rj_sbox(k[14]); + k[19] ^= rj_sbox(k[15]); + + for(i = 20; i < 32; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3], + k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1]; + +} /* aes_expandEncKey */ + +/* -------------------------------------------------------------------------- */ +void aes_expandDecKey(uint8_t *k, uint8_t *rc) +{ + uint8_t i; + + for(i = 28; i > 16; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3], + k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1]; + + k[16] ^= rj_sbox(k[12]); + k[17] ^= rj_sbox(k[13]); + k[18] ^= rj_sbox(k[14]); + k[19] ^= rj_sbox(k[15]); + + for(i = 12; i > 0; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3], + k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1]; + + *rc = FD(*rc); + k[0] ^= rj_sbox(k[29]) ^ (*rc); + k[1] ^= rj_sbox(k[30]); + k[2] ^= rj_sbox(k[31]); + k[3] ^= rj_sbox(k[28]); +} /* aes_expandDecKey */ + + +/* -------------------------------------------------------------------------- */ +void aes256_init(aes256_context *ctx, uint8_t *k) +{ + uint8_t rcon = 1; + register uint8_t i; + + for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i]; + for (i = 8; --i;) aes_expandEncKey(ctx->deckey, &rcon); +} /* aes256_init */ + +/* -------------------------------------------------------------------------- */ +void aes256_done(aes256_context *ctx) +{ + register uint8_t i; + + for (i = 0; i < sizeof(ctx->key); i++) + ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0; +} /* aes256_done */ + +/* -------------------------------------------------------------------------- */ +void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf) +{ + uint8_t i, rcon; + + aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key); + for(i = 1, rcon = 1; i < 14; ++i) + { + aes_subBytes(buf); + aes_shiftRows(buf); + aes_mixColumns(buf); + if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]); + else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key); + } + aes_subBytes(buf); + aes_shiftRows(buf); + aes_expandEncKey(ctx->key, &rcon); + aes_addRoundKey(buf, ctx->key); +} /* aes256_encrypt */ + +/* -------------------------------------------------------------------------- */ +void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf) +{ + uint8_t i, rcon; + + aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key); + aes_shiftRows_inv(buf); + aes_subBytes_inv(buf); + + for (i = 14, rcon = 0x80; --i;) + { + if( ( i & 1 ) ) + { + aes_expandDecKey(ctx->key, &rcon); + aes_addRoundKey(buf, &ctx->key[16]); + } + else aes_addRoundKey(buf, ctx->key); + aes_mixColumns_inv(buf); + aes_shiftRows_inv(buf); + aes_subBytes_inv(buf); + } + aes_addRoundKey( buf, ctx->key); +} /* aes256_decrypt */ diff --git a/core/io/aes256.h b/core/io/aes256.h index 180352e970..fabbcf1968 100644 --- a/core/io/aes256.h +++ b/core/io/aes256.h @@ -1,46 +1,46 @@ -/*
-* Byte-oriented AES-256 implementation.
-* All lookup tables replaced with 'on the fly' calculations.
-*
-* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
-* Other contributors: Hal Finney
-*
-* Permission to use, copy, modify, and distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-#ifndef AES_256_H
-#define AES_256_H
-
-#include "typedefs.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- typedef struct {
- uint8_t key[32];
- uint8_t enckey[32];
- uint8_t deckey[32];
- } aes256_context;
-
-
- void aes256_init(aes256_context *, uint8_t * /* key */);
- void aes256_done(aes256_context *);
- void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */);
- void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/* +* Byte-oriented AES-256 implementation. +* All lookup tables replaced with 'on the fly' calculations. +* +* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com +* Other contributors: Hal Finney +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef AES_256_H +#define AES_256_H + +#include "typedefs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct { + uint8_t key[32]; + uint8_t enckey[32]; + uint8_t deckey[32]; + } aes256_context; + + + void aes256_init(aes256_context *, uint8_t * /* key */); + void aes256_done(aes256_context *); + void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */); + void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/io/compression.cpp b/core/io/compression.cpp index ea2f5d2d9c..729b7bec52 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,12 +26,12 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#include "zlib.h" +#include "os/copymem.h" #include "compression.h" #include "fastlz.h" -#include "zlib.h" #include "zip_io.h" -#include "os/copymem.h" int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode) { diff --git a/core/io/compression.h b/core/io/compression.h index 70742d42d6..106a3f0201 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,28 +26,28 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COMPRESSION_H
-#define COMPRESSION_H
-
-#include "typedefs.h"
-
-class Compression
-{
-public:
-
- enum Mode {
- MODE_FASTLZ,
- MODE_DEFLATE
- };
-
-
- static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode=MODE_FASTLZ);
- static int get_max_compressed_buffer_size(int p_src_size,Mode p_mode=MODE_FASTLZ);
- static void decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size,Mode p_mode=MODE_FASTLZ);
-
- Compression();
-};
-
-
-
-#endif // COMPRESSION_H
+#ifndef COMPRESSION_H +#define COMPRESSION_H + +#include "typedefs.h" + +class Compression +{ +public: + + enum Mode { + MODE_FASTLZ, + MODE_DEFLATE + }; + + + static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode=MODE_FASTLZ); + static int get_max_compressed_buffer_size(int p_src_size,Mode p_mode=MODE_FASTLZ); + static void decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size,Mode p_mode=MODE_FASTLZ); + + Compression(); +}; + + + +#endif // COMPRESSION_H diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 45e8cf69ab..75388f514a 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -357,6 +357,7 @@ if (res!=-1 && res < min_pos) {\ } break; case MIN_OPEN: { int level=1; + end++; while(end<close_pos) { if (str[end]=='[') @@ -373,6 +374,7 @@ if (res!=-1 && res < min_pos) {\ } break; case MIN_CURLY_OPEN: { int level=1; + end++; while(end<close_pos) { if (str[end]=='{') @@ -471,9 +473,12 @@ static Variant _decode_variant(const String& p_string) { ERR_FAIL_COND_V(params.size()!=1 && params.size()!=2,Variant()); int scode=0; - if (params[0].is_numeric()) + if (params[0].is_numeric()) { scode=params[0].to_int(); - else + if (scode < 10) { + scode=KEY_0+scode; + } + } else scode=find_keycode(params[0]); InputEvent ie; @@ -577,7 +582,7 @@ static Variant _decode_variant(const String& p_string) { int w=params[2].to_int(); int h=params[3].to_int(); - if (w == 0 && w == 0) { + if (w == 0 && h == 0) { //r_v = Image(w, h, imgformat); return Image(); }; diff --git a/core/io/config_file.h b/core/io/config_file.h index e132e46fea..608f143fb1 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp index 6927b3772f..ab17cb8118 100644 --- a/core/io/file_access_buffered.cpp +++ b/core/io/file_access_buffered.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_buffered.h b/core/io/file_access_buffered.h index 533cc6c7dd..e6de203cda 100644 --- a/core/io/file_access_buffered.h +++ b/core/io/file_access_buffered.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h index 5de2f66ace..d36c4843e4 100644 --- a/core/io/file_access_buffered_fa.h +++ b/core/io/file_access_buffered_fa.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index b90a41df54..1d06dc8c4b 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 3039b5c8be..69a03fa14f 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,76 +26,76 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef FILE_ACCESS_COMPRESSED_H
-#define FILE_ACCESS_COMPRESSED_H
-
-#include "io/compression.h"
-#include "os/file_access.h"
-
-class FileAccessCompressed : public FileAccess {
-
- Compression::Mode cmode;
- bool writing;
- int write_pos;
- uint8_t*write_ptr;
- int write_buffer_size;
- int write_max;
- int block_size;
- mutable bool read_eof;
- mutable bool at_end;
-
- struct ReadBlock {
- int csize;
- int offset;
- };
-
- mutable Vector<uint8_t> comp_buffer;
- uint8_t *read_ptr;
- mutable int read_block;
- int read_block_count;
- mutable int read_block_size;
- mutable int read_pos;
- Vector<ReadBlock> read_blocks;
- int read_total;
-
-
-
-
- String magic;
- mutable Vector<uint8_t> buffer;
- FileAccess *f;
-public:
-
- void configure(const String& p_magic, Compression::Mode p_mode=Compression::MODE_FASTLZ, int p_block_size=4096);
-
- Error open_after_magic(FileAccess *p_base);
-
- virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
- virtual void close(); ///< close a file
- virtual bool is_open() const; ///< true when file is open
-
- virtual void seek(size_t p_position); ///< seek to a given position
- virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
- virtual size_t get_pos() const; ///< get position in the file
- virtual size_t get_len() const; ///< get size of the file
-
- virtual bool eof_reached() const; ///< reading passed EOF
-
- virtual uint8_t get_8() const; ///< get a byte
- virtual int get_buffer(uint8_t *p_dst, int p_length) const;
-
- virtual Error get_error() const; ///< get last error
-
- virtual void store_8(uint8_t p_dest); ///< store a byte
-
- virtual bool file_exists(const String& p_name); ///< return true if a file exists
-
- virtual uint64_t _get_modified_time(const String& p_file);
-
-
- FileAccessCompressed();
- virtual ~FileAccessCompressed();
-
-};
-
-#endif // FILE_ACCESS_COMPRESSED_H
+#ifndef FILE_ACCESS_COMPRESSED_H +#define FILE_ACCESS_COMPRESSED_H + +#include "io/compression.h" +#include "os/file_access.h" + +class FileAccessCompressed : public FileAccess { + + Compression::Mode cmode; + bool writing; + int write_pos; + uint8_t*write_ptr; + int write_buffer_size; + int write_max; + int block_size; + mutable bool read_eof; + mutable bool at_end; + + struct ReadBlock { + int csize; + int offset; + }; + + mutable Vector<uint8_t> comp_buffer; + uint8_t *read_ptr; + mutable int read_block; + int read_block_count; + mutable int read_block_size; + mutable int read_pos; + Vector<ReadBlock> read_blocks; + int read_total; + + + + + String magic; + mutable Vector<uint8_t> buffer; + FileAccess *f; +public: + + void configure(const String& p_magic, Compression::Mode p_mode=Compression::MODE_FASTLZ, int p_block_size=4096); + + Error open_after_magic(FileAccess *p_base); + + virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file + virtual void close(); ///< close a file + virtual bool is_open() const; ///< true when file is open + + virtual void seek(size_t p_position); ///< seek to a given position + virtual void seek_end(int64_t p_position=0); ///< seek from the end of file + virtual size_t get_pos() const; ///< get position in the file + virtual size_t get_len() const; ///< get size of the file + + virtual bool eof_reached() const; ///< reading passed EOF + + virtual uint8_t get_8() const; ///< get a byte + virtual int get_buffer(uint8_t *p_dst, int p_length) const; + + virtual Error get_error() const; ///< get last error + + virtual void store_8(uint8_t p_dest); ///< store a byte + + virtual bool file_exists(const String& p_name); ///< return true if a file exists + + virtual uint64_t _get_modified_time(const String& p_file); + + + FileAccessCompressed(); + virtual ~FileAccessCompressed(); + +}; + +#endif // FILE_ACCESS_COMPRESSED_H diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 29f27dcbda..65b1ca5207 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -5,10 +5,12 @@ #include "print_string.h" #define COMP_MAGIC 0x43454447 +#include "core/variant.h" +#include <stdio.h> Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode) { - print_line("open and parse!"); + //print_line("open and parse!"); ERR_FAIL_COND_V(file!=NULL,ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(p_key.size()!=32,ERR_INVALID_PARAMETER); diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index a1dd2e48bb..83da55fc61 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,7 +39,7 @@ void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) { if (!files) { files = memnew((Map<String, Vector<uint8_t> >)); - }; + } String name; if (Globals::get_singleton()) @@ -49,7 +49,7 @@ void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) { name = DirAccess::normalize_path(name); (*files)[name] = p_data; -}; +} void FileAccessMemory::cleanup() { @@ -57,13 +57,13 @@ void FileAccessMemory::cleanup() { return; memdelete(files); -}; +} FileAccess* FileAccessMemory::create() { return memnew(FileAccessMemory); -}; +} bool FileAccessMemory::file_exists(const String& p_name) { @@ -71,8 +71,16 @@ bool FileAccessMemory::file_exists(const String& p_name) { name = DirAccess::normalize_path(name); return files && (files->find(name) != NULL); -}; +} + +Error FileAccessMemory::open_custom(const uint8_t* p_data, int p_len) { + + data=(uint8_t*)p_data; + length=p_len; + pos=0; + return OK; +} Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) { @@ -89,57 +97,57 @@ Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) { pos = 0; return OK; -}; +} void FileAccessMemory::close() { data = NULL; -}; +} bool FileAccessMemory::is_open() const { return data != NULL; -}; +} void FileAccessMemory::seek(size_t p_position) { ERR_FAIL_COND(!data); pos = p_position; -}; +} void FileAccessMemory::seek_end(int64_t p_position) { ERR_FAIL_COND(!data); pos = length + p_position; -}; +} size_t FileAccessMemory::get_pos() const { ERR_FAIL_COND_V(!data, 0); return pos; -}; +} size_t FileAccessMemory::get_len() const { ERR_FAIL_COND_V(!data, 0); return length; -}; +} bool FileAccessMemory::eof_reached() const { return pos >= length; -}; +} uint8_t FileAccessMemory::get_8() const { - uint8_t ret; + uint8_t ret = 0; if (pos < length) { ret = data[pos]; - }; + } ++pos; return ret; -}; +} int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const { @@ -156,19 +164,19 @@ int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const { pos += p_length; return read; -}; +} Error FileAccessMemory::get_error() const { return pos >= length ? ERR_FILE_EOF : OK; -}; +} void FileAccessMemory::store_8(uint8_t p_byte) { ERR_FAIL_COND(!data); ERR_FAIL_COND(pos >= length); data[pos++] = p_byte; -}; +} void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) { @@ -176,11 +184,11 @@ void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) { int write = MIN(p_length, left); if (write < p_length) { WARN_PRINT("Writing less data than requested"); - }; + } copymem(&data[pos], p_src, write); pos += p_length; -}; +} FileAccessMemory::FileAccessMemory() { diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index a02a022a4f..8c58a8a8ce 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,6 +44,7 @@ public: static void register_file(String p_name, Vector<uint8_t> p_data); static void cleanup(); + virtual Error open_custom(const uint8_t* p_data, int p_len); ///< open a file virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 26194040b0..850e055129 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -254,6 +254,7 @@ FileAccessNetworkClient::~FileAccessNetworkClient() { quit=true; sem->post(); Thread::wait_to_finish(thread); + memdelete(thread); } memdelete(blockrequest_mutex); diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index f338bea43f..2190cdb0ea 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index e2cb300ebc..339a6d0528 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -48,7 +48,10 @@ Error PackedData::add_pack(const String& p_path) { void PackedData::add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size,const uint8_t* p_md5, PackSource* p_src) { - bool exists = files.has(path); + PathMD5 pmd5(path.md5_buffer()); + //printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b); + + bool exists = files.has(pmd5); PackedFile pf; pf.pack=pkg_path; @@ -58,7 +61,7 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o pf.md5[i]=p_md5[i]; pf.src = p_src; - files[path]=pf; + files[pmd5]=pf; if (!exists) { //search for dir @@ -89,7 +92,9 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o void PackedData::add_pack_source(PackSource *p_source) { - sources.push_back(p_source); + if (p_source != NULL) { + sources.push_back(p_source); + } }; PackedData *PackedData::singleton=NULL; @@ -104,6 +109,21 @@ PackedData::PackedData() { add_pack_source(memnew(PackedSourcePCK)); } +void PackedData::_free_packed_dirs(PackedDir *p_dir) { + + for (Map<String,PackedDir*>::Element *E=p_dir->subdirs.front();E;E=E->next()) + _free_packed_dirs(E->get()); + memdelete(p_dir); +} + +PackedData::~PackedData() { + + for(int i=0;i<sources.size();i++) { + memdelete(sources[i]); + } + _free_packed_dirs(root); +} + ////////////////////////////////////////////////////////////////// @@ -113,6 +133,8 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) { if (!f) return false; + //printf("try open %ls!\n", p_path.c_str()); + uint32_t magic= f->get_32(); if (magic != 0x43504447) { @@ -357,6 +379,10 @@ bool DirAccessPack::current_is_dir() const{ return cdir; } +bool DirAccessPack::current_is_hidden() const{ + + return false; +} void DirAccessPack::list_dir_end() { list_dirs.clear(); diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index a4c750bf3c..5bf5ad012c 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -60,8 +60,34 @@ private: Set<String> files; }; + struct PathMD5 { + uint64_t a; + uint64_t b; + bool operator < (const PathMD5& p_md5) const { + + if (p_md5.a == a) { + return b < p_md5.b; + } else { + return a < p_md5.a; + } + } + + bool operator == (const PathMD5& p_md5) const { + return a == p_md5.a && b == p_md5.b; + }; + + PathMD5() { + a = b = 0; + }; + + PathMD5(const Vector<uint8_t> p_buf) { + a = *((uint64_t*)&p_buf[0]); + b = *((uint64_t*)&p_buf[8]); + }; + }; + + Map<PathMD5,PackedFile> files; - Map<String,PackedFile> files; Vector<PackSource*> sources; PackedDir *root; @@ -70,6 +96,8 @@ private: static PackedData *singleton; bool disabled; + void _free_packed_dirs(PackedDir *p_dir); + public: void add_pack_source(PackSource* p_source); @@ -85,6 +113,7 @@ public: _FORCE_INLINE_ bool has_path(const String& p_path); PackedData(); + ~PackedData(); }; class PackSource { @@ -93,6 +122,7 @@ public: virtual bool try_open_pack(const String& p_path)=0; virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file)=0; + virtual ~PackSource() {} }; class PackedSourcePCK : public PackSource { @@ -151,7 +181,9 @@ public: FileAccess *PackedData::try_open_path(const String& p_path) { - Map<String,PackedFile>::Element *E=files.find(p_path); + //print_line("try open path " + p_path); + PathMD5 pmd5(p_path.md5_buffer()); + Map<PathMD5,PackedFile>::Element *E=files.find(pmd5); if (!E) return NULL; //not found if (E->get().offset==0) @@ -162,7 +194,7 @@ FileAccess *PackedData::try_open_path(const String& p_path) { bool PackedData::has_path(const String& p_path) { - return files.has(p_path); + return files.has(PathMD5(p_path.md5_buffer())); } @@ -180,6 +212,7 @@ public: virtual bool list_dir_begin(); virtual String get_next(); virtual bool current_is_dir() const; + virtual bool current_is_hidden() const; virtual void list_dir_end(); virtual int get_drive_count(); diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 55c0dedad9..ab2eb3b3f2 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -31,6 +31,7 @@ #include "file_access_zip.h" #include "core/os/file_access.h" +#include "core/os/copymem.h" ZipArchive* ZipArchive::instance = NULL; @@ -103,9 +104,17 @@ static int godot_testerror(voidpf opaque, voidpf stream) { return f->get_error()!=OK?1:0; }; +static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) { + return memalloc(items * size); }; +static void godot_free(voidpf opaque, voidpf address) { + + memfree(address); +}; + +}; // extern "C" void ZipArchive::close_handle(unzFile p_file) const { @@ -125,6 +134,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const { ERR_FAIL_COND_V(!f, NULL); zlib_filefunc_def io; + zeromem(&io, sizeof(io)); io.opaque = f; io.zopen_file = godot_open; @@ -136,9 +146,13 @@ unzFile ZipArchive::get_file_handle(String p_file) const { io.zclose_file = godot_close; io.zerror_file = godot_testerror; + io.alloc_mem = godot_alloc; + io.free_mem = godot_free; + unzFile pkg = unzOpen2(packages[file.package].filename.utf8().get_data(), &io); ERR_FAIL_COND_V(!pkg, NULL); - unzGoToFilePos(pkg, &file.file_pos); + int unz_err = unzGoToFilePos(pkg, &file.file_pos); + ERR_FAIL_COND_V(unz_err != UNZ_OK, NULL); if (unzOpenCurrentFile(pkg) != UNZ_OK) { unzClose(pkg); @@ -150,7 +164,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const { bool ZipArchive::try_open_pack(const String& p_name) { - printf("opening pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz")); + //printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz")); if (p_name.extension().nocasecmp_to("zip") != 0 && p_name.extension().nocasecmp_to("pcz") != 0) return false; @@ -198,7 +212,8 @@ bool ZipArchive::try_open_pack(const String& p_name) { files[fname] = f; uint8_t md5[16]={0,0,0,0,0,0,0,0 , 0,0,0,0,0,0,0,0}; - PackedData::get_singleton()->add_path(p_name, fname, 0, 0, md5, this); + PackedData::get_singleton()->add_path(p_name, fname, 1, 0, md5, this); + //printf("packed data add path %ls, %ls\n", p_name.c_str(), fname.c_str()); if ((i+1)<gi.number_entry) { unzGoToNextFile(zfile); diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 27e202f47f..58092efd4b 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,6 +29,8 @@ #include "http_client.h" #include "io/stream_peer_ssl.h" +VARIANT_ENUM_CAST(HTTPClient::Status); + Error HTTPClient::connect_url(const String& p_url) { return OK; @@ -271,7 +273,7 @@ Error HTTPClient::poll(){ while(true) { uint8_t byte; int rec=0; - Error err = connection->get_partial_data(&byte,1,rec); + Error err = _get_http_data(&byte,1,rec); if (err!=OK) { close(); status=STATUS_CONNECTION_ERROR; @@ -323,7 +325,7 @@ Error HTTPClient::poll(){ if (i==0 && responses[i].begins_with("HTTP")) { - String num = responses[i].get_slice(" ",1); + String num = responses[i].get_slicec(' ',1); response_num=num.to_int(); } else { @@ -415,7 +417,7 @@ ByteArray HTTPClient::read_response_body_chunk() { //reading len uint8_t b; int rec=0; - err = connection->get_partial_data(&b,1,rec); + err = _get_http_data(&b,1,rec); if (rec==0) break; @@ -469,7 +471,7 @@ ByteArray HTTPClient::read_response_body_chunk() { } else { int rec=0; - err = connection->get_partial_data(&chunk[chunk.size()-chunk_left],chunk_left,rec); + err = _get_http_data(&chunk[chunk.size()-chunk_left],chunk_left,rec); if (rec==0) { break; } @@ -500,20 +502,29 @@ ByteArray HTTPClient::read_response_body_chunk() { } } else { - ByteArray::Write r = tmp_read.write(); - int rec=0; - err = connection->get_partial_data(r.ptr(),MIN(body_left,tmp_read.size()),rec); - if (rec>0) { - ByteArray ret; - ret.resize(rec); - ByteArray::Write w = ret.write(); - copymem(w.ptr(),r.ptr(),rec); - body_left-=rec; - if (body_left==0) { - status=STATUS_CONNECTED; + + int to_read = MIN(body_left,read_chunk_size); + ByteArray ret; + ret.resize(to_read); + ByteArray::Write w = ret.write(); + int _offset = 0; + while (to_read > 0) { + int rec=0; + err = _get_http_data(w.ptr()+_offset,to_read,rec); + if (rec>0) { + body_left-=rec; + to_read-=rec; + _offset += rec; + } else { + if (to_read>0) //ended up reading less + ret.resize(_offset); + break; } - return ret; } + if (body_left==0) { + status=STATUS_CONNECTED; + } + return ret; } @@ -551,10 +562,24 @@ bool HTTPClient::is_blocking_mode_enabled() const{ return blocking; } +Error HTTPClient::_get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received) { + + if (blocking) { + + Error err = connection->get_data(p_buffer,p_bytes); + if (err==OK) + r_received=p_bytes; + else + r_received=0; + return err; + } else { + return connection->get_partial_data(p_buffer,p_bytes,r_received); + } +} void HTTPClient::_bind_methods() { - ObjectTypeDB::bind_method(_MD("connect:Error","host","port","use_ssl"),&HTTPClient::connect,DEFVAL(false),DEFVAL(true)); + ObjectTypeDB::bind_method(_MD("connect:Error","host","port","use_ssl","verify_host"),&HTTPClient::connect,DEFVAL(false),DEFVAL(true)); ObjectTypeDB::bind_method(_MD("set_connection","connection:StreamPeer"),&HTTPClient::set_connection); ObjectTypeDB::bind_method(_MD("request","method","url","headers","body"),&HTTPClient::request,DEFVAL(String())); ObjectTypeDB::bind_method(_MD("send_body_text","body"),&HTTPClient::send_body_text); @@ -568,6 +593,7 @@ void HTTPClient::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_response_headers_as_dictionary"),&HTTPClient::_get_response_headers_as_dictionary); ObjectTypeDB::bind_method(_MD("get_response_body_length"),&HTTPClient::get_response_body_length); ObjectTypeDB::bind_method(_MD("read_response_body_chunk"),&HTTPClient::read_response_body_chunk); + ObjectTypeDB::bind_method(_MD("set_read_chunk_size","bytes"),&HTTPClient::set_read_chunk_size); ObjectTypeDB::bind_method(_MD("set_blocking_mode","enabled"),&HTTPClient::set_blocking_mode); ObjectTypeDB::bind_method(_MD("is_blocking_mode_enabled"),&HTTPClient::is_blocking_mode_enabled); @@ -575,6 +601,8 @@ void HTTPClient::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_status"),&HTTPClient::get_status); ObjectTypeDB::bind_method(_MD("poll:Error"),&HTTPClient::poll); + ObjectTypeDB::bind_method(_MD("query_string_from_dict:String","fields"),&HTTPClient::query_string_from_dict); + BIND_CONSTANT( METHOD_GET ); BIND_CONSTANT( METHOD_HEAD ); @@ -658,6 +686,21 @@ void HTTPClient::_bind_methods() { } +void HTTPClient::set_read_chunk_size(int p_size) { + ERR_FAIL_COND(p_size<256 || p_size>(1<<24)); + read_chunk_size=p_size; +} + +String HTTPClient::query_string_from_dict(const Dictionary& p_dict) { + String query = ""; + Array keys = p_dict.keys(); + for (int i = 0; i < keys.size(); ++i) { + query += "&" + String(keys[i]).http_escape() + "=" + String(p_dict[keys[i]]).http_escape(); + } + query.erase(0, 1); + return query; +} + HTTPClient::HTTPClient(){ tcp_connection = StreamPeerTCP::create_ref(); @@ -671,7 +714,7 @@ HTTPClient::HTTPClient(){ response_num=0; ssl=false; blocking=false; - tmp_read.resize(4096); + read_chunk_size=4096; } HTTPClient::~HTTPClient(){ @@ -679,4 +722,3 @@ HTTPClient::~HTTPClient(){ } - diff --git a/core/io/http_client.h b/core/io/http_client.h index 09ad64f48a..b103dc43fc 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -157,7 +157,10 @@ private: static void _bind_methods(); StringArray _get_response_headers(); Dictionary _get_response_headers_as_dictionary(); - ByteArray tmp_read; + int read_chunk_size; + + Error _get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received); + public: @@ -185,9 +188,12 @@ public: void set_blocking_mode(bool p_enable); //useful mostly if running in a thread bool is_blocking_mode_enabled() const; + void set_read_chunk_size(int p_size); Error poll(); + String query_string_from_dict(const Dictionary& p_dict); + HTTPClient(); ~HTTPClient(); }; diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 180df8964b..2db6e00f0a 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -50,8 +50,10 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom if (!f) { Error err; f=FileAccess::open(p_file,FileAccess::READ,&err); - if (!f) + if (!f) { + print_line("ERROR OPENING FILE: "+p_file); return err; + } } String extension = p_file.extension(); @@ -62,15 +64,20 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom if (!loader[i]->recognize(extension)) continue; Error err = loader[i]->load_image(p_image,f); + if (err!=ERR_FILE_UNRECOGNIZED) { + + if (!p_custom) memdelete(f); + return err; } } - + print_line("NO LOADER?"); + if (!p_custom) memdelete(f); diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 665cc0b460..ff972696ea 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/ioapi.h b/core/io/ioapi.h index a13d7ba621..24bf612617 100644 --- a/core/io/ioapi.h +++ b/core/io/ioapi.h @@ -40,7 +40,6 @@ #endif #include <stdio.h> -#include <stdlib.h> #include "zlib.h" #if defined(USE_FILE32API) diff --git a/core/io/ip.cpp b/core/io/ip.cpp index d2a685f6b0..523f9f472b 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,7 +31,7 @@ #include "os/semaphore.h" #include "hash_map.h" - +VARIANT_ENUM_CAST(IP::ResolverStatus); /************* RESOLVER ******************/ @@ -183,7 +183,7 @@ void IP::erase_resolve_item(ResolverID p_id) { GLOBAL_LOCK_FUNCTION; - resolver->queue[p_id].status=IP::RESOLVER_STATUS_DONE; + resolver->queue[p_id].status=IP::RESOLVER_STATUS_NONE; } diff --git a/core/io/ip.h b/core/io/ip.h index 0181dc7d12..6f50a190e6 100644 --- a/core/io/ip.h +++ b/core/io/ip.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index a1400adbb6..ed5a45c9ef 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -47,7 +47,7 @@ IP_Address::IP_Address(const String& p_string) { } for(int i=0;i<4;i++) { - field[i]=p_string.get_slice(".",i).to_int(); + field[i]=p_string.get_slicec('.',i).to_int(); } } diff --git a/core/io/ip_address.h b/core/io/ip_address.h index cd39aa6c81..e55f45a2d7 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,6 +39,12 @@ struct IP_Address { }; //operator Variant() const; + bool operator==(const IP_Address& p_ip) const { + return host==p_ip.host; + } + bool operator!=(const IP_Address& p_ip) const { + return host!=p_ip.host; + } operator String() const; IP_Address(const String& p_string); IP_Address(uint8_t p_a,uint8_t p_b,uint8_t p_c,uint8_t p_d); diff --git a/core/io/json.cpp b/core/io/json.cpp index a83d7e4d6e..22c99d0465 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -177,9 +177,6 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke case 'n': res=10; break; case 'f': res=12; break; case 'r': res=13; break; - case '\"': res='\"'; break; - case '\\': res='\\'; break; - case '/': res='/'; break; //wtf case 'u': { //hexnumbarh - oct is deprecated @@ -218,10 +215,13 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke } break; + //case '\"': res='\"'; break; + //case '\\': res='\\'; break; + //case '/': res='/'; break; default: { - - r_err_str="Invalid escape sequence"; - return ERR_PARSE_ERROR; + res = next; + //r_err_str="Invalid escape sequence"; + //return ERR_PARSE_ERROR; } break; } @@ -250,7 +250,7 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke if (p_str[idx]=='-' || (p_str[idx]>='0' && p_str[idx]<='9')) { //a number const CharType *rptr; - double number = String::to_double(&p_str[idx],-1,&rptr); + double number = String::to_double(&p_str[idx],&rptr); idx+=(rptr - &p_str[idx]); r_token.type=TK_NUMBER; r_token.value=number; diff --git a/core/io/json.h b/core/io/json.h index d113d0e4ef..78b6303451 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index c6c15af5e0..62ccd81489 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,7 +36,10 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int * const uint8_t * buf=p_buffer; int len=p_len; - ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + if (len<4) { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + } uint32_t type=decode_uint32(buf); @@ -299,10 +302,8 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int * ERR_FAIL_COND_V(len<12,ERR_INVALID_DATA); Vector<StringName> names; Vector<StringName> subnames; - bool absolute; StringName prop; - int i=0; uint32_t namecount=strlen&=0x7FFFFFFF; uint32_t subnamecount = decode_uint32(buf+4); uint32_t flags = decode_uint32(buf+8); @@ -391,7 +392,6 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int * ie.type=decode_uint32(&buf[0]); ie.device=decode_uint32(&buf[4]); - uint32_t len = decode_uint32(&buf[8])-12; if (r_len) (*r_len)+=12; diff --git a/core/io/marshalls.h b/core/io/marshalls.h index bb8d3b336a..df673debf5 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/object_format_binary.cpp b/core/io/object_format_binary.cpp deleted file mode 100644 index c031f6e82b..0000000000 --- a/core/io/object_format_binary.cpp +++ /dev/null @@ -1,1491 +0,0 @@ -/*************************************************************************/ -/* object_format_binary.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "object_format_binary.h" -#include "resource.h" -#include "io/resource_loader.h" -#include "print_string.h" -#include "object_type_db.h" -#include "globals.h" -#include "os/os.h" -#include "version.h" - - -#define print_bl(m_what) -#ifdef OLD_SCENE_FORMAT_ENABLED - - -enum { - - SECTION_RESOURCE=0, - SECTION_OBJECT=1, - SECTION_META_OBJECT=2, - SECTION_PROPERTY=3, - SECTION_END=4, - - //numbering must be different from variant, in case new variant types are added (variant must be always contiguous for jumptable optimization) - VARIANT_NIL=1, - VARIANT_BOOL=2, - VARIANT_INT=3, - VARIANT_REAL=4, - VARIANT_STRING=5, - VARIANT_VECTOR2=10, - VARIANT_RECT2=11, - VARIANT_VECTOR3=12, - VARIANT_PLANE=13, - VARIANT_QUAT=14, - VARIANT_AABB=15, - VARIANT_MATRIX3=16, - VARIANT_TRANSFORM=17, - VARIANT_MATRIX32=18, - VARIANT_COLOR=20, - VARIANT_IMAGE=21, - VARIANT_NODE_PATH=22, - VARIANT_RID=23, - VARIANT_OBJECT=24, - VARIANT_INPUT_EVENT=25, - VARIANT_DICTIONARY=26, - VARIANT_ARRAY=30, - VARIANT_RAW_ARRAY=31, - VARIANT_INT_ARRAY=32, - VARIANT_REAL_ARRAY=33, - VARIANT_STRING_ARRAY=34, - VARIANT_VECTOR3_ARRAY=35, - VARIANT_COLOR_ARRAY=36, - VARIANT_VECTOR2_ARRAY=37, - - IMAGE_ENCODING_EMPTY=0, - IMAGE_ENCODING_RAW=1, - IMAGE_ENCODING_PNG=2, //not yet - IMAGE_ENCODING_JPG=3, - - IMAGE_FORMAT_GRAYSCALE=0, - IMAGE_FORMAT_INTENSITY=1, - IMAGE_FORMAT_GRAYSCALE_ALPHA=2, - IMAGE_FORMAT_RGB=3, - IMAGE_FORMAT_RGBA=4, - IMAGE_FORMAT_INDEXED=5, - IMAGE_FORMAT_INDEXED_ALPHA=6, - IMAGE_FORMAT_BC1=7, - IMAGE_FORMAT_BC2=8, - IMAGE_FORMAT_BC3=9, - IMAGE_FORMAT_BC4=10, - IMAGE_FORMAT_BC5=11, - IMAGE_FORMAT_CUSTOM=12, - - OBJECT_EMPTY=0, - OBJECT_EXTERNAL_RESOURCE=1, - OBJECT_INTERNAL_RESOURCE=2, - - -}; - - -void ObjectFormatSaverBinary::_pad_buffer(int p_bytes) { - - int extra = 4-(p_bytes%4); - if (extra<4) { - for(int i=0;i<extra;i++) - f->store_8(0); //pad to 32 - } - -} - - -void ObjectFormatSaverBinary::write_property(int p_idx,const Variant& p_property) { - - f->store_32(SECTION_PROPERTY); - f->store_32(p_idx); - - switch(p_property.get_type()) { - - case Variant::NIL: { - - f->store_32(VARIANT_NIL); - // don't store anything - } break; - case Variant::BOOL: { - - f->store_32(VARIANT_BOOL); - bool val=p_property; - f->store_32(val); - } break; - case Variant::INT: { - - f->store_32(VARIANT_INT); - int val=p_property; - f->store_32(val); - } break; - case Variant::REAL: { - - f->store_32(VARIANT_REAL); - real_t val=p_property; - f->store_real(val); - - } break; - case Variant::STRING: { - - f->store_32(VARIANT_STRING); - String val=p_property; - save_unicode_string(val); - - } break; - case Variant::VECTOR2: { - - f->store_32(VARIANT_VECTOR2); - Vector2 val=p_property; - f->store_real(val.x); - f->store_real(val.y); - - } break; - case Variant::RECT2: { - - f->store_32(VARIANT_RECT2); - Rect2 val=p_property; - f->store_real(val.pos.x); - f->store_real(val.pos.y); - f->store_real(val.size.x); - f->store_real(val.size.y); - - } break; - case Variant::VECTOR3: { - - f->store_32(VARIANT_VECTOR3); - Vector3 val=p_property; - f->store_real(val.x); - f->store_real(val.y); - f->store_real(val.z); - - } break; - case Variant::PLANE: { - - f->store_32(VARIANT_PLANE); - Plane val=p_property; - f->store_real(val.normal.x); - f->store_real(val.normal.y); - f->store_real(val.normal.z); - f->store_real(val.d); - - } break; - case Variant::QUAT: { - - f->store_32(VARIANT_QUAT); - Quat val=p_property; - f->store_real(val.x); - f->store_real(val.y); - f->store_real(val.z); - f->store_real(val.w); - - } break; - case Variant::_AABB: { - - f->store_32(VARIANT_AABB); - AABB val=p_property; - f->store_real(val.pos.x); - f->store_real(val.pos.y); - f->store_real(val.pos.z); - f->store_real(val.size.x); - f->store_real(val.size.y); - f->store_real(val.size.z); - - } break; - case Variant::MATRIX32: { - - f->store_32(VARIANT_MATRIX32); - Matrix32 val=p_property; - f->store_real(val.elements[0].x); - f->store_real(val.elements[0].y); - f->store_real(val.elements[1].x); - f->store_real(val.elements[1].y); - f->store_real(val.elements[2].x); - f->store_real(val.elements[2].y); - - } break; - case Variant::MATRIX3: { - - f->store_32(VARIANT_MATRIX3); - Matrix3 val=p_property; - f->store_real(val.elements[0].x); - f->store_real(val.elements[0].y); - f->store_real(val.elements[0].z); - f->store_real(val.elements[1].x); - f->store_real(val.elements[1].y); - f->store_real(val.elements[1].z); - f->store_real(val.elements[2].x); - f->store_real(val.elements[2].y); - f->store_real(val.elements[2].z); - - } break; - case Variant::TRANSFORM: { - - f->store_32(VARIANT_TRANSFORM); - Transform val=p_property; - f->store_real(val.basis.elements[0].x); - f->store_real(val.basis.elements[0].y); - f->store_real(val.basis.elements[0].z); - f->store_real(val.basis.elements[1].x); - f->store_real(val.basis.elements[1].y); - f->store_real(val.basis.elements[1].z); - f->store_real(val.basis.elements[2].x); - f->store_real(val.basis.elements[2].y); - f->store_real(val.basis.elements[2].z); - f->store_real(val.origin.x); - f->store_real(val.origin.y); - f->store_real(val.origin.z); - - } break; - case Variant::COLOR: { - - f->store_32(VARIANT_COLOR); - Color val=p_property; - f->store_real(val.r); - f->store_real(val.g); - f->store_real(val.b); - f->store_real(val.a); - - } break; - case Variant::IMAGE: { - - f->store_32(VARIANT_IMAGE); - Image val =p_property; - if (val.empty()) { - f->store_32(IMAGE_ENCODING_EMPTY); - break; - } - f->store_32(IMAGE_ENCODING_RAW); //raw encoding - f->store_32(val.get_width()); - f->store_32(val.get_height()); - f->store_32(val.get_mipmaps()); - switch(val.get_format()) { - - case Image::FORMAT_GRAYSCALE: f->store_32(IMAGE_FORMAT_GRAYSCALE ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255 - case Image::FORMAT_INTENSITY: f->store_32(IMAGE_FORMAT_INTENSITY ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255 - case Image::FORMAT_GRAYSCALE_ALPHA: f->store_32(IMAGE_FORMAT_GRAYSCALE_ALPHA ); break; ///< two bytes per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255. alpha 0-255 - case Image::FORMAT_RGB: f->store_32(IMAGE_FORMAT_RGB ); break; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B - case Image::FORMAT_RGBA: f->store_32(IMAGE_FORMAT_RGBA ); break; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B: f->store_32(IMAGE_FORMAT_ ); break; one byte A - case Image::FORMAT_INDEXED: f->store_32(IMAGE_FORMAT_INDEXED ); break; ///< index byte 0-256: f->store_32(IMAGE_FORMAT_ ); break; and after image end: f->store_32(IMAGE_FORMAT_ ); break; 256*3 bytes of palette - case Image::FORMAT_INDEXED_ALPHA: f->store_32(IMAGE_FORMAT_INDEXED_ALPHA ); break; ///< index byte 0-256: f->store_32(IMAGE_FORMAT_ ); break; and after image end: f->store_32(IMAGE_FORMAT_ ); break; 256*4 bytes of palette (alpha) - case Image::FORMAT_BC1: f->store_32(IMAGE_FORMAT_BC1 ); break; // DXT1 - case Image::FORMAT_BC2: f->store_32(IMAGE_FORMAT_BC2 ); break; // DXT3 - case Image::FORMAT_BC3: f->store_32(IMAGE_FORMAT_BC3 ); break; // DXT5 - case Image::FORMAT_BC4: f->store_32(IMAGE_FORMAT_BC4 ); break; // ATI1 - case Image::FORMAT_BC5: f->store_32(IMAGE_FORMAT_BC5 ); break; // ATI2 - case Image::FORMAT_CUSTOM: f->store_32(IMAGE_FORMAT_CUSTOM ); break; - default: {} - - } - - int dlen = val.get_data().size(); - f->store_32(dlen); - DVector<uint8_t>::Read r = val.get_data().read(); - f->store_buffer(r.ptr(),dlen); - _pad_buffer(dlen); - - } break; - case Variant::NODE_PATH: { - f->store_32(VARIANT_NODE_PATH); - save_unicode_string(p_property); - } break; - case Variant::_RID: { - - f->store_32(VARIANT_RID); - WARN_PRINT("Can't save RIDs"); - RID val = p_property; - f->store_32(val.get_id()); - } break; - case Variant::OBJECT: { - - f->store_32(VARIANT_OBJECT); - RES res = p_property; - if (res.is_null()) { - f->store_32(OBJECT_EMPTY); - return; // don't save it - } - - if (res->get_path().length() && res->get_path().find("::")==-1) { - f->store_32(OBJECT_EXTERNAL_RESOURCE); - save_unicode_string(res->get_type()); - String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path(); - save_unicode_string(path); - } else { - - if (!resource_map.has(res)) { - f->store_32(OBJECT_EMPTY); - ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); - ERR_FAIL(); - } - - f->store_32(OBJECT_INTERNAL_RESOURCE); - f->store_32(resource_map[res]); - //internal resource - } - - - } break; - case Variant::INPUT_EVENT: { - - f->store_32(VARIANT_INPUT_EVENT); - WARN_PRINT("Can't save InputEvent (maybe it could..)"); - } break; - case Variant::DICTIONARY: { - - f->store_32(VARIANT_DICTIONARY); - Dictionary d = p_property; - f->store_32(d.size()); - - List<Variant> keys; - d.get_key_list(&keys); - - for(List<Variant>::Element *E=keys.front();E;E=E->next()) { - - //if (!_check_type(dict[E->get()])) - // continue; - - write_property(0,E->get()); - write_property(0,d[E->get()]); - } - - - } break; - case Variant::ARRAY: { - - f->store_32(VARIANT_ARRAY); - Array a=p_property; - f->store_32(a.size()); - for(int i=0;i<a.size();i++) { - - write_property(i,a[i]); - } - - } break; - case Variant::RAW_ARRAY: { - - f->store_32(VARIANT_RAW_ARRAY); - DVector<uint8_t> arr = p_property; - int len=arr.size(); - f->store_32(len); - DVector<uint8_t>::Read r = arr.read(); - f->store_buffer(r.ptr(),len); - _pad_buffer(len); - - } break; - case Variant::INT_ARRAY: { - - f->store_32(VARIANT_INT_ARRAY); - DVector<int> arr = p_property; - int len=arr.size(); - f->store_32(len); - DVector<int>::Read r = arr.read(); - for(int i=0;i<len;i++) - f->store_32(r[i]); - - } break; - case Variant::REAL_ARRAY: { - - f->store_32(VARIANT_REAL_ARRAY); - DVector<real_t> arr = p_property; - int len=arr.size(); - f->store_32(len); - DVector<real_t>::Read r = arr.read(); - for(int i=0;i<len;i++) { - f->store_real(r[i]); - } - - } break; - case Variant::STRING_ARRAY: { - - f->store_32(VARIANT_STRING_ARRAY); - DVector<String> arr = p_property; - int len=arr.size(); - f->store_32(len); - DVector<String>::Read r = arr.read(); - for(int i=0;i<len;i++) { - save_unicode_string(r[i]); - } - - } break; - case Variant::VECTOR3_ARRAY: { - - f->store_32(VARIANT_VECTOR3_ARRAY); - DVector<Vector3> arr = p_property; - int len=arr.size(); - f->store_32(len); - DVector<Vector3>::Read r = arr.read(); - for(int i=0;i<len;i++) { - f->store_real(r[i].x); - f->store_real(r[i].y); - f->store_real(r[i].z); - } - - } break; - case Variant::VECTOR2_ARRAY: { - - f->store_32(VARIANT_VECTOR2_ARRAY); - DVector<Vector2> arr = p_property; - int len=arr.size(); - f->store_32(len); - DVector<Vector2>::Read r = arr.read(); - for(int i=0;i<len;i++) { - f->store_real(r[i].x); - f->store_real(r[i].y); - } - - } break; - case Variant::COLOR_ARRAY: { - - f->store_32(VARIANT_COLOR_ARRAY); - DVector<Color> arr = p_property; - int len=arr.size(); - f->store_32(len); - DVector<Color>::Read r = arr.read(); - for(int i=0;i<len;i++) { - f->store_real(r[i].r); - f->store_real(r[i].g); - f->store_real(r[i].b); - f->store_real(r[i].a); - } - - } break; - default: { - - ERR_EXPLAIN("Invalid variant"); - ERR_FAIL(); - } - } -} - - -void ObjectFormatSaverBinary::_find_resources(const Variant& p_variant) { - - - switch(p_variant.get_type()) { - case Variant::OBJECT: { - - - RES res = p_variant.operator RefPtr(); - - if (res.is_null()) - return; - - if (!bundle_resources && res->get_path().length() && res->get_path().find("::") == -1 ) - return; - - if (resource_map.has(res)) - return; - - List<PropertyInfo> property_list; - - res->get_property_list(&property_list); - - for(List<PropertyInfo>::Element *E=property_list.front();E;E=E->next()) { - - if (E->get().usage&PROPERTY_USAGE_STORAGE || (bundle_resources && E->get().usage&PROPERTY_USAGE_BUNDLE)) { - - _find_resources(res->get(E->get().name)); - } - } - - SavedObject *so = memnew( SavedObject ); - _save_obj(res.ptr(),so); - so->meta=res.get_ref_ptr(); - - resource_map[ res ] = saved_resources.size(); - saved_resources.push_back(so); - - } break; - - case Variant::ARRAY: { - - Array varray=p_variant; - int len=varray.size(); - for(int i=0;i<len;i++) { - - Variant v=varray.get(i); - _find_resources(v); - } - - } break; - - case Variant::DICTIONARY: { - - Dictionary d=p_variant; - List<Variant> keys; - d.get_key_list(&keys); - for(List<Variant>::Element *E=keys.front();E;E=E->next()) { - - Variant v = d[E->get()]; - _find_resources(v); - } - } break; - default: {} - } - -} -Error ObjectFormatSaverBinary::_save_obj(const Object *p_object,SavedObject *so) { - - if (optimizer.is_valid()) { - //use optimizer - - List<OptimizedSaver::Property> props; - optimizer->get_property_list(p_object,&props); - - for(List<OptimizedSaver::Property>::Element *E=props.front();E;E=E->next()) { - - if (skip_editor && String(E->get().name).begins_with("__editor")) - continue; - _find_resources(E->get().value); - SavedObject::SavedProperty sp; - - sp.name_idx=get_string_index(E->get().name); - sp.value=E->get().value; - so->properties.push_back(sp); - } - - } else { - //use classic way - List<PropertyInfo> property_list; - p_object->get_property_list( &property_list ); - - for(List<PropertyInfo>::Element *E=property_list.front();E;E=E->next()) { - - if (skip_editor && E->get().name.begins_with("__editor")) - continue; - if (E->get().usage&PROPERTY_USAGE_STORAGE || (bundle_resources && E->get().usage&PROPERTY_USAGE_BUNDLE)) { - - SavedObject::SavedProperty sp; - sp.name_idx=get_string_index(E->get().name); - sp.value = p_object->get(E->get().name); - _find_resources(sp.value); - so->properties.push_back(sp); - } - } - } - - return OK; - -} - -Error ObjectFormatSaverBinary::save(const Object *p_object,const Variant &p_meta) { - - ERR_FAIL_COND_V(!f,ERR_UNCONFIGURED); - ERR_EXPLAIN("write_object should supply either an object, a meta, or both"); - ERR_FAIL_COND_V(!p_object && p_meta.get_type()==Variant::NIL, ERR_INVALID_PARAMETER); - - SavedObject *so = memnew( SavedObject ); - - if (p_object) - so->type=p_object->get_type(); - - _find_resources(p_meta); - so->meta=p_meta; - Error err = _save_obj(p_object,so); - ERR_FAIL_COND_V( err, ERR_INVALID_DATA ); - - saved_objects.push_back(so); - - return OK; -} - -void ObjectFormatSaverBinary::save_unicode_string(const String& p_string) { - - - CharString utf8 = p_string.utf8(); - f->store_32(utf8.length()+1); - f->store_buffer((const uint8_t*)utf8.get_data(),utf8.length()+1); -} - -ObjectFormatSaverBinary::ObjectFormatSaverBinary(FileAccess *p_file,const String& p_magic,const String& p_local_path,uint32_t p_flags,const Ref<OptimizedSaver>& p_optimizer) { - - optimizer=p_optimizer; - relative_paths=p_flags&ObjectSaver::FLAG_RELATIVE_PATHS; - skip_editor=p_flags&ObjectSaver::FLAG_OMIT_EDITOR_PROPERTIES; - bundle_resources=p_flags&ObjectSaver::FLAG_BUNDLE_RESOURCES; - big_endian=p_flags&ObjectSaver::FLAG_SAVE_BIG_ENDIAN; - f=p_file; // should be already opened - local_path=p_local_path; - magic=p_magic; - - bin_meta_idx = get_string_index("__bin_meta__"); //is often used, so create -} - -int ObjectFormatSaverBinary::get_string_index(const String& p_string) { - - StringName s=p_string; - if (string_map.has(s)) - return string_map[s]; - - string_map[s]=strings.size(); - strings.push_back(s); - return strings.size()-1; -} - -ObjectFormatSaverBinary::~ObjectFormatSaverBinary() { - - - static const uint8_t header[4]={'O','B','D','B'}; - f->store_buffer(header,4); - if (big_endian) { - f->store_32(1); - f->set_endian_swap(true); - } else - f->store_32(0); - - f->store_32(0); //64 bits file, false for now - f->store_32(VERSION_MAJOR); - f->store_32(VERSION_MINOR); - save_unicode_string(magic); - for(int i=0;i<16;i++) - f->store_32(0); // reserved - - f->store_32(strings.size()); //string table size - for(int i=0;i<strings.size();i++) { - print_bl("saving string: "+strings[i]); - save_unicode_string(strings[i]); - } - - // save resources - - for(int i=0;i<saved_resources.size();i++) { - - SavedObject *so = saved_resources[i]; - RES res = so->meta; - ERR_CONTINUE(!resource_map.has(res)); - - f->store_32(SECTION_RESOURCE); - size_t skip_pos = f->get_pos(); - f->store_64(0); // resource skip seek pos - save_unicode_string(res->get_type()); - - if (res->get_path().length() && res->get_path().find("::") == -1 ) - save_unicode_string(res->get_path()); - else - save_unicode_string("local://"+itos(i)); - - - - List<SavedObject::SavedProperty>::Element *SE = so->properties.front(); - - while(SE) { - - write_property(SE->get().name_idx,SE->get().value); - SE=SE->next(); - } - - f->store_32(SECTION_END); - - size_t end=f->get_pos(); - f->seek(skip_pos); - f->store_64(end); - f->seek_end(); - - memdelete( so ); - } - - if (!saved_objects.empty()) { - - - for(List<SavedObject*>::Element *E=saved_objects.front();E;E=E->next()) { - - SavedObject *so = E->get(); - - - size_t section_end; - - if (so->type!="") { - f->store_32(SECTION_OBJECT); - section_end=f->get_pos(); - f->store_64(0); //section end - save_unicode_string(so->type); - } else { - f->store_32(SECTION_META_OBJECT); - section_end=f->get_pos(); - f->store_64(0); //section end - } - - - if (so->meta.get_type()!=Variant::NIL) - write_property(bin_meta_idx,so->meta); - - List<SavedObject::SavedProperty>::Element *SE = so->properties.front(); - - while(SE) { - - write_property(SE->get().name_idx,SE->get().value); - SE=SE->next(); - } - - f->store_32(SECTION_END); - - size_t end=f->get_pos(); - f->seek(section_end); - f->store_64(end); - f->seek_end(); - - memdelete(so); //no longer needed - } - - - } - - f->store_32(SECTION_END); - - f->close(); - memdelete(f); -} - - -ObjectFormatSaver* ObjectFormatSaverInstancerBinary::instance(const String& p_file,const String& p_magic,uint32_t p_flags,const Ref<OptimizedSaver>& p_optimizer) { - - FileAccess *f = FileAccess::open(p_file, FileAccess::WRITE); - - ERR_FAIL_COND_V( !f, NULL ); - String local_path = Globals::get_singleton()->localize_path(p_file); - - return memnew( ObjectFormatSaverBinary( f, p_magic,local_path,p_flags,p_optimizer ) ); -} - -void ObjectFormatSaverInstancerBinary::get_recognized_extensions(List<String> *p_extensions) const { - - p_extensions->push_back("bin"); -} - - -ObjectFormatSaverInstancerBinary::~ObjectFormatSaverInstancerBinary() { - - -} - - - -/************************************************/ -/************************************************/ -/************************************************/ -/************************************************/ -/************************************************/ - - -void ObjectFormatLoaderBinary::_advance_padding(uint32_t p_len) { - - uint32_t extra = 4-(p_len%4); - if (extra<4) { - for(uint32_t i=0;i<extra;i++) - f->get_8(); //pad to 32 - } - -} - -Error ObjectFormatLoaderBinary::parse_property(Variant& r_v, int &r_index) { - - - uint32_t prop = f->get_32(); - if (prop==SECTION_END) - return ERR_FILE_EOF; - ERR_FAIL_COND_V(prop!=SECTION_PROPERTY,ERR_FILE_CORRUPT); - - r_index = f->get_32(); - - uint32_t type = f->get_32(); - print_bl("find property of type: "+itos(type)); - - - switch(type) { - - case VARIANT_NIL: { - - r_v=Variant(); - } break; - case VARIANT_BOOL: { - - r_v=bool(f->get_32()); - } break; - case VARIANT_INT: { - - r_v=int(f->get_32()); - } break; - case VARIANT_REAL: { - - r_v=f->get_real(); - } break; - case VARIANT_STRING: { - - r_v=get_unicode_string(); - } break; - case VARIANT_VECTOR2: { - - Vector2 v; - v.x=f->get_real(); - v.y=f->get_real(); - r_v=v; - - } break; - case VARIANT_RECT2: { - - Rect2 v; - v.pos.x=f->get_real(); - v.pos.y=f->get_real(); - v.size.x=f->get_real(); - v.size.y=f->get_real(); - r_v=v; - - } break; - case VARIANT_VECTOR3: { - - Vector3 v; - v.x=f->get_real(); - v.y=f->get_real(); - v.z=f->get_real(); - r_v=v; - } break; - case VARIANT_PLANE: { - - Plane v; - v.normal.x=f->get_real(); - v.normal.y=f->get_real(); - v.normal.z=f->get_real(); - v.d=f->get_real(); - r_v=v; - } break; - case VARIANT_QUAT: { - Quat v; - v.x=f->get_real(); - v.y=f->get_real(); - v.z=f->get_real(); - v.w=f->get_real(); - r_v=v; - - } break; - case VARIANT_AABB: { - - AABB v; - v.pos.x=f->get_real(); - v.pos.y=f->get_real(); - v.pos.z=f->get_real(); - v.size.x=f->get_real(); - v.size.y=f->get_real(); - v.size.z=f->get_real(); - r_v=v; - - } break; - case VARIANT_MATRIX32: { - - Matrix32 v; - v.elements[0].x=f->get_real(); - v.elements[0].y=f->get_real(); - v.elements[1].x=f->get_real(); - v.elements[1].y=f->get_real(); - v.elements[2].x=f->get_real(); - v.elements[2].y=f->get_real(); - r_v=v; - - } break; - case VARIANT_MATRIX3: { - - Matrix3 v; - v.elements[0].x=f->get_real(); - v.elements[0].y=f->get_real(); - v.elements[0].z=f->get_real(); - v.elements[1].x=f->get_real(); - v.elements[1].y=f->get_real(); - v.elements[1].z=f->get_real(); - v.elements[2].x=f->get_real(); - v.elements[2].y=f->get_real(); - v.elements[2].z=f->get_real(); - r_v=v; - - } break; - case VARIANT_TRANSFORM: { - - Transform v; - v.basis.elements[0].x=f->get_real(); - v.basis.elements[0].y=f->get_real(); - v.basis.elements[0].z=f->get_real(); - v.basis.elements[1].x=f->get_real(); - v.basis.elements[1].y=f->get_real(); - v.basis.elements[1].z=f->get_real(); - v.basis.elements[2].x=f->get_real(); - v.basis.elements[2].y=f->get_real(); - v.basis.elements[2].z=f->get_real(); - v.origin.x=f->get_real(); - v.origin.y=f->get_real(); - v.origin.z=f->get_real(); - r_v=v; - } break; - case VARIANT_COLOR: { - - Color v; - v.r=f->get_real(); - v.g=f->get_real(); - v.b=f->get_real(); - v.a=f->get_real(); - r_v=v; - - } break; - case VARIANT_IMAGE: { - - - uint32_t encoding = f->get_32(); - if (encoding==IMAGE_ENCODING_EMPTY) { - r_v=Variant(); - break; - } - - if (encoding==IMAGE_ENCODING_RAW) { - uint32_t width = f->get_32(); - uint32_t height = f->get_32(); - uint32_t mipmaps = f->get_32(); - uint32_t format = f->get_32(); - Image::Format fmt; - switch(format) { - - case IMAGE_FORMAT_GRAYSCALE: { fmt=Image::FORMAT_GRAYSCALE; } break; - case IMAGE_FORMAT_INTENSITY: { fmt=Image::FORMAT_INTENSITY; } break; - case IMAGE_FORMAT_GRAYSCALE_ALPHA: { fmt=Image::FORMAT_GRAYSCALE_ALPHA; } break; - case IMAGE_FORMAT_RGB: { fmt=Image::FORMAT_RGB; } break; - case IMAGE_FORMAT_RGBA: { fmt=Image::FORMAT_RGBA; } break; - case IMAGE_FORMAT_INDEXED: { fmt=Image::FORMAT_INDEXED; } break; - case IMAGE_FORMAT_INDEXED_ALPHA: { fmt=Image::FORMAT_INDEXED_ALPHA; } break; - case IMAGE_FORMAT_BC1: { fmt=Image::FORMAT_BC1; } break; - case IMAGE_FORMAT_BC2: { fmt=Image::FORMAT_BC2; } break; - case IMAGE_FORMAT_BC3: { fmt=Image::FORMAT_BC3; } break; - case IMAGE_FORMAT_BC4: { fmt=Image::FORMAT_BC4; } break; - case IMAGE_FORMAT_BC5: { fmt=Image::FORMAT_BC5; } break; - case IMAGE_FORMAT_CUSTOM: { fmt=Image::FORMAT_CUSTOM; } break; - default: { - - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - - } - - - uint32_t datalen = f->get_32(); - - print_bl("width: "+itos(width)); - print_bl("height: "+itos(height)); - print_bl("mipmaps: "+itos(mipmaps)); - print_bl("format: "+itos(format)); - print_bl("datalen: "+itos(datalen)); - - DVector<uint8_t> imgdata; - imgdata.resize(datalen); - DVector<uint8_t>::Write w = imgdata.write(); - f->get_buffer(w.ptr(),datalen); - _advance_padding(datalen); - w=DVector<uint8_t>::Write(); - - r_v=Image(width,height,mipmaps,fmt,imgdata); - } - - - } break; - case VARIANT_NODE_PATH: { - - r_v=NodePath(get_unicode_string()); - } break; - case VARIANT_RID: { - - r_v=f->get_32(); - } break; - case VARIANT_OBJECT: { - - uint32_t type=f->get_32(); - - switch(type) { - - case OBJECT_EMPTY: { - //do none - - } break; - case OBJECT_INTERNAL_RESOURCE: { - uint32_t index=f->get_32(); - String path = local_path+"::"+itos(index); - RES res = ResourceLoader::load(path); - if (res.is_null()) { - WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data()); - } - r_v=res; - - } break; - case OBJECT_EXTERNAL_RESOURCE: { - - String type = get_unicode_string(); - String path = get_unicode_string(); - - if (path.find("://")==-1 && path.is_rel_path()) { - // path is relative to file being loaded, so convert to a resource path - path=Globals::get_singleton()->localize_path(local_path.get_base_dir()+"/"+path); - - } - - RES res=ResourceLoader::load(path,type); - - if (res.is_null()) { - WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data()); - } - r_v=res; - - } break; - default: { - - ERR_FAIL_V(ERR_FILE_CORRUPT); - } break; - } - - } break; - case VARIANT_INPUT_EVENT: { - - } break; - case VARIANT_DICTIONARY: { - - int len=f->get_32(); - Dictionary d; - for(int i=0;i<len;i++) { - int idx; - Variant key; - Error err = parse_property(key,idx); - ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT); - Variant value; - err = parse_property(value,idx); - ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT); - d[key]=value; - } - r_v=d; - } break; - case VARIANT_ARRAY: { - int len=f->get_32(); - Array a; - a.resize(len); - for(int i=0;i<len;i++) { - int idx; - Variant val; - Error err = parse_property(val,idx); - ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT); - a[i]=val; - } - r_v=a; - - } break; - case VARIANT_RAW_ARRAY: { - - uint32_t len = f->get_32(); - - DVector<uint8_t> array; - array.resize(len); - DVector<uint8_t>::Write w = array.write(); - f->get_buffer(w.ptr(),len); - _advance_padding(len); - w=DVector<uint8_t>::Write(); - r_v=array; - - } break; - case VARIANT_INT_ARRAY: { - - uint32_t len = f->get_32(); - - DVector<int> array; - array.resize(len); - DVector<int>::Write w = array.write(); - f->get_buffer((uint8_t*)w.ptr(),len*4); - w=DVector<int>::Write(); - r_v=array; - } break; - case VARIANT_REAL_ARRAY: { - - uint32_t len = f->get_32(); - - DVector<real_t> array; - array.resize(len); - DVector<real_t>::Write w = array.write(); - f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)); - w=DVector<real_t>::Write(); - r_v=array; - } break; - case VARIANT_STRING_ARRAY: { - - uint32_t len = f->get_32(); - DVector<String> array; - array.resize(len); - DVector<String>::Write w = array.write(); - for(int i=0;i<len;i++) - w[i]=get_unicode_string(); - w=DVector<String>::Write(); - r_v=array; - - - } break; - case VARIANT_VECTOR2_ARRAY: { - - uint32_t len = f->get_32(); - - DVector<Vector2> array; - array.resize(len); - DVector<Vector2>::Write w = array.write(); - if (sizeof(Vector2)==8) { - f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*2); - } else { - ERR_EXPLAIN("Vector2 size is NOT 8!"); - ERR_FAIL_V(ERR_UNAVAILABLE); - } - w=DVector<Vector2>::Write(); - r_v=array; - - } break; - case VARIANT_VECTOR3_ARRAY: { - - uint32_t len = f->get_32(); - - DVector<Vector3> array; - array.resize(len); - DVector<Vector3>::Write w = array.write(); - if (sizeof(Vector3)==12) { - f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*3); - } else { - ERR_EXPLAIN("Vector3 size is NOT 12!"); - ERR_FAIL_V(ERR_UNAVAILABLE); - } - w=DVector<Vector3>::Write(); - r_v=array; - - } break; - case VARIANT_COLOR_ARRAY: { - - uint32_t len = f->get_32(); - - DVector<Color> array; - array.resize(len); - DVector<Color>::Write w = array.write(); - if (sizeof(Color)==16) { - f->get_buffer((uint8_t*)w.ptr(),len*sizeof(real_t)*4); - } else { - ERR_EXPLAIN("Color size is NOT 16!"); - ERR_FAIL_V(ERR_UNAVAILABLE); - } - w=DVector<Color>::Write(); - r_v=array; - } break; - - default: { - ERR_FAIL_V(ERR_FILE_CORRUPT); - } break; - } - - - - return OK; //never reach anyway - -} - -Error ObjectFormatLoaderBinary::load(Object **p_object,Variant &p_meta) { - - - - while(true) { - - if (f->eof_reached()) { - ERR_EXPLAIN("Premature end of file at: "+local_path); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - - RES resource; - Object *obj=NULL; - bool meta=false; - - uint32_t section = f->get_32(); - - switch(section) { - - - case SECTION_RESOURCE: { - - print_bl("resource found"); - - size_t section_end = f->get_64(); - print_bl("section end: "+itos(section_end)); - String type = get_unicode_string(); - String path = get_unicode_string(); - print_bl("path: "+path); - - if (path.begins_with("local://")) { - //built-in resource (but really external) - path=path.replace("local://",local_path+"::"); - } - - if (ResourceCache::has(path)) { - f->seek(section_end); - continue; - } - - //load properties - - - obj = ObjectTypeDB::instance(type); - if (!obj) { - ERR_EXPLAIN("Object of unrecognized type '"+type+"' in file: "+type); - } - - ERR_FAIL_COND_V(!obj,ERR_FILE_CORRUPT); - - Resource *r = obj->cast_to<Resource>(); - if (!r) { - memdelete(obj); //bye - ERR_EXPLAIN("Object type in resource field not a resource, type is: "+obj->get_type()); - ERR_FAIL_COND_V(!obj->cast_to<Resource>(),ERR_FILE_CORRUPT); - } - - resource = RES( r ); - r->set_path(path); - } break; - case SECTION_META_OBJECT: - meta=true; - print_bl("meta found"); - - case SECTION_OBJECT: { - - uint64_t section_end = f->get_64(); - - if (!meta) { - print_bl("object"); - - String type = get_unicode_string(); - if (ObjectTypeDB::can_instance(type)) { - obj = ObjectTypeDB::instance(type); - if (!obj) { - ERR_EXPLAIN("Object of unrecognized type in file: "+type); - } - ERR_FAIL_COND_V(!obj,ERR_FILE_CORRUPT); - } else { - - f->seek(section_end); - return ERR_SKIP; - }; - - - } - - - } break; - case SECTION_END: { - - - return ERR_FILE_EOF; - } break; - - default: { - - ERR_EXPLAIN("Invalid Section ID '"+itos(section)+"' in file: "+local_path); - ERR_FAIL_V(ERR_FILE_CORRUPT); - - } - - } - - - //load properties - - while(true) { - - int name_idx; - Variant v; - Error err; - err = parse_property(v,name_idx); - - print_bl("prop idx "+itos(name_idx)+" value: "+String(v)); - - if (err==ERR_FILE_EOF) - break; - - if (err!=OK) { - ERR_EXPLAIN("File Corrupted"); - ERR_FAIL_COND_V(err!=OK,ERR_FILE_CORRUPT); - } - - - if (resource.is_null() && name_idx==0) { //0 is __bin_meta__ - - p_meta=v; - continue; - } else if (!obj) { - - ERR_EXPLAIN("Normal property found in meta object."); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - - Map<int,StringName>::Element *E=string_map.find(name_idx); - if (!E) { - ERR_EXPLAIN("Property ID has no matching name: "+itos(name_idx)); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - - obj->set(E->get(),v); - } - - if (!obj) { - *p_object=NULL; - return OK; // it was a meta object - } - - if (resource.is_null()) { - - //regular object - *p_object=obj; - return OK; - } else { - - resource_cache.push_back(resource); //keep it in mem until finished loading - } - - } -} - - -ObjectFormatLoaderBinary::~ObjectFormatLoaderBinary() { - - if (f) { - if (f->is_open()) - f->close(); - memdelete(f); - } -} - - -String ObjectFormatLoaderBinary::get_unicode_string() { - - uint32_t len = f->get_32(); - if (len>str_buf.size()) { - str_buf.resize(len); - } - f->get_buffer((uint8_t*)&str_buf[0],len); - String s; - s.parse_utf8(&str_buf[0]); - return s; -} - -ObjectFormatLoaderBinary::ObjectFormatLoaderBinary(FileAccess *p_f,bool p_endian_swap,bool p_use64) { - - f=p_f; - endian_swap=p_endian_swap; - use_real64=p_use64; - - //load string table - uint32_t string_table_size = f->get_32(); - print_bl("string table size: "+itos(string_table_size)); - for(int i=0;i<string_table_size;i++) { - - String str = get_unicode_string(); - print_bl("string "+itos(i)+" is: "+str); - string_map[i]=str; - } - - -} - -ObjectFormatLoaderBinary* ObjectFormatLoaderInstancerBinary::instance(const String& p_file,const String& p_magic) { - - FileAccess *f=FileAccess::open(p_file,FileAccess::READ); - ERR_FAIL_COND_V(!f,NULL); - - uint8_t header[4]; - f->get_buffer(header,4); - if (header[0]!='O' || header[1]!='B' || header[2]!='D' || header[3]!='B') { - - ERR_EXPLAIN("File not in valid binary format: "+p_file); - ERR_FAIL_V(NULL); - } - - uint32_t big_endian = f->get_32(); -#ifdef BIG_ENDIAN_ENABLED - bool endian_swap = !big_endian; -#else - bool endian_swap = big_endian; -#endif - - bool use_real64 = f->get_32(); - - f->set_endian_swap(big_endian!=0); //read big endian if saved as big endian - - uint32_t ver_major=f->get_32(); - uint32_t ver_minor=f->get_32(); - - print_bl("big endian: "+itos(big_endian)); - print_bl("endian swap: "+itos(endian_swap)); - print_bl("real64: "+itos(use_real64)); - print_bl("major: "+itos(ver_major)); - print_bl("minor: "+itos(ver_minor)); - - if (ver_major>VERSION_MAJOR || (ver_major==VERSION_MAJOR && ver_minor>VERSION_MINOR)) { - - f->close(); - memdelete(f); - ERR_EXPLAIN("File Format '"+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+p_file); - ERR_FAIL_V(NULL); - - } - - uint32_t magic_len = f->get_32(); - Vector<char> magic; - magic.resize(magic_len); - f->get_buffer((uint8_t*)&magic[0],magic_len); - String magic_str; - magic_str.parse_utf8(&magic[0]); - - print_bl("magic: "+magic_str); - if (magic_str!=p_magic) { - - f->close(); - memdelete(f); - ERR_EXPLAIN("File magic mismatch, found '"+magic_str+"' in : "+p_file); - ERR_FAIL_V(NULL); - } - - print_bl("skipping 32"); - for(int i=0;i<16;i++) - f->get_32(); //skip a few reserved fields - - if (f->eof_reached()) { - - f->close(); - memdelete(f); - ERR_EXPLAIN("Premature End Of File: "+p_file); - ERR_FAIL_V(NULL); - - } - - print_bl("creating loader"); - ObjectFormatLoaderBinary *loader = memnew( ObjectFormatLoaderBinary(f,endian_swap,use_real64) ); - loader->local_path=p_file; - - return loader; -} - -void ObjectFormatLoaderInstancerBinary::get_recognized_extensions(List<String> *p_extensions) const { - - p_extensions->push_back("bin"); -} - - -#endif diff --git a/core/io/object_format_binary.h b/core/io/object_format_binary.h deleted file mode 100644 index aaf6bf357a..0000000000 --- a/core/io/object_format_binary.h +++ /dev/null @@ -1,158 +0,0 @@ -/*************************************************************************/ -/* object_format_binary.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef OBJECT_FORMAT_BINARY_H -#define OBJECT_FORMAT_BINARY_H - -#include "object_loader.h" -#include "object_saver_base.h" -#include "dvector.h" -#include "core/os/file_access.h" - -#ifdef OLD_SCENE_FORMAT_ENABLED -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - - -class ObjectFormatSaverBinary : public ObjectFormatSaver { - - String local_path; - - - Ref<OptimizedSaver> optimizer; - - bool relative_paths; - bool bundle_resources; - bool skip_editor; - bool big_endian; - int bin_meta_idx; - FileAccess *f; - String magic; - Map<RES,int> resource_map; - Map<StringName,int> string_map; - Vector<StringName> strings; - - struct SavedObject { - - Variant meta; - String type; - - - struct SavedProperty { - - int name_idx; - Variant value; - }; - - List<SavedProperty> properties; - }; - - - int get_string_index(const String& p_string); - void save_unicode_string(const String& p_string); - - List<SavedObject*> saved_objects; - List<SavedObject*> saved_resources; - - void _pad_buffer(int p_bytes); - Error _save_obj(const Object *p_object,SavedObject *so); - void _find_resources(const Variant& p_variant); - void write_property(int p_idx,const Variant& p_property); - - -public: - - virtual Error save(const Object *p_object,const Variant &p_meta); - - ObjectFormatSaverBinary(FileAccess *p_file,const String& p_magic,const String& p_local_path,uint32_t p_flags,const Ref<OptimizedSaver>& p_optimizer); - ~ObjectFormatSaverBinary(); -}; - -class ObjectFormatSaverInstancerBinary : public ObjectFormatSaverInstancer { -public: - - virtual ObjectFormatSaver* instance(const String& p_file,const String& p_magic,uint32_t p_flags=0,const Ref<OptimizedSaver>& p_optimizer=Ref<OptimizedSaver>()); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - - virtual ~ObjectFormatSaverInstancerBinary(); -}; - - - - -/***********************************/ -/***********************************/ -/***********************************/ -/***********************************/ - -class ObjectFormatLoaderBinary : public ObjectFormatLoader { - - String local_path; - - FileAccess *f; - - bool endian_swap; - bool use_real64; - - Vector<char> str_buf; - List<RES> resource_cache; - - Map<int,StringName> string_map; - - String get_unicode_string(); - void _advance_padding(uint32_t p_len); - -friend class ObjectFormatLoaderInstancerBinary; - - - Error parse_property(Variant& r_v, int& r_index); - -public: - - - virtual Error load(Object **p_object,Variant &p_meta); - - ObjectFormatLoaderBinary(FileAccess *f,bool p_endian_swap,bool p_use64); - virtual ~ObjectFormatLoaderBinary(); -}; - -class ObjectFormatLoaderInstancerBinary : public ObjectFormatLoaderInstancer { -public: - - virtual ObjectFormatLoaderBinary* instance(const String& p_file,const String& p_magic); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - - - -}; - - - -#endif // OBJECT_FORMAT_BINARY_H -#endif diff --git a/core/io/object_format_xml.cpp b/core/io/object_format_xml.cpp deleted file mode 100644 index 0a8ce70d5e..0000000000 --- a/core/io/object_format_xml.cpp +++ /dev/null @@ -1,3190 +0,0 @@ -/*************************************************************************/ -/* object_format_xml.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifdef XML_ENABLED -#ifdef OLD_SCENE_FORMAT_ENABLED -#include "object_format_xml.h" -#include "resource.h" -#include "io/resource_loader.h" -#include "print_string.h" -#include "object_type_db.h" -#include "globals.h" -#include "os/os.h" -#include "version.h" - -void ObjectFormatSaverXML::escape(String& p_str) { - - p_str=p_str.replace("&","&"); - p_str=p_str.replace("<",">"); - p_str=p_str.replace(">","<"); - p_str=p_str.replace("'","'"); - p_str=p_str.replace("\"","""); - for (int i=1;i<32;i++) { - - char chr[2]={i,0}; - p_str=p_str.replace(chr,"&#"+String::num(i)+";"); - } - - -} -void ObjectFormatSaverXML::write_tabs(int p_diff) { - - for (int i=0;i<depth+p_diff;i++) { - - f->store_8('\t'); - } -} - -void ObjectFormatSaverXML::write_string(String p_str,bool p_escape) { - - /* write an UTF8 string */ - if (p_escape) - escape(p_str); - - f->store_string(p_str);; - /* - CharString cs=p_str.utf8(); - const char *data=cs.get_data(); - - while (*data) { - f->store_8(*data); - data++; - }*/ - - -} - -void ObjectFormatSaverXML::enter_tag(const String& p_section,const String& p_args) { - - if (p_args.length()) - write_string("<"+p_section+" "+p_args+">",false); - else - write_string("<"+p_section+">",false); - depth++; -} -void ObjectFormatSaverXML::exit_tag(const String& p_section) { - - depth--; - write_string("</"+p_section+">",false); - -} - -/* -static bool _check_type(const Variant& p_property) { - - if (p_property.get_type()==Variant::_RID) - return false; - if (p_property.get_type()==Variant::OBJECT) { - RES res = p_property; - if (res.is_null()) - return false; - } - - return true; -}*/ - -void ObjectFormatSaverXML::write_property(const String& p_name,const Variant& p_property,bool *r_ok) { - - if (r_ok) - *r_ok=false; - - String type; - String params; - bool oneliner=true; - - switch( p_property.get_type() ) { - - case Variant::NIL: type="nil"; break; - case Variant::BOOL: type="bool"; break; - case Variant::INT: type="int"; break; - case Variant::REAL: type="real"; break; - case Variant::STRING: type="string"; break; - case Variant::VECTOR2: type="vector2"; break; - case Variant::RECT2: type="rect2"; break; - case Variant::VECTOR3: type="vector3"; break; - case Variant::PLANE: type="plane"; break; - case Variant::_AABB: type="aabb"; break; - case Variant::QUAT: type="quaternion"; break; - case Variant::MATRIX32: type="matrix32"; break; - case Variant::MATRIX3: type="matrix3"; break; - case Variant::TRANSFORM: type="transform"; break; - case Variant::COLOR: type="color"; break; - case Variant::IMAGE: { - type="image"; - Image img=p_property; - if (img.empty()) { - enter_tag(type,"name=\""+p_name+"\""); - exit_tag(type); - if (r_ok) - *r_ok=true; - return; - } - params+="encoding=\"raw\""; - params+=" width=\""+itos(img.get_width())+"\""; - params+=" height=\""+itos(img.get_height())+"\""; - params+=" mipmaps=\""+itos(img.get_mipmaps())+"\""; - - switch(img.get_format()) { - - case Image::FORMAT_GRAYSCALE: params+=" format=\"grayscale\""; break; - case Image::FORMAT_INTENSITY: params+=" format=\"intensity\""; break; - case Image::FORMAT_GRAYSCALE_ALPHA: params+=" format=\"grayscale_alpha\""; break; - case Image::FORMAT_RGB: params+=" format=\"rgb\""; break; - case Image::FORMAT_RGBA: params+=" format=\"rgba\""; break; - case Image::FORMAT_INDEXED : params+=" format=\"indexed\""; break; - case Image::FORMAT_INDEXED_ALPHA: params+=" format=\"indexed_alpha\""; break; - case Image::FORMAT_BC1: params+=" format=\"bc1\""; break; - case Image::FORMAT_BC2: params+=" format=\"bc2\""; break; - case Image::FORMAT_BC3: params+=" format=\"bc3\""; break; - case Image::FORMAT_BC4: params+=" format=\"bc4\""; break; - case Image::FORMAT_BC5: params+=" format=\"bc5\""; break; - case Image::FORMAT_CUSTOM: params+=" format=\"custom\" custom_size=\""+itos(img.get_data().size())+"\""; break; - default: {} - } - } break; - case Variant::NODE_PATH: type="node_path"; break; - case Variant::OBJECT: { - type="resource"; - RES res = p_property; - if (res.is_null()) { - enter_tag(type,"name=\""+p_name+"\""); - exit_tag(type); - if (r_ok) - *r_ok=true; - - return; // don't save it - } - - params="resource_type=\""+res->get_type()+"\""; - - if (res->get_path().length() && res->get_path().find("::")==-1) { - //external resource - String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path(); - escape(path); - params+=" path=\""+path+"\""; - } else { - - //internal resource - ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); - ERR_FAIL_COND(!resource_map.has(res)); - - params+=" path=\"local://"+itos(resource_map[res])+"\""; - } - - } break; - case Variant::INPUT_EVENT: type="input_event"; break; - case Variant::DICTIONARY: type="dictionary" ; oneliner=false; break; - case Variant::ARRAY: type="array"; params="len=\""+itos(p_property.operator Array().size())+"\""; oneliner=false; break; - - case Variant::RAW_ARRAY: type="raw_array"; params="len=\""+itos(p_property.operator DVector < uint8_t >().size())+"\""; break; - case Variant::INT_ARRAY: type="int_array"; params="len=\""+itos(p_property.operator DVector < int >().size())+"\""; break; - case Variant::REAL_ARRAY: type="real_array"; params="len=\""+itos(p_property.operator DVector < real_t >().size())+"\""; break; - case Variant::STRING_ARRAY: type="string_array"; params="len=\""+itos(p_property.operator DVector < String >().size())+"\""; break; - case Variant::VECTOR2_ARRAY: type="vector2_array"; params="len=\""+itos(p_property.operator DVector < Vector2 >().size())+"\""; break; - case Variant::VECTOR3_ARRAY: type="vector3_array"; params="len=\""+itos(p_property.operator DVector < Vector3 >().size())+"\""; break; - case Variant::COLOR_ARRAY: type="color_array"; params="len=\""+itos(p_property.operator DVector < Color >().size())+"\""; break; - default: { - - ERR_PRINT("Unknown Variant type."); - ERR_FAIL(); - } - - } - - write_tabs(); - - if (p_name!="") { - if (params.length()) - enter_tag(type,"name=\""+p_name+"\" "+params); - else - enter_tag(type,"name=\""+p_name+"\""); - } else { - if (params.length()) - enter_tag(type," "+params); - else - enter_tag(type,""); - } - - if (!oneliner) - write_string("\n",false); - else - write_string(" ",false); - - - switch( p_property.get_type() ) { - - case Variant::NIL: { - - } break; - case Variant::BOOL: { - - write_string( p_property.operator bool() ? "True":"False" ); - } break; - case Variant::INT: { - - write_string( itos(p_property.operator int()) ); - } break; - case Variant::REAL: { - - write_string( rtos(p_property.operator real_t()) ); - } break; - case Variant::STRING: { - - String str=p_property; - escape(str); - str="\""+str+"\""; - write_string( str,false ); - } break; - case Variant::VECTOR2: { - - Vector2 v = p_property; - write_string( rtoss(v.x) +", "+rtoss(v.y) ); - } break; - case Variant::RECT2: { - - Rect2 aabb = p_property; - write_string( rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y) ); - - } break; - case Variant::VECTOR3: { - - Vector3 v = p_property; - write_string( rtoss(v.x) +", "+rtoss(v.y)+", "+rtoss(v.z) ); - } break; - case Variant::PLANE: { - - Plane p = p_property; - write_string( rtoss(p.normal.x) +", "+rtoss(p.normal.y)+", "+rtoss(p.normal.z)+", "+rtoss(p.d) ); - - } break; - case Variant::_AABB: { - - AABB aabb = p_property; - write_string( rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.pos.z) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y) +", "+rtoss(aabb.size.z) ); - - } break; - case Variant::QUAT: { - - Quat quat = p_property; - write_string( rtoss(quat.x)+", "+rtoss(quat.y)+", "+rtoss(quat.z)+", "+rtoss(quat.w)+", "); - - } break; - case Variant::MATRIX32: { - - String s; - Matrix32 m3 = p_property; - for (int i=0;i<3;i++) { - for (int j=0;j<2;j++) { - - if (i!=0 || j!=0) - s+=", "; - s+=rtoss( m3.elements[i][j] ); - } - } - - write_string(s); - - } break; - case Variant::MATRIX3: { - - String s; - Matrix3 m3 = p_property; - for (int i=0;i<3;i++) { - for (int j=0;j<3;j++) { - - if (i!=0 || j!=0) - s+=", "; - s+=rtoss( m3.elements[i][j] ); - } - } - - write_string(s); - - } break; - case Variant::TRANSFORM: { - - String s; - Transform t = p_property; - Matrix3 &m3 = t.basis; - for (int i=0;i<3;i++) { - for (int j=0;j<3;j++) { - - if (i!=0 || j!=0) - s+=", "; - s+=rtoss( m3.elements[i][j] ); - } - } - - s=s+", "+rtoss(t.origin.x) +", "+rtoss(t.origin.y)+", "+rtoss(t.origin.z); - - write_string(s); - } break; - - // misc types - case Variant::COLOR: { - - Color c = p_property; - write_string( rtoss(c.r) +", "+rtoss(c.g)+", "+rtoss(c.b)+", "+rtoss(c.a) ); - - } break; - case Variant::IMAGE: { - - String s; - Image img = p_property; - DVector<uint8_t> data = img.get_data(); - int len = data.size(); - DVector<uint8_t>::Read r = data.read(); - const uint8_t *ptr=r.ptr();; - for (int i=0;i<len;i++) { - - uint8_t byte = ptr[i]; - const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - char str[3]={ hex[byte>>4], hex[byte&0xF], 0}; - s+=str; - } - - write_string(s); - } break; - case Variant::NODE_PATH: { - - String str=p_property; - escape(str); - str="\""+str+"\""; - write_string( str,false); - - } break; - - case Variant::OBJECT: { - /* this saver does not save resources in here - RES res = p_property; - - if (!res.is_null()) { - - String path=res->get_path(); - if (!res->is_shared() || !path.length()) { - // if no path, or path is from inside a scene - write_object( *res ); - } - - } - */ - - } break; - case Variant::INPUT_EVENT: { - - write_string( p_property.operator String() ); - } break; - case Variant::DICTIONARY: { - - Dictionary dict = p_property; - - - List<Variant> keys; - dict.get_key_list(&keys); - - for(List<Variant>::Element *E=keys.front();E;E=E->next()) { - - //if (!_check_type(dict[E->get()])) - // continue; - - bool ok; - write_property("",E->get(),&ok); - ERR_CONTINUE(!ok); - - write_property("",dict[E->get()],&ok); - if (!ok) - write_property("",Variant()); //at least make the file consistent.. - } - - - - - } break; - case Variant::ARRAY: { - - Array array = p_property; - int len=array.size(); - for (int i=0;i<len;i++) { - - write_property("",array[i]); - - } - - } break; - - case Variant::RAW_ARRAY: { - - String s; - DVector<uint8_t> data = p_property; - int len = data.size(); - DVector<uint8_t>::Read r = data.read(); - const uint8_t *ptr=r.ptr();; - for (int i=0;i<len;i++) { - - uint8_t byte = ptr[i]; - const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - char str[3]={ hex[byte>>4], hex[byte&0xF], 0}; - s+=str; - } - - write_string(s,false); - - } break; - case Variant::INT_ARRAY: { - - DVector<int> data = p_property; - int len = data.size(); - DVector<int>::Read r = data.read(); - const int *ptr=r.ptr();; - write_tabs(); - - for (int i=0;i<len;i++) { - - if (i>0) - write_string(", ",false); - - write_string(itos(ptr[i]),false); - } - - - - } break; - case Variant::REAL_ARRAY: { - - DVector<real_t> data = p_property; - int len = data.size(); - DVector<real_t>::Read r = data.read(); - const real_t *ptr=r.ptr();; - write_tabs(); - - for (int i=0;i<len;i++) { - - if (i>0) - write_string(", ",false); - write_string(rtoss(ptr[i]),false); - } - - - } break; - case Variant::STRING_ARRAY: { - - DVector<String> data = p_property; - int len = data.size(); - DVector<String>::Read r = data.read(); - const String *ptr=r.ptr();; - String s; - - for (int i=0;i<len;i++) { - - if (i>0) - s+=", "; - String str=ptr[i]; - escape(str); - s=s+"\""+str+"\""; - } - - write_string(s,false); - - } break; - case Variant::VECTOR2_ARRAY: { - - DVector<Vector2> data = p_property; - int len = data.size(); - DVector<Vector2>::Read r = data.read(); - const Vector2 *ptr=r.ptr();; - write_tabs(); - - for (int i=0;i<len;i++) { - - if (i>0) - write_string(", ",false); - write_string(rtoss(ptr[i].x),false); - write_string(", "+rtoss(ptr[i].y),false); - - } - - - } break; - case Variant::VECTOR3_ARRAY: { - - DVector<Vector3> data = p_property; - int len = data.size(); - DVector<Vector3>::Read r = data.read(); - const Vector3 *ptr=r.ptr();; - write_tabs(); - - for (int i=0;i<len;i++) { - - if (i>0) - write_string(", ",false); - write_string(rtoss(ptr[i].x),false); - write_string(", "+rtoss(ptr[i].y),false); - write_string(", "+rtoss(ptr[i].z),false); - - } - - - } break; - case Variant::COLOR_ARRAY: { - - DVector<Color> data = p_property; - int len = data.size(); - DVector<Color>::Read r = data.read(); - const Color *ptr=r.ptr();; - write_tabs(); - - for (int i=0;i<len;i++) { - - if (i>0) - write_string(", ",false); - - write_string(rtoss(ptr[i].r),false); - write_string(", "+rtoss(ptr[i].g),false); - write_string(", "+rtoss(ptr[i].b),false); - write_string(", "+rtoss(ptr[i].a),false); - - } - - } break; - default: {} - - } - if (oneliner) - write_string(" "); - else - write_tabs(-1); - exit_tag(type); - - write_string("\n",false); - - if (r_ok) - *r_ok=true; - -} - - -void ObjectFormatSaverXML::_find_resources(const Variant& p_variant) { - - - switch(p_variant.get_type()) { - case Variant::OBJECT: { - - - - RES res = p_variant.operator RefPtr(); - - if (res.is_null()) - return; - - if (!bundle_resources && res->get_path().length() && res->get_path().find("::") == -1 ) - return; - - if (resource_map.has(res)) - return; - - List<PropertyInfo> property_list; - - res->get_property_list( &property_list ); - - List<PropertyInfo>::Element *I=property_list.front(); - - while(I) { - - PropertyInfo pi=I->get(); - - if (pi.usage&PROPERTY_USAGE_STORAGE || (bundle_resources && pi.usage&PROPERTY_USAGE_BUNDLE)) { - - Variant v=res->get(I->get().name); - _find_resources(v); - } - - I=I->next(); - } - - resource_map[ res ] = resource_map.size(); //saved after, so the childs it needs are available when loaded - saved_resources.push_back(res); - - } break; - - case Variant::ARRAY: { - - Array varray=p_variant; - int len=varray.size(); - for(int i=0;i<len;i++) { - - Variant v=varray.get(i); - _find_resources(v); - } - - } break; - - case Variant::DICTIONARY: { - - Dictionary d=p_variant; - List<Variant> keys; - d.get_key_list(&keys); - for(List<Variant>::Element *E=keys.front();E;E=E->next()) { - - Variant v = d[E->get()]; - _find_resources(v); - } - } break; - default: {} - } - -} - - - -Error ObjectFormatSaverXML::save(const Object *p_object,const Variant &p_meta) { - - ERR_FAIL_COND_V(!f,ERR_UNCONFIGURED); - ERR_EXPLAIN("write_object should supply either an object, a meta, or both"); - ERR_FAIL_COND_V(!p_object && p_meta.get_type()==Variant::NIL, ERR_INVALID_PARAMETER); - - SavedObject *so = memnew( SavedObject ); - - if (p_object) - so->type=p_object->get_type(); - - _find_resources(p_meta); - so->meta=p_meta; - - if (p_object) { - - - if (optimizer.is_valid()) { - //use optimizer - - List<OptimizedSaver::Property> props; - optimizer->get_property_list(p_object,&props); - - for(List<OptimizedSaver::Property>::Element *E=props.front();E;E=E->next()) { - - if (skip_editor && String(E->get().name).begins_with("__editor")) - continue; - _find_resources(E->get().value); - SavedObject::SavedProperty sp; - sp.name=E->get().name; - sp.value=E->get().value; - so->properties.push_back(sp); - } - - } else { - //use classic way - List<PropertyInfo> property_list; - p_object->get_property_list( &property_list ); - - for(List<PropertyInfo>::Element *E=property_list.front();E;E=E->next()) { - - if (skip_editor && E->get().name.begins_with("__editor")) - continue; - if (E->get().usage&PROPERTY_USAGE_STORAGE || (bundle_resources && E->get().usage&PROPERTY_USAGE_BUNDLE)) { - - SavedObject::SavedProperty sp; - sp.name=E->get().name; - sp.value = p_object->get(E->get().name); - _find_resources(sp.value); - so->properties.push_back(sp); - } - } - } - - } - - saved_objects.push_back(so); - - return OK; -} - -ObjectFormatSaverXML::ObjectFormatSaverXML(FileAccess *p_file,const String& p_magic,const String& p_local_path,uint32_t p_flags,const Ref<OptimizedSaver>& p_optimizer) { - - optimizer=p_optimizer; - relative_paths=p_flags&ObjectSaver::FLAG_RELATIVE_PATHS; - skip_editor=p_flags&ObjectSaver::FLAG_OMIT_EDITOR_PROPERTIES; - bundle_resources=p_flags&ObjectSaver::FLAG_BUNDLE_RESOURCES; - f=p_file; // should be already opened - depth=0; - local_path=p_local_path; - magic=p_magic; -} -ObjectFormatSaverXML::~ObjectFormatSaverXML() { - - write_string("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>",false); //no escape - write_string("\n",false); - enter_tag("object_file","magic=\""+magic+"\" "+"version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\""); - write_string("\n",false); - - // save resources - - for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { - - RES res = E->get(); - ERR_CONTINUE(!resource_map.has(res)); - - write_tabs(); - if (res->get_path().length() && res->get_path().find("::") == -1 ) - enter_tag("resource","type=\""+res->get_type()+"\" path=\""+res->get_path()+"\""); //bundled - else - enter_tag("resource","type=\""+res->get_type()+"\" path=\"local://"+itos(resource_map[res])+"\""); - - if (optimizer.is_valid()) { - - List<OptimizedSaver::Property> props; - optimizer->get_property_list(res.ptr(),&props); - - for(List<OptimizedSaver::Property>::Element *E=props.front();E;E=E->next()) { - - if (skip_editor && String(E->get().name).begins_with("__editor")) - continue; - - write_property(E->get().name,E->get().value); - } - - - } else { - - List<PropertyInfo> property_list; - res->get_property_list(&property_list); - for(List<PropertyInfo>::Element *PE = property_list.front();PE;PE=PE->next()) { - - - if (skip_editor && PE->get().name.begins_with("__editor")) - continue; - - if (PE->get().usage&PROPERTY_USAGE_STORAGE || (bundle_resources && PE->get().usage&PROPERTY_USAGE_BUNDLE)) { - - String name = PE->get().name; - Variant value = res->get(name); - write_property(name,value); - } - - - } - - } - write_tabs(-1); - exit_tag("resource"); - write_string("\n",false); - } - - if (!saved_objects.empty()) { - - - for(List<SavedObject*>::Element *E=saved_objects.front();E;E=E->next()) { - - SavedObject *so = E->get(); - - - - write_tabs(); - if (so->type!="") - enter_tag("object","type=\""+so->type+"\""); - else - enter_tag("object"); - write_string("\n",false); - - if (so->meta.get_type()!=Variant::NIL) { - - write_property("__xml_meta__",so->meta); - - } - - List<SavedObject::SavedProperty>::Element *SE = so->properties.front(); - - while(SE) { - - write_property(SE->get().name,SE->get().value); - SE=SE->next(); - } - - - write_tabs(-1); - exit_tag("object"); - write_string("\n",false); - memdelete(so); //no longer needed - } - - - } else { - - WARN_PRINT("File contains no saved objects."); - } - - exit_tag("object_file"); - f->close(); - memdelete(f); -} - - -ObjectFormatSaver* ObjectFormatSaverInstancerXML::instance(const String& p_file,const String& p_magic,uint32_t p_flags,const Ref<OptimizedSaver>& p_optimizer) { - - Error err; - FileAccess *f = FileAccess::open(p_file, FileAccess::WRITE,&err); - - ERR_FAIL_COND_V( err, NULL ); - String local_path = Globals::get_singleton()->localize_path(p_file); - - return memnew( ObjectFormatSaverXML( f, p_magic,local_path,p_flags,p_optimizer ) ); -} - -void ObjectFormatSaverInstancerXML::get_recognized_extensions(List<String> *p_extensions) const { - - p_extensions->push_back("xml"); -} - - -ObjectFormatSaverInstancerXML::~ObjectFormatSaverInstancerXML() { - - -} - -/************************************************/ -/************************************************/ -/************************************************/ -/************************************************/ -/************************************************/ - - - -#ifdef OPTIMIZED_XML_LOADER - -#define IS_FLOAT_CHAR(m_c) \ - ((m_c>='0' && m_c<='9') || m_c=='e' || m_c=='-' || m_c=='+' || m_c=='.') - -#define XML_FAIL(m_cond,m_err) \ - if (m_cond) {\ - ERR_EXPLAIN(local_path+":"+itos(parser->get_current_line())+": "+String(m_err));\ - ERR_FAIL_COND_V( m_cond, ERR_FILE_CORRUPT );\ - } - - -Error ObjectFormatLoaderXML::_parse_property(Variant& r_v,String& r_name) { - - XML_FAIL( parser->is_empty(), "unexpected empty tag"); - - String type=parser->get_node_name(); - String name=parser->get_attribute_value_safe("name"); - - r_v=Variant(); - r_name=name; - - if (type=="dictionary") { - - Dictionary d; - int reading=0; - Variant key; - while(parser->read()==OK) { - - if (parser->get_node_type()==XMLParser::NODE_ELEMENT) { - Error err; - String tagname; - - if (reading==0) { - - err=_parse_property(key,tagname); - XML_FAIL( err,"error parsing dictionary key: "+name); - reading++; - } else { - - reading=0; - Variant value; - err=_parse_property(value,tagname); - XML_FAIL( err,"error parsing dictionary value: "+name); - d[key]=value; - } - - } else if (parser->get_node_type()==XMLParser::NODE_ELEMENT_END && parser->get_node_name()=="dictionary") { - r_v=d; - return OK; - } - } - - - XML_FAIL( true, "unexpected end of file while reading dictionary: "+name); - - } else if (type=="array") { - - XML_FAIL( !parser->has_attribute("len"), "array missing 'len' attribute"); - - int len=parser->get_attribute_value("len").to_int(); - - Array array; - array.resize(len); - - - Variant v; - String tagname; - int idx=0; - - - while(parser->read()==OK) { - - if (parser->get_node_type()==XMLParser::NODE_ELEMENT) { - - XML_FAIL( idx >= len, "array size mismatch (too many elements)"); - Error err; - String tagname; - Variant key; - - err=_parse_property(key,tagname); - XML_FAIL( err,"error parsing element of array: "+name); - array[idx]=key; - idx++; - - - } else if (parser->get_node_type()==XMLParser::NODE_ELEMENT_END && parser->get_node_name()=="array") { - - XML_FAIL( idx != len, "array size mismatch (not "+itos(len)+"):"+name); - r_v=array; - return OK; - } - } - - XML_FAIL( true, "unexpected end of file while reading dictionary: "+name); - - } else if (type=="resource") { - - - XML_FAIL(!parser->has_attribute("path"),"resource property has no 'path' set (embedding not supported).") - - String path=parser->get_attribute_value("path"); - String hint = parser->get_attribute_value_safe("resource_type"); - - if (path.begins_with("local://")) - path=path.replace("local://",local_path+"::"); - else if (path.find("://")==-1 && path.is_rel_path()) { - // path is relative to file being loaded, so convert to a resource path - path=Globals::get_singleton()->localize_path(local_path.get_base_dir()+"/"+path); - - } - - //take advantage of the resource loader cache. The resource is cached on it, even if - RES res=ResourceLoader::load(path,hint); - - - if (res.is_null()) { - - WARN_PRINT(String("Couldn't load resource: "+path).ascii().get_data()); - } - - r_v=res.get_ref_ptr(); - - } else if (type=="image") { - - if (parser->has_attribute("encoding")) { //there is image data - - String encoding=parser->get_attribute_value("encoding"); - - if (encoding=="raw") { - - //raw image (bytes) - - XML_FAIL( !parser->has_attribute("width"), "missing attribute in raw encoding: 'width'."); - XML_FAIL( !parser->has_attribute("height"), "missing attribute in raw encoding: 'height'."); - XML_FAIL( !parser->has_attribute("format"), "missing attribute in raw encoding: 'format'."); - - String format = parser->get_attribute_value("format"); - String width = parser->get_attribute_value("width"); - String height = parser->get_attribute_value("height"); - - Image::Format imgformat; - int chans=0; - int pal=0; - - if (format=="grayscale") { - imgformat=Image::FORMAT_GRAYSCALE; - chans=1; - } else if (format=="intensity") { - imgformat=Image::FORMAT_INTENSITY; - chans=1; - } else if (format=="grayscale_alpha") { - imgformat=Image::FORMAT_GRAYSCALE_ALPHA; - chans=2; - } else if (format=="rgb") { - imgformat=Image::FORMAT_RGB; - chans=3; - } else if (format=="rgba") { - imgformat=Image::FORMAT_RGBA; - chans=4; - } else if (format=="indexed") { - imgformat=Image::FORMAT_INDEXED; - chans=1; - pal=256*3; - } else if (format=="indexed_alpha") { - imgformat=Image::FORMAT_INDEXED_ALPHA; - chans=1; - pal=256*4; - } else { - - XML_FAIL(true, "invalid format for image: "+format); - - } - - XML_FAIL( chans==0, "invalid number of color channels in image (0)."); - - int w=width.to_int(); - int h=height.to_int(); - - if (w == 0 && w == 0) { //epmty, don't even bother - //r_v = Image(w, h, imgformat); - r_v=Image(); - return OK; - } else { - - //decode hexa - - DVector<uint8_t> pixels; - pixels.resize(chans*w*h+pal); - int pixels_size=pixels.size(); - XML_FAIL( pixels_size==0, "corrupt"); - - ERR_FAIL_COND_V(pixels_size==0,ERR_FILE_CORRUPT); - DVector<uint8_t>::Write wr=pixels.write(); - uint8_t *bytes=wr.ptr(); - - XML_FAIL( parser->read()!=OK, "error reading" ); - XML_FAIL( parser->get_node_type()!=XMLParser::NODE_TEXT, "expected text!"); - - String text = parser->get_node_data().strip_edges(); - XML_FAIL( text.length()/2 != pixels_size, "unexpected image data size" ); - - for(int i=0;i<pixels_size*2;i++) { - - uint8_t byte; - CharType c=text[i]; - - if ( (c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f') ) { - - if (i&1) { - - byte|=HEX2CHR(c); - bytes[i>>1]=byte; - } else { - - byte=HEX2CHR(c)<<4; - } - - - } - } - - wr=DVector<uint8_t>::Write(); - r_v=Image(w,h,imgformat,pixels); - } - } - - } else { - r_v=Image(); // empty image, since no encoding defined - } - - } else if (type=="raw_array") { - - XML_FAIL( !parser->has_attribute("len"), "array missing 'len' attribute"); - - int len=parser->get_attribute_value("len").to_int(); - if (len>0) { - - XML_FAIL( parser->read()!=OK, "error reading" ); - XML_FAIL( parser->get_node_type()!=XMLParser::NODE_TEXT, "expected text!"); - String text = parser->get_node_data(); - - XML_FAIL( text.length() != len*2, "raw array length mismatch" ); - - DVector<uint8_t> bytes; - bytes.resize(len); - DVector<uint8_t>::Write w=bytes.write(); - uint8_t *bytesptr=w.ptr(); - - - for(int i=0;i<len*2;i++) { - - uint8_t byte; - CharType c=text[i]; - - if ( (c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f') ) { - - if (i&1) { - - byte|=HEX2CHR(c); - bytesptr[i>>1]=byte; - } else { - - byte=HEX2CHR(c)<<4; - } - } - } - - w=DVector<uint8_t>::Write(); - r_v=bytes; - } - - } else if (type=="int_array") { - - int len=parser->get_attribute_value("len").to_int(); - - if (len>0) { - - XML_FAIL( parser->read()!=OK, "error reading" ); - XML_FAIL( parser->get_node_type()!=XMLParser::NODE_TEXT, "expected text!"); - String text = parser->get_node_data(); - - const CharType *c=text.c_str(); - DVector<int> varray; - varray.resize(len); - DVector<int>::Write w = varray.write(); - - int idx=0; - const CharType *from=c-1; - - while(*c) { - - bool ischar = (*c >='0' && *c<='9') || *c=='+' || *c=='-'; - if (!ischar) { - - if (int64_t(c-from)>1) { - - int i = String::to_int(from+1,int64_t(c-from)); - w[idx++]=i; - } - - from=c; - } else { - - XML_FAIL( idx >= len, "array too big"); - } - - c++; - } - - XML_FAIL( idx != len, "array size mismatch"); - - w = varray.write(); - r_v=varray; - } - - - - } else if (type=="real_array") { - - int len=parser->get_attribute_value("len").to_int(); - - if (len>0) { - - XML_FAIL( parser->read()!=OK, "error reading" ); - XML_FAIL( parser->get_node_type()!=XMLParser::NODE_TEXT, "expected text!"); - String text = parser->get_node_data(); - - const CharType *c=text.c_str(); - DVector<real_t> varray; - varray.resize(len); - DVector<real_t>::Write w = varray.write(); - - int idx=0; - const CharType *from=c-1; - - while(*c) { - - bool ischar = IS_FLOAT_CHAR((*c)); - if (!ischar) { - - if (int64_t(c-from)>1) { - - real_t f = String::to_double(from+1,int64_t(c-from)); - w[idx++]=f; - } - - from=c; - } else { - - XML_FAIL( idx >= len, "array too big"); - } - - c++; - } - - XML_FAIL( idx != len, "array size mismatch"); - - w = varray.write(); - r_v=varray; - } - - } else if (type=="string_array") { - - - // this is invalid xml, and will have to be fixed at some point.. - - int len=parser->get_attribute_value("len").to_int(); - - if (len>0) { - - XML_FAIL( parser->read()!=OK, "error reading" ); - XML_FAIL( parser->get_node_type()!=XMLParser::NODE_TEXT, "expected text!"); - String text = parser->get_node_data(); - - const CharType *c=text.c_str(); - DVector<String> sarray; - sarray.resize(len); - DVector<String>::Write w = sarray.write(); - - - bool inside=false; - const CharType *from=c; - int idx=0; - - while(*c) { - - if (inside) { - - if (*c == '"') { - inside=false; - String s = String(from,int64_t(c-from)); - w[idx]=s; - idx++; - } - } else { - - if (*c == '"') { - inside=true; - from=c+1; - XML_FAIL( idx>=len, "string array is too big!!: "+name); - } - } - - c++; - } - - XML_FAIL( inside, "unterminated string array: "+name); - XML_FAIL( len != idx, "string array size mismatch: "+name); - - w = DVector<String>::Write(); - - r_v=sarray; - - } - } else if (type=="vector3_array") { - - int len=parser->get_attribute_value("len").to_int(); - - if (len>0) { - - XML_FAIL( parser->read()!=OK, "error reading" ); - XML_FAIL( parser->get_node_type()!=XMLParser::NODE_TEXT, "expected text!"); - String text = parser->get_node_data(); - - const CharType *c=text.c_str(); - DVector<Vector3> varray; - varray.resize(len); - DVector<Vector3>::Write w = varray.write(); - - int idx=0; - int sidx=0; - Vector3 v; - const CharType *from=c-1; - - while(*c) { - - bool ischar = IS_FLOAT_CHAR((*c)); - if (!ischar) { - - if (int64_t(c-from)>1) { - - real_t f = String::to_double(from+1,int64_t(c-from)); - v[sidx++]=f; - if (sidx==3) { - w[idx++]=v; - sidx=0; - - } - } - - from=c; - } else { - - XML_FAIL( idx >= len, "array too big"); - } - - c++; - } - - XML_FAIL( idx != len, "array size mismatch"); - - w = varray.write(); - r_v=varray; - } - - } else if (type=="color_array") { - - int len=parser->get_attribute_value("len").to_int(); - - if (len>0) { - - XML_FAIL( parser->read()!=OK, "error reading" ); - XML_FAIL( parser->get_node_type()!=XMLParser::NODE_TEXT, "expected text!"); - String text = parser->get_node_data(); - - const CharType *c=text.c_str(); - DVector<Color> carray; - carray.resize(len); - DVector<Color>::Write w = carray.write(); - - int idx=0; - int sidx=0; - Color v; - const CharType *from=c-1; - - while(*c) { - - bool ischar = IS_FLOAT_CHAR((*c)); - if (!ischar) { - - if (int64_t(c-from)>1) { - - real_t f = String::to_double(from+1,int64_t(c-from)); - v[sidx++]=f; - if (sidx==4) { - w[idx++]=v; - sidx=0; - - } - } - - from=c; - } else { - - XML_FAIL( idx >= len, "array too big"); - } - - c++; - } - - XML_FAIL( idx != len, "array size mismatch"); - - w = carray.write(); - r_v=carray; - } - } else { - // simple string parsing code - XML_FAIL( parser->read()!=OK, "can't read data" ); - - String data=parser->get_node_data(); - data=data.strip_edges(); - - if (type=="nil") { - // uh do nothing - - } else if (type=="bool") { - // uh do nothing - if (data.nocasecmp_to("true")==0 || data.to_int()!=0) - r_v=true; - else - r_v=false; - - } else if (type=="int") { - - r_v=data.to_int(); - } else if (type=="real") { - - r_v=data.to_double(); - } else if (type=="string") { - - String str=data; - str=str.substr(1,str.length()-2); - r_v=str; - } else if (type=="vector3") { - - r_v=Vector3( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double() - ); - - } else if (type=="vector2") { - - - r_v=Vector2( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double() - ); - - } else if (type=="plane") { - - r_v=Plane( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() - ); - - } else if (type=="quaternion") { - - r_v=Quat( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() - ); - - } else if (type=="rect2") { - - r_v=Rect2( - Vector2( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double() - ), - Vector2( - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() - ) - ); - - - } else if (type=="aabb") { - - r_v=AABB( - Vector3( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double() - ), - Vector3( - data.get_slice(",",3).to_double(), - data.get_slice(",",4).to_double(), - data.get_slice(",",5).to_double() - ) - ); - - - } else if (type=="matrix3") { - - Matrix3 m3; - for (int i=0;i<3;i++) { - for (int j=0;j<3;j++) { - m3.elements[i][j]=data.get_slice(",",i*3+j).to_double(); - } - } - r_v=m3; - - } else if (type=="transform") { - - Transform tr; - for (int i=0;i<3;i++) { - for (int j=0;j<3;j++) { - tr.basis.elements[i][j]=data.get_slice(",",i*3+j).to_double(); - } - - } - tr.origin=Vector3( - data.get_slice(",",9).to_double(), - data.get_slice(",",10).to_double(), - data.get_slice(",",11).to_double() - ); - r_v=tr; - - } else if (type=="color") { - - r_v=Color( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() - ); - - } else if (type=="node_path") { - - String str=data; - str=str.substr(1,str.length()-2); - r_v=NodePath( str ); - - } else if (type=="input_event") { - - // ? - } else { - - XML_FAIL(true,"unrecognized property tag: "+type); - } - } - - _close_tag(type); - - return OK; -} - - - - -Error ObjectFormatLoaderXML::_close_tag(const String& p_tag) { - - int c=1; - - while(parser->read()==OK) { - - - if (parser->get_node_type()==XMLParser::NODE_ELEMENT && parser->get_node_name()==p_tag) { - c++; - } else if (parser->get_node_type()==XMLParser::NODE_ELEMENT_END && parser->get_node_name()==p_tag) { - c--; - - if (c==0) - return OK; - } - - } - - return ERR_FILE_CORRUPT; -} - -Error ObjectFormatLoaderXML::load(Object **p_object,Variant &p_meta) { - - *p_object=NULL; - p_meta=Variant(); - - while(parser->read()==OK) { - - if (parser->get_node_type()==XMLParser::NODE_ELEMENT) { - - String name = parser->get_node_name(); - - - XML_FAIL( !parser->has_attribute("type"), "'type' attribute missing." ); - String type = parser->get_attribute_value("type"); - - - Object *obj=NULL; - Ref<Resource> resource; - if (name=="resource") { - - XML_FAIL( !parser->has_attribute("path"), "'path' attribute missing." ); - String path = parser->get_attribute_value("path"); - - XML_FAIL(!path.begins_with("local://"),"path does not begin with 'local://'"); - - - path=path.replace("local://",local_path+"::"); - - if (ResourceCache::has(path)) { - Error err = _close_tag(name); - XML_FAIL( err, "error skipping resource."); - continue; //it's a resource, and it's already loaded - - } - - obj = ObjectTypeDB::instance(type); - XML_FAIL(!obj,"couldn't instance object of type: '"+type+"'"); - - Resource *r = obj->cast_to<Resource>(); - XML_FAIL(!obj,"object isn't of type Resource: '"+type+"'"); - - resource = RES( r ); - r->set_path(path); - - - } else if (name=="object") { - - - if (ObjectTypeDB::can_instance(type)) { - obj = ObjectTypeDB::instance(type); - XML_FAIL(!obj,"couldn't instance object of type: '"+type+"'"); - } else { - - _close_tag(name); - return ERR_SKIP; - }; - } else { - XML_FAIL(true,"Unknown main tag: "+parser->get_node_name()); - } - - //load properties - - while (parser->read()==OK) { - - if (parser->get_node_type()==XMLParser::NODE_ELEMENT_END && parser->get_node_name()==name) - break; - else if (parser->get_node_type()==XMLParser::NODE_ELEMENT) { - - String name; - Variant v; - Error err; - err = _parse_property(v,name); - XML_FAIL(err,"Error parsing property: "+name); - - if (resource.is_null() && name=="__xml_meta__") { - - p_meta=v; - continue; - } else { - - XML_FAIL( !obj, "Normal property found in meta object"); - - } - - obj->set(name,v); - - - } - } - - - if (!obj) { - *p_object=NULL; - return OK; // it was a meta object - } - - if (resource.is_null()) { - //regular object - *p_object=obj; - return OK; - } else { - - resource_cache.push_back(resource); //keep it in mem until finished loading and load next - } - - - } else if (parser->get_node_type()==XMLParser::NODE_ELEMENT_END && parser->get_node_name()=="object_file") - return ERR_FILE_EOF; - } - - return OK; //never reach anyway -} - -ObjectFormatLoaderXML* ObjectFormatLoaderInstancerXML::instance(const String& p_file,const String& p_magic) { - - Ref<XMLParser> parser = memnew( XMLParser ); - - Error err = parser->open(p_file); - ERR_FAIL_COND_V(err,NULL); - - ObjectFormatLoaderXML *loader = memnew( ObjectFormatLoaderXML ); - - loader->parser=parser; - loader->local_path = Globals::get_singleton()->localize_path(p_file); - - while(parser->read()==OK) { - - if (parser->get_node_type()==XMLParser::NODE_ELEMENT && parser->get_node_name()=="object_file") { - - ERR_FAIL_COND_V( parser->is_empty(), NULL ); - - String version = parser->get_attribute_value_safe("version"); - String magic = parser->get_attribute_value_safe("MAGIC"); - - if (version.get_slice_count(".")!=2) { - - ERR_EXPLAIN("Invalid Version String '"+version+"'' in file: "+p_file); - ERR_FAIL_V(NULL); - } - - int major = version.get_slice(".",0).to_int(); - int minor = version.get_slice(".",1).to_int(); - - if (major>VERSION_MAJOR || (major==VERSION_MAJOR && minor>VERSION_MINOR)) { - - ERR_EXPLAIN("File Format '"+version+"' is too new! Please upgrade to a a new engine version: "+p_file); - ERR_FAIL_V(NULL); - - } - - return loader; - } - - } - - ERR_EXPLAIN("No data found in file!"); - ERR_FAIL_V(NULL); -} - -void ObjectFormatLoaderInstancerXML::get_recognized_extensions(List<String> *p_extensions) const { - - p_extensions->push_back("xml"); -} - - - -#else - -ObjectFormatLoaderXML::Tag* ObjectFormatLoaderXML::parse_tag(bool *r_exit) { - - - while(get_char()!='<' && !f->eof_reached()) {} - if (f->eof_reached()) - return NULL; - - Tag tag; - bool exit=false; - if (r_exit) - *r_exit=false; - - bool complete=false; - while(!f->eof_reached()) { - - CharType c=get_char(); - if (c<33 && tag.name.length() && !exit) { - break; - } else if (c=='>') { - complete=true; - break; - } else if (c=='/') { - exit=true; - } else { - tag.name+=c; - } - } - - if (f->eof_reached()) - return NULL; - - if (exit) { - if (!tag_stack.size()) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Unmatched exit tag </"+tag.name+">"); - ERR_FAIL_COND_V(!tag_stack.size(),NULL); - } - - if (tag_stack.back()->get().name!=tag.name) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Mismatched exit tag. Got </"+tag.name+">, expected </"+tag_stack.back()->get().name+">"); - ERR_FAIL_COND_V(tag_stack.back()->get().name!=tag.name,NULL); - } - - if (!complete) { - while(get_char()!='>' && !f->eof_reached()) {} - if (f->eof_reached()) - return NULL; - } - - if (r_exit) - *r_exit=true; - - tag_stack.pop_back(); - return NULL; - - } - - if (!complete) { - String name; - String value; - bool reading_value=false; - - while(!f->eof_reached()) { - - CharType c=get_char(); - if (c=='>') { - if (value.length()) { - - tag.args[name]=value; - } - break; - - } else if ( ((!reading_value && (c<33)) || c=='=' || c=='"') && tag.name.length()) { - - if (!reading_value && name.length()) { - - reading_value=true; - } else if (reading_value && value.length()) { - - tag.args[name]=value; - name=""; - value=""; - reading_value=false; - } - - } else if (reading_value) { - - value+=c; - } else { - - name+=c; - } - } - - if (f->eof_reached()) - return NULL; - } - - tag_stack.push_back(tag); - - return &tag_stack.back()->get(); -} - - -Error ObjectFormatLoaderXML::close_tag(const String& p_name) { - - int level=0; - bool inside_tag=false; - - while(true) { - - if (f->eof_reached()) { - - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": EOF found while attempting to find </"+p_name+">"); - ERR_FAIL_COND_V( f->eof_reached(), ERR_FILE_CORRUPT ); - } - - uint8_t c = get_char(); - - if (c == '<') { - - if (inside_tag) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Malformed XML. Already inside Tag."); - ERR_FAIL_COND_V(inside_tag,ERR_FILE_CORRUPT); - } - inside_tag=true; - c = get_char(); - if (c == '/') { - - --level; - } else { - - ++level; - }; - } else if (c == '>') { - - if (!inside_tag) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Malformed XML. Already outside Tag"); - ERR_FAIL_COND_V(!inside_tag,ERR_FILE_CORRUPT); - } - inside_tag=false; - if (level == -1) { - tag_stack.pop_back(); - return OK; - }; - }; - } - - return OK; -} - -void ObjectFormatLoaderXML::unquote(String& p_str) { - - p_str=p_str.strip_edges(); - p_str=p_str.replace("\"",""); - p_str=p_str.replace(">","<"); - p_str=p_str.replace("<",">"); - p_str=p_str.replace("'","'"); - p_str=p_str.replace(""","\""); - for (int i=1;i<32;i++) { - - char chr[2]={i,0}; - p_str=p_str.replace("&#"+String::num(i)+";",chr); - } - p_str=p_str.replace("&","&"); - - //p_str.parse_utf8( p_str.ascii(true).get_data() ); - -} - -Error ObjectFormatLoaderXML::goto_end_of_tag() { - - uint8_t c; - while(true) { - - c=get_char(); - if (c=='>') //closetag - break; - if (f->eof_reached()) { - - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": EOF found while attempting to find close tag."); - ERR_FAIL_COND_V( f->eof_reached(), ERR_FILE_CORRUPT ); - } - - } - tag_stack.pop_back(); - - return OK; -} - - -Error ObjectFormatLoaderXML::parse_property_data(String &r_data) { - - r_data=""; - CharString cs; - while(true) { - - CharType c=get_char(); - if (c=='<') - break; - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - cs.push_back(c); - } - - cs.push_back(0); - - r_data.parse_utf8(cs.get_data()); - - while(get_char()!='>' && !f->eof_reached()) {} - if (f->eof_reached()) { - - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Malformed XML."); - ERR_FAIL_COND_V( f->eof_reached(), ERR_FILE_CORRUPT ); - } - - r_data=r_data.strip_edges(); - tag_stack.pop_back(); - - return OK; -} - - -Error ObjectFormatLoaderXML::_parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end) { - - if (buff.empty()) - buff.resize(32); // optimize - - int buff_max=buff.size(); - int buff_size=0; - *end=false; - char *buffptr=&buff[0]; - bool found=false; - bool quoted=false; - - while(true) { - - char c=get_char(); - - if (c==0) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": File corrupt (zero found)."); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } else if (c=='"') { - quoted=!quoted; - } else if ((!quoted && ((p_number_only && c<33) || c==',')) || c=='<') { - - - if (c=='<') { - *end=true; - break; - } - if (c<32 && f->eof_reached()) { - *end=true; - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": File corrupt (unexpected EOF)."); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - - if (found) - break; - - } else { - - found=true; - if (buff_size>=buff_max) { - - buff_max++; - buff.resize(buff_max); - - } - - buffptr[buff_size]=c; - buff_size++; - } - } - - if (buff_size>=buff_max) { - - buff_max++; - buff.resize(buff_max); - - } - - buff[buff_size]=0; - buff_size++; - - return OK; -} - -Error ObjectFormatLoaderXML::parse_property(Variant& r_v, String &r_name) { - - bool exit; - Tag *tag = parse_tag(&exit); - - if (!tag) { - if (exit) // shouldn't have exited - return ERR_FILE_EOF; - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": File corrupt (No Property Tag)."); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - - r_v=Variant(); - r_name=""; - - - //ERR_FAIL_COND_V(tag->name!="property",ERR_FILE_CORRUPT); - //ERR_FAIL_COND_V(!tag->args.has("name"),ERR_FILE_CORRUPT); -// ERR_FAIL_COND_V(!tag->args.has("type"),ERR_FILE_CORRUPT); - - //String name=tag->args["name"]; - //ERR_FAIL_COND_V(name=="",ERR_FILE_CORRUPT); - String type=tag->name; - String name=tag->args["name"]; - - if (type=="") { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": 'type' field is empty."); - ERR_FAIL_COND_V(type=="",ERR_FILE_CORRUPT); - } - - if (type=="dictionary") { - - Dictionary d; - - while(true) { - - Error err; - String tagname; - Variant key; - - int dictline = get_current_line(); - - - err=parse_property(key,tagname); - - if (err && err!=ERR_FILE_EOF) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error parsing dictionary: "+name+" (from line "+itos(dictline)+")"); - ERR_FAIL_COND_V(err && err!=ERR_FILE_EOF,err); - } - //ERR_FAIL_COND_V(tagname!="key",ERR_FILE_CORRUPT); - if (err) - break; - Variant value; - err=parse_property(value,tagname); - if (err) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error parsing dictionary: "+name+" (from line "+itos(dictline)+")"); - } - - ERR_FAIL_COND_V(err,err); - //ERR_FAIL_COND_V(tagname!="value",ERR_FILE_CORRUPT); - - d[key]=value; - } - - - //err=parse_property_data(name); // skip the rest - //ERR_FAIL_COND_V(err,err); - - r_name=name; - r_v=d; - return OK; - - } else if (type=="array") { - - if (!tag->args.has("len")) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Array missing 'len' field: "+name); - ERR_FAIL_COND_V(!tag->args.has("len"),ERR_FILE_CORRUPT); - } - - - int len=tag->args["len"].to_int(); - - Array array; - array.resize(len); - - Error err; - Variant v; - String tagname; - int idx=0; - while( (err=parse_property(v,tagname))==OK ) { - - ERR_CONTINUE( idx <0 || idx >=len ); - - array.set(idx,v); - idx++; - } - - if (idx!=len) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error loading array (size mismatch): "+name); - ERR_FAIL_COND_V(idx!=len,err); - } - - if (err!=ERR_FILE_EOF) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error loading array: "+name); - ERR_FAIL_COND_V(err!=ERR_FILE_EOF,err); - } - - //err=parse_property_data(name); // skip the rest - //ERR_FAIL_COND_V(err,err); - - r_name=name; - r_v=array; - return OK; - - } else if (type=="resource") { - - if (tag->args.has("path")) { - - String path=tag->args["path"]; - String hint; - if (tag->args.has("resource_type")) - hint=tag->args["resource_type"]; - - if (path.begins_with("local://")) - path=path.replace("local://",local_path+"::"); - else if (path.find("://")==-1 && path.is_rel_path()) { - // path is relative to file being loaded, so convert to a resource path - path=Globals::get_singleton()->localize_path(local_path.get_base_dir()+"/"+path); - - } - - //take advantage of the resource loader cache. The resource is cached on it, even if - RES res=ResourceLoader::load(path,hint); - - - if (res.is_null()) { - - WARN_PRINT(String("Couldn't load resource: "+path).ascii().get_data()); - } - - r_v=res.get_ref_ptr(); - } - - - - Error err=goto_end_of_tag(); - if (err) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error closing <resource> tag."); - ERR_FAIL_COND_V(err,err); - } - - - r_name=name; - - return OK; - - } else if (type=="image") { - - if (!tag->args.has("encoding")) { - //empty image - r_v=Image(); - String sdfsdfg; - Error err=parse_property_data(sdfsdfg); - return OK; - } - - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Image missing 'encoding' field."); - ERR_FAIL_COND_V( !tag->args.has("encoding"), ERR_FILE_CORRUPT ); - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Image missing 'width' field."); - ERR_FAIL_COND_V( !tag->args.has("width"), ERR_FILE_CORRUPT ); - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Image missing 'height' field."); - ERR_FAIL_COND_V( !tag->args.has("height"), ERR_FILE_CORRUPT ); - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Image missing 'format' field."); - ERR_FAIL_COND_V( !tag->args.has("format"), ERR_FILE_CORRUPT ); - - String encoding=tag->args["encoding"]; - - if (encoding=="raw") { - String width=tag->args["width"]; - String height=tag->args["height"]; - String format=tag->args["format"]; - int mipmaps=tag->args.has("mipmaps")?int(tag->args["mipmaps"].to_int()):int(0); - int custom_size = tag->args.has("custom_size")?int(tag->args["custom_size"].to_int()):int(0); - - r_name=name; - - Image::Format imgformat; - - - if (format=="grayscale") { - imgformat=Image::FORMAT_GRAYSCALE; - } else if (format=="intensity") { - imgformat=Image::FORMAT_INTENSITY; - } else if (format=="grayscale_alpha") { - imgformat=Image::FORMAT_GRAYSCALE_ALPHA; - } else if (format=="rgb") { - imgformat=Image::FORMAT_RGB; - } else if (format=="rgba") { - imgformat=Image::FORMAT_RGBA; - } else if (format=="indexed") { - imgformat=Image::FORMAT_INDEXED; - } else if (format=="indexed_alpha") { - imgformat=Image::FORMAT_INDEXED_ALPHA; - } else if (format=="bc1") { - imgformat=Image::FORMAT_BC1; - } else if (format=="bc2") { - imgformat=Image::FORMAT_BC2; - } else if (format=="bc3") { - imgformat=Image::FORMAT_BC3; - } else if (format=="bc4") { - imgformat=Image::FORMAT_BC4; - } else if (format=="bc5") { - imgformat=Image::FORMAT_BC5; - } else if (format=="custom") { - imgformat=Image::FORMAT_CUSTOM; - } else { - - ERR_FAIL_V( ERR_FILE_CORRUPT ); - } - - - int datasize; - int w=width.to_int(); - int h=height.to_int(); - - if (w == 0 && w == 0) { - //r_v = Image(w, h, imgformat); - r_v=Image(); - String sdfsdfg; - Error err=parse_property_data(sdfsdfg); - return OK; - }; - - if (imgformat==Image::FORMAT_CUSTOM) { - - datasize=custom_size; - } else { - - datasize = Image::get_image_data_size(h,w,imgformat,mipmaps); - } - - if (datasize==0) { - //r_v = Image(w, h, imgformat); - r_v=Image(); - String sdfsdfg; - Error err=parse_property_data(sdfsdfg); - return OK; - }; - - DVector<uint8_t> pixels; - pixels.resize(datasize); - DVector<uint8_t>::Write wb = pixels.write(); - - int idx=0; - uint8_t byte; - while( idx<datasize*2) { - - CharType c=get_char(); - - ERR_FAIL_COND_V(c=='<',ERR_FILE_CORRUPT); - - if ( (c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f') ) { - - if (idx&1) { - - byte|=HEX2CHR(c); - wb[idx>>1]=byte; - } else { - - byte=HEX2CHR(c)<<4; - } - - idx++; - } - - } - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - - wb=DVector<uint8_t>::Write(); - - r_v=Image(w,h,mipmaps,imgformat,pixels); - String sdfsdfg; - Error err=parse_property_data(sdfsdfg); - ERR_FAIL_COND_V(err,err); - - return OK; - } - - ERR_FAIL_V(ERR_FILE_CORRUPT); - - } else if (type=="raw_array") { - - if (!tag->args.has("len")) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": RawArray missing 'len' field: "+name); - ERR_FAIL_COND_V(!tag->args.has("len"),ERR_FILE_CORRUPT); - } - int len=tag->args["len"].to_int(); - - DVector<uint8_t> bytes; - bytes.resize(len); - DVector<uint8_t>::Write w=bytes.write(); - uint8_t *bytesptr=w.ptr(); - int idx=0; - uint8_t byte; - while( idx<len*2) { - - CharType c=get_char(); - - if (idx&1) { - - byte|=HEX2CHR(c); - bytesptr[idx>>1]=byte; - } else { - - byte=HEX2CHR(c)<<4; - } - - idx++; - } - - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - - w=DVector<uint8_t>::Write(); - r_v=bytes; - String sdfsdfg; - Error err=parse_property_data(sdfsdfg); - ERR_FAIL_COND_V(err,err); - r_name=name; - - return OK; - - } else if (type=="int_array") { - - if (!tag->args.has("len")) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Array missing 'len' field: "+name); - ERR_FAIL_COND_V(!tag->args.has("len"),ERR_FILE_CORRUPT); - } - int len=tag->args["len"].to_int(); - - DVector<int> ints; - ints.resize(len); - DVector<int>::Write w=ints.write(); - int *intsptr=w.ptr(); - int idx=0; - String str; -#if 0 - while( idx<len ) { - - - CharType c=get_char(); - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - - if (c<33 || c==',' || c=='<') { - - if (str.length()) { - - intsptr[idx]=str.to_int(); - str=""; - idx++; - } - - if (c=='<') { - - while(get_char()!='>' && !f->eof_reached()) {} - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - break; - } - - } else { - - str+=c; - } - } - -#else - - Vector<char> tmpdata; - - while( idx<len ) { - - bool end=false; - Error err = _parse_array_element(tmpdata,true,f,&end); - ERR_FAIL_COND_V(err,err); - - intsptr[idx]=String::to_int(&tmpdata[0]); - idx++; - if (end) - break; - - } - -#endif - w=DVector<int>::Write(); - - r_v=ints; - Error err=goto_end_of_tag(); - ERR_FAIL_COND_V(err,err); - r_name=name; - - return OK; - } else if (type=="real_array") { - - if (!tag->args.has("len")) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Array missing 'len' field: "+name); - ERR_FAIL_COND_V(!tag->args.has("len"),ERR_FILE_CORRUPT); - } - int len=tag->args["len"].to_int();; - - DVector<real_t> reals; - reals.resize(len); - DVector<real_t>::Write w=reals.write(); - real_t *realsptr=w.ptr(); - int idx=0; - String str; - - -#if 0 - while( idx<len ) { - - - CharType c=get_char(); - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - - - if (c<33 || c==',' || c=='<') { - - if (str.length()) { - - realsptr[idx]=str.to_double(); - str=""; - idx++; - } - - if (c=='<') { - - while(get_char()!='>' && !f->eof_reached()) {} - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - break; - } - - } else { - - str+=c; - } - } - -#else - - - - Vector<char> tmpdata; - - while( idx<len ) { - - bool end=false; - Error err = _parse_array_element(tmpdata,true,f,&end); - ERR_FAIL_COND_V(err,err); - - realsptr[idx]=String::to_double(&tmpdata[0]); - idx++; - - if (end) - break; - } - -#endif - - w=DVector<real_t>::Write(); - r_v=reals; - - Error err=goto_end_of_tag(); - ERR_FAIL_COND_V(err,err); - r_name=name; - - return OK; - } else if (type=="string_array") { - - if (!tag->args.has("len")) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Array missing 'len' field: "+name); - ERR_FAIL_COND_V(!tag->args.has("len"),ERR_FILE_CORRUPT); - } - int len=tag->args["len"].to_int(); - - DVector<String> strings; - strings.resize(len); - DVector<String>::Write w=strings.write(); - String *stringsptr=w.ptr(); - int idx=0; - String str; - - bool inside_str=false; - CharString cs; - while( idx<len ) { - - - CharType c=get_char(); - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - - - if (c=='"') { - if (inside_str) { - - cs.push_back(0); - String str; - str.parse_utf8(cs.get_data()); - unquote(str); - stringsptr[idx]=str; - cs.clear(); - idx++; - inside_str=false; - } else { - inside_str=true; - } - } else if (c=='<') { - - while(get_char()!='>' && !f->eof_reached()) {} - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - break; - - - } else if (inside_str){ - - cs.push_back(c); - } - } - w=DVector<String>::Write(); - r_v=strings; - String sdfsdfg; - Error err=parse_property_data(sdfsdfg); - ERR_FAIL_COND_V(err,err); - - r_name=name; - - return OK; - } else if (type=="vector3_array") { - - if (!tag->args.has("len")) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Array missing 'len' field: "+name); - ERR_FAIL_COND_V(!tag->args.has("len"),ERR_FILE_CORRUPT); - } - int len=tag->args["len"].to_int();; - - DVector<Vector3> vectors; - vectors.resize(len); - DVector<Vector3>::Write w=vectors.write(); - Vector3 *vectorsptr=w.ptr(); - int idx=0; - int subidx=0; - Vector3 auxvec; - String str; - -// uint64_t tbegin = OS::get_singleton()->get_ticks_usec(); -#if 0 - while( idx<len ) { - - - CharType c=get_char(); - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - - - if (c<33 || c==',' || c=='<') { - - if (str.length()) { - - auxvec[subidx]=str.to_double(); - subidx++; - str=""; - if (subidx==3) { - vectorsptr[idx]=auxvec; - - idx++; - subidx=0; - } - } - - if (c=='<') { - - while(get_char()!='>' && !f->eof_reached()) {} - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - break; - } - - } else { - - str+=c; - } - } -#else - - Vector<char> tmpdata; - - while( idx<len ) { - - bool end=false; - Error err = _parse_array_element(tmpdata,true,f,&end); - ERR_FAIL_COND_V(err,err); - - - auxvec[subidx]=String::to_double(&tmpdata[0]); - subidx++; - if (subidx==3) { - vectorsptr[idx]=auxvec; - - idx++; - subidx=0; - } - - if (end) - break; - } - - - -#endif - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Premature end of vector3 array"); - ERR_FAIL_COND_V(idx<len,ERR_FILE_CORRUPT); -// double time_taken = (OS::get_singleton()->get_ticks_usec() - tbegin)/1000000.0; - - - w=DVector<Vector3>::Write(); - r_v=vectors; - String sdfsdfg; - Error err=goto_end_of_tag(); - ERR_FAIL_COND_V(err,err); - r_name=name; - - return OK; - - } else if (type=="vector2_array") { - - if (!tag->args.has("len")) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Array missing 'len' field: "+name); - ERR_FAIL_COND_V(!tag->args.has("len"),ERR_FILE_CORRUPT); - } - int len=tag->args["len"].to_int();; - - DVector<Vector2> vectors; - vectors.resize(len); - DVector<Vector2>::Write w=vectors.write(); - Vector2 *vectorsptr=w.ptr(); - int idx=0; - int subidx=0; - Vector2 auxvec; - String str; - -// uint64_t tbegin = OS::get_singleton()->get_ticks_usec(); -#if 0 - while( idx<len ) { - - - CharType c=get_char(); - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - - - if (c<22 || c==',' || c=='<') { - - if (str.length()) { - - auxvec[subidx]=str.to_double(); - subidx++; - str=""; - if (subidx==2) { - vectorsptr[idx]=auxvec; - - idx++; - subidx=0; - } - } - - if (c=='<') { - - while(get_char()!='>' && !f->eof_reached()) {} - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - break; - } - - } else { - - str+=c; - } - } -#else - - Vector<char> tmpdata; - - while( idx<len ) { - - bool end=false; - Error err = _parse_array_element(tmpdata,true,f,&end); - ERR_FAIL_COND_V(err,err); - - - auxvec[subidx]=String::to_double(&tmpdata[0]); - subidx++; - if (subidx==2) { - vectorsptr[idx]=auxvec; - - idx++; - subidx=0; - } - - if (end) - break; - } - - - -#endif - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Premature end of vector2 array"); - ERR_FAIL_COND_V(idx<len,ERR_FILE_CORRUPT); -// double time_taken = (OS::get_singleton()->get_ticks_usec() - tbegin)/1000000.0; - - - w=DVector<Vector2>::Write(); - r_v=vectors; - String sdfsdfg; - Error err=goto_end_of_tag(); - ERR_FAIL_COND_V(err,err); - r_name=name; - - return OK; - - } else if (type=="color_array") { - - if (!tag->args.has("len")) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Array missing 'len' field: "+name); - ERR_FAIL_COND_V(!tag->args.has("len"),ERR_FILE_CORRUPT); - } - int len=tag->args["len"].to_int();; - - DVector<Color> colors; - colors.resize(len); - DVector<Color>::Write w=colors.write(); - Color *colorsptr=w.ptr(); - int idx=0; - int subidx=0; - Color auxcol; - String str; - - while( idx<len ) { - - - CharType c=get_char(); - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - - - if (c<33 || c==',' || c=='<') { - - if (str.length()) { - - auxcol[subidx]=str.to_double(); - subidx++; - str=""; - if (subidx==4) { - colorsptr[idx]=auxcol; - idx++; - subidx=0; - } - } - - if (c=='<') { - - while(get_char()!='>' && !f->eof_reached()) {} - ERR_FAIL_COND_V(f->eof_reached(),ERR_FILE_CORRUPT); - break; - } - - } else { - - str+=c; - } - } - w=DVector<Color>::Write(); - r_v=colors; - String sdfsdfg; - Error err=parse_property_data(sdfsdfg); - ERR_FAIL_COND_V(err,err); - r_name=name; - - return OK; - } - - - String data; - Error err = parse_property_data(data); - ERR_FAIL_COND_V(err!=OK,err); - - if (type=="nil") { - // uh do nothing - - } else if (type=="bool") { - // uh do nothing - if (data.nocasecmp_to("true")==0 || data.to_int()!=0) - r_v=true; - else - r_v=false; - } else if (type=="int") { - - r_v=data.to_int(); - } else if (type=="real") { - - r_v=data.to_double(); - } else if (type=="string") { - - String str=data; - unquote(str); - r_v=str; - } else if (type=="vector3") { - - - r_v=Vector3( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double() - ); - - } else if (type=="vector2") { - - - r_v=Vector2( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double() - ); - - } else if (type=="plane") { - - r_v=Plane( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() - ); - - } else if (type=="quaternion") { - - r_v=Quat( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() - ); - - } else if (type=="rect2") { - - r_v=Rect2( - Vector2( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double() - ), - Vector2( - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() - ) - ); - - - } else if (type=="aabb") { - - r_v=AABB( - Vector3( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double() - ), - Vector3( - data.get_slice(",",3).to_double(), - data.get_slice(",",4).to_double(), - data.get_slice(",",5).to_double() - ) - ); - - } else if (type=="matrix32") { - - Matrix32 m3; - for (int i=0;i<3;i++) { - for (int j=0;j<2;j++) { - m3.elements[i][j]=data.get_slice(",",i*2+j).to_double(); - } - } - r_v=m3; - - } else if (type=="matrix3") { - - Matrix3 m3; - for (int i=0;i<3;i++) { - for (int j=0;j<3;j++) { - m3.elements[i][j]=data.get_slice(",",i*3+j).to_double(); - } - } - r_v=m3; - - } else if (type=="transform") { - - Transform tr; - for (int i=0;i<3;i++) { - for (int j=0;j<3;j++) { - tr.basis.elements[i][j]=data.get_slice(",",i*3+j).to_double(); - } - - } - tr.origin=Vector3( - data.get_slice(",",9).to_double(), - data.get_slice(",",10).to_double(), - data.get_slice(",",11).to_double() - ); - r_v=tr; - - } else if (type=="color") { - - r_v=Color( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() - ); - - } else if (type=="node_path") { - - String str=data; - unquote(str); - r_v=NodePath( str ); - } else if (type=="input_event") { - - // ? - } else { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Unrecognized tag in file: "+type); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - r_name=name; - return OK; -} - - -Error ObjectFormatLoaderXML::load(Object **p_object,Variant &p_meta) { - - *p_object=NULL; - p_meta=Variant(); - - - - while(true) { - - - bool exit; - Tag *tag = parse_tag(&exit); - - - if (!tag) { - if (!exit) // shouldn't have exited - ERR_FAIL_V(ERR_FILE_CORRUPT); - *p_object=NULL; - return ERR_FILE_EOF; - } - - RES resource; - Object *obj=NULL; - - if (tag->name=="resource") { - //loading resource - - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'len' field."); - ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT); - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'type' field."); - ERR_FAIL_COND_V(!tag->args.has("type"),ERR_FILE_CORRUPT); - String path=tag->args["path"]; - - if (path.begins_with("local://")) { - //built-in resource (but really external) - path=path.replace("local://",local_path+"::"); - } - - - if (ResourceCache::has(path)) { - Error err = close_tag(tag->name); - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Unable to close <resource> tag."); - ERR_FAIL_COND_V( err, err ); - continue; //it's a resource, and it's already loaded - - } - - String type = tag->args["type"]; - - obj = ObjectTypeDB::instance(type); - if (!obj) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Object of unrecognized type in file: "+type); - } - ERR_FAIL_COND_V(!obj,ERR_FILE_CORRUPT); - - Resource *r = obj->cast_to<Resource>(); - if (!r) { - memdelete(obj); //bye - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Object type in resource field not a resource, type is: "+obj->get_type()); - ERR_FAIL_COND_V(!obj->cast_to<Resource>(),ERR_FILE_CORRUPT); - } - - resource = RES( r ); - r->set_path(path); - - - - } else if (tag->name=="object") { - - if ( tag->args.has("type") ) { - - ERR_FAIL_COND_V(!ObjectTypeDB::type_exists(tag->args["type"]), ERR_FILE_CORRUPT); - - if (ObjectTypeDB::can_instance(tag->args["type"])) { - obj = ObjectTypeDB::instance(tag->args["type"]); - if (!obj) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Object of unrecognized type in file: "+tag->args["type"]); - } - ERR_FAIL_COND_V(!obj,ERR_FILE_CORRUPT); - } else { - - close_tag(tag->name); - return ERR_SKIP; - }; - } else { - //otherwise it's a meta object - } - - } else { - - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Unknown main tag: "+tag->name); - ERR_FAIL_V( ERR_FILE_CORRUPT ); - } - - //load properties - - while(true) { - - String name; - Variant v; - Error err; - err = parse_property(v,name); - if (err==ERR_FILE_EOF) //tag closed - break; - if (err!=OK) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": XML Parsing aborted."); - ERR_FAIL_COND_V(err!=OK,ERR_FILE_CORRUPT); - } - if (resource.is_null() && name=="__xml_meta__") { - - p_meta=v; - continue; - } else if (!obj) { - - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Normal property found in meta object."); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - - obj->set(name,v); - } - - if (!obj) { - *p_object=NULL; - return OK; // it was a meta object - } - - if (resource.is_null()) { - - //regular object - *p_object=obj; - return OK; - } else { - - - resource_cache.push_back(resource); //keep it in mem until finished loading - } - - // a resource.. continue! - - } - - - - return OK; //never reach anyway - -} - -int ObjectFormatLoaderXML::get_current_line() const { - - return lines; -} - - -uint8_t ObjectFormatLoaderXML::get_char() const { - - uint8_t c = f->get_8(); - if (c=='\n') - lines++; - return c; - -} - -ObjectFormatLoaderXML::~ObjectFormatLoaderXML() { - - if (f) { - if (f->is_open()) - f->close(); - memdelete(f); - } -} - - - -ObjectFormatLoaderXML* ObjectFormatLoaderInstancerXML::instance(const String& p_file,const String& p_magic) { - - Error err; - FileAccess *f=FileAccess::open(p_file,FileAccess::READ,&err); - if (err!=OK) { - - ERR_FAIL_COND_V(err!=OK,NULL); - } - - ObjectFormatLoaderXML *loader = memnew( ObjectFormatLoaderXML ); - - loader->lines=1; - loader->f=f; - loader->local_path = Globals::get_singleton()->localize_path(p_file); - - ObjectFormatLoaderXML::Tag *tag = loader->parse_tag(); - if (!tag || tag->name!="?xml" || !tag->args.has("version") || !tag->args.has("encoding") || tag->args["encoding"]!="UTF-8") { - - f->close(); - memdelete(loader); - ERR_EXPLAIN("Not a XML:UTF-8 File: "+p_file); - ERR_FAIL_V(NULL); - } - - loader->tag_stack.clear(); - - tag = loader->parse_tag(); - - if (!tag || tag->name!="object_file" || !tag->args.has("magic") || !tag->args.has("version") || tag->args["magic"]!=p_magic) { - - f->close(); - memdelete(loader); - ERR_EXPLAIN("Unrecognized XML File: "+p_file); - ERR_FAIL_V(NULL); - } - - String version = tag->args["version"]; - if (version.get_slice_count(".")!=2) { - - f->close(); - memdelete(loader); - ERR_EXPLAIN("Invalid Version String '"+version+"'' in file: "+p_file); - ERR_FAIL_V(NULL); - } - - int major = version.get_slice(".",0).to_int(); - int minor = version.get_slice(".",1).to_int(); - - if (major>VERSION_MAJOR || (major==VERSION_MAJOR && minor>VERSION_MINOR)) { - - f->close(); - memdelete(loader); - ERR_EXPLAIN("File Format '"+version+"' is too new! Please upgrade to a a new engine version: "+p_file); - ERR_FAIL_V(NULL); - - } - - return loader; -} - -void ObjectFormatLoaderInstancerXML::get_recognized_extensions(List<String> *p_extensions) const { - - p_extensions->push_back("xml"); -} - - -#endif -#endif -#endif diff --git a/core/io/object_format_xml.h b/core/io/object_format_xml.h deleted file mode 100644 index 1169a1de58..0000000000 --- a/core/io/object_format_xml.h +++ /dev/null @@ -1,196 +0,0 @@ -/*************************************************************************/ -/* object_format_xml.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef OBJECT_FORMAT_XML_H -#define OBJECT_FORMAT_XML_H - -#ifdef XML_ENABLED -#ifdef OLD_SCENE_FORMAT_ENABLED -#include "io/object_loader.h" -#include "io/object_saver.h" -#include "os/file_access.h" -#include "map.h" -#include "resource.h" -#include "xml_parser.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class ObjectFormatSaverXML : public ObjectFormatSaver { - - String local_path; - - - Ref<OptimizedSaver> optimizer; - - bool relative_paths; - bool bundle_resources; - bool skip_editor; - FileAccess *f; - String magic; - int depth; - Map<RES,int> resource_map; - - struct SavedObject { - - Variant meta; - String type; - - - struct SavedProperty { - - String name; - Variant value; - }; - - List<SavedProperty> properties; - }; - - List<RES> saved_resources; - - List<SavedObject*> saved_objects; - - void enter_tag(const String& p_section,const String& p_args=""); - void exit_tag(const String& p_section); - - void _find_resources(const Variant& p_variant); - void write_property(const String& p_name,const Variant& p_property,bool *r_ok=NULL); - - - void escape(String& p_str); - void write_tabs(int p_diff=0); - void write_string(String p_str,bool p_escape=true); - -public: - - virtual Error save(const Object *p_object,const Variant &p_meta); - - ObjectFormatSaverXML(FileAccess *p_file,const String& p_magic,const String& p_local_path,uint32_t p_flags,const Ref<OptimizedSaver>& p_optimizer); - ~ObjectFormatSaverXML(); -}; - -class ObjectFormatSaverInstancerXML : public ObjectFormatSaverInstancer { -public: - - virtual ObjectFormatSaver* instance(const String& p_file,const String& p_magic,uint32_t p_flags=0,const Ref<OptimizedSaver>& p_optimizer=Ref<OptimizedSaver>()); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - - virtual ~ObjectFormatSaverInstancerXML(); -}; - -/***********************************/ -/***********************************/ -/***********************************/ -/***********************************/ - -//#define OPTIMIZED_XML_LOADER - -#ifdef OPTIMIZED_XML_LOADER - -class ObjectFormatLoaderXML : public ObjectFormatLoader { - - Ref<XMLParser> parser; - String local_path; - - Error _close_tag(const String& p_tag); - Error _parse_property(Variant& r_property,String& r_name); - -friend class ObjectFormatLoaderInstancerXML; - - List<RES> resource_cache; -public: - - - virtual Error load(Object **p_object,Variant &p_meta); - - -}; - -class ObjectFormatLoaderInstancerXML : public ObjectFormatLoaderInstancer { -public: - - virtual ObjectFormatLoaderXML* instance(const String& p_file,const String& p_magic); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - -}; - -#else - - -class ObjectFormatLoaderXML : public ObjectFormatLoader { - - String local_path; - - FileAccess *f; - - struct Tag { - - String name; - HashMap<String,String> args; - }; - - _FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end); - - mutable int lines; - uint8_t get_char() const; - int get_current_line() const; - -friend class ObjectFormatLoaderInstancerXML; - List<Tag> tag_stack; - - List<RES> resource_cache; - Tag* parse_tag(bool* r_exit=NULL); - Error close_tag(const String& p_name); - void unquote(String& p_str); - Error goto_end_of_tag(); - Error parse_property_data(String &r_data); - Error parse_property(Variant& r_v, String &r_name); - -public: - - - virtual Error load(Object **p_object,Variant &p_meta); - - virtual ~ObjectFormatLoaderXML(); -}; - -class ObjectFormatLoaderInstancerXML : public ObjectFormatLoaderInstancer { -public: - - virtual ObjectFormatLoaderXML* instance(const String& p_file,const String& p_magic); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - - - -}; - -#endif -#endif -#endif -#endif diff --git a/core/io/object_loader.cpp b/core/io/object_loader.cpp deleted file mode 100644 index bb42cf7338..0000000000 --- a/core/io/object_loader.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************/ -/* object_loader.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "object_loader.h" - -#ifdef OLD_SCENE_FORMAT_ENABLED - -bool ObjectFormatLoaderInstancer::recognize(const String& p_extension) const { - - - List<String> extensions; - get_recognized_extensions(&extensions); - for (List<String>::Element *E=extensions.front();E;E=E->next()) { - - if (E->get().nocasecmp_to(p_extension)==0) - return true; - } - - return false; -} - -ObjectFormatLoaderInstancer *ObjectLoader::loader[MAX_LOADERS]; -int ObjectLoader::loader_count=0; - - -ObjectFormatLoader *ObjectLoader::instance_format_loader(const String& p_path,const String& p_magic,String p_force_extension) { - - String extension=p_force_extension.length()?p_force_extension:p_path.extension(); - - for (int i=0;i<loader_count;i++) { - - if (!loader[i]->recognize(extension)) - continue; - ObjectFormatLoader *format_loader = loader[i]->instance(p_path,p_magic); - if (format_loader) - return format_loader; - } - - return NULL; -} - -void ObjectLoader::get_recognized_extensions(List<String> *p_extensions) { - - for (int i=0;i<loader_count;i++) { - - loader[i]->get_recognized_extensions(p_extensions); - } -} - - - -void ObjectLoader::add_object_format_loader_instancer(ObjectFormatLoaderInstancer *p_format_loader_instancer) { - - ERR_FAIL_COND(loader_count>=MAX_LOADERS ); - loader[loader_count++]=p_format_loader_instancer; -} - - -#endif diff --git a/core/io/object_loader.h b/core/io/object_loader.h deleted file mode 100644 index 9199313f04..0000000000 --- a/core/io/object_loader.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************/ -/* object_loader.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef OBJECT_LOADER_H -#define OBJECT_LOADER_H - -#include "object.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -#ifdef OLD_SCENE_FORMAT_ENABLED -class ObjectFormatLoader { -public: - - virtual Error load(Object **p_object,Variant &p_meta)=0; - - virtual ~ObjectFormatLoader() {} -}; - -class ObjectFormatLoaderInstancer { -public: - - virtual ObjectFormatLoader* instance(const String& p_file,const String& p_magic)=0; - virtual void get_recognized_extensions(List<String> *p_extensions) const=0; - bool recognize(const String& p_extension) const; - - virtual ~ObjectFormatLoaderInstancer() {} -}; - -class ObjectLoader { - - enum { - MAX_LOADERS=64 - }; - - static ObjectFormatLoaderInstancer *loader[MAX_LOADERS]; - static int loader_count; - -public: - - static ObjectFormatLoader *instance_format_loader(const String& p_path,const String& p_magic,String p_force_extension=""); - static void add_object_format_loader_instancer(ObjectFormatLoaderInstancer *p_format_loader_instancer); - static void get_recognized_extensions(List<String> *p_extensions); - - - -}; - -#endif -#endif diff --git a/core/io/object_saver.cpp b/core/io/object_saver.cpp deleted file mode 100644 index cff2e836a7..0000000000 --- a/core/io/object_saver.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************/ -/* object_saver.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "object_saver.h" -#ifdef OLD_SCENE_FORMAT_ENABLED - -void OptimizedSaver::add_property(const StringName& p_name, const Variant& p_value) { - - ERR_FAIL_COND(!_list); - Property p; - p.name=p_name; - p.value=p_value; - _list->push_back(p); -} - -bool OptimizedSaver::optimize_object(const Object *p_object) { - - return false; //not optimize -} - -void OptimizedSaver::get_property_list(const Object* p_object,List<Property> *p_properties) { - - - _list=p_properties; - - bool res = call("optimize_object",p_object); - - if (!res) { - - List<PropertyInfo> plist; - p_object->get_property_list(&plist); - for(List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) { - - PropertyInfo pinfo=E->get(); - if ((pinfo.usage&PROPERTY_USAGE_STORAGE) || (is_bundle_resources_enabled() && pinfo.usage&PROPERTY_USAGE_BUNDLE)) { - - add_property(pinfo.name,p_object->get(pinfo.name)); - } - } - - } - - _list=NULL; -} - -void OptimizedSaver::set_target_platform(const String& p_platform) { - - ERR_FAIL_COND(p_platform!="" && !p_platform.is_valid_identifier()); - platform=p_platform; -} - -String OptimizedSaver::get_target_platform() const { - - return platform; -} - -void OptimizedSaver::set_target_name(const String& p_name) { - - name=p_name; -} - -String OptimizedSaver::get_target_name() const { - - return name; -} - -void OptimizedSaver::_bind_methods() { - - ObjectTypeDB::bind_method(_MD("set_target_platform","name"),&OptimizedSaver::set_target_platform); - ObjectTypeDB::bind_method(_MD("get_target_platform"),&OptimizedSaver::get_target_platform); - ObjectTypeDB::bind_method(_MD("set_target_name","name"),&OptimizedSaver::set_target_name); - ObjectTypeDB::bind_method(_MD("add_property","name","value"),&OptimizedSaver::add_property); - ObjectTypeDB::bind_method(_MD("optimize_object","obj"),&OptimizedSaver::optimize_object); -} - -OptimizedSaver::OptimizedSaver() { - - _list=NULL; -} - -ObjectFormatSaverInstancer *ObjectSaver::saver[MAX_LOADERS]; -int ObjectSaver::saver_count=0; - -bool ObjectFormatSaverInstancer::recognize(const String& p_extension) const { - - - List<String> extensions; - get_recognized_extensions(&extensions); - for (List<String>::Element *E=extensions.front();E;E=E->next()) { - - if (E->get().nocasecmp_to(p_extension.extension())==0) - return true; - } - - return false; -} - -ObjectFormatSaver *ObjectSaver::instance_format_saver(const String& p_path,const String& p_magic,String p_force_extension,uint32_t p_flags,const Ref<OptimizedSaver>& p_optimizer) { - - String extension=p_force_extension.length()?p_force_extension:p_path.extension(); - - for (int i=0;i<saver_count;i++) { - - if (!saver[i]->recognize(extension)) - continue; - ObjectFormatSaver *format_saver = saver[i]->instance(p_path,p_magic,p_flags,p_optimizer); - if (format_saver) - return format_saver; - } - - return NULL; -} - -void ObjectSaver::get_recognized_extensions(List<String> *p_extensions) { - - for (int i=0;i<saver_count;i++) { - - saver[i]->get_recognized_extensions(p_extensions); - } -} - - - -void ObjectSaver::add_object_format_saver_instancer(ObjectFormatSaverInstancer *p_format_saver_instancer) { - - ERR_FAIL_COND(saver_count>=MAX_LOADERS ); - saver[saver_count++]=p_format_saver_instancer; -} - - - -#endif diff --git a/core/io/object_saver.h b/core/io/object_saver.h deleted file mode 100644 index b22f7e05bb..0000000000 --- a/core/io/object_saver.h +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************/ -/* object_saver.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef OBJECT_SAVER_H -#define OBJECT_SAVER_H - -#include "object.h" -#include "resource.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -#ifdef OLD_SCENE_FORMAT_ENABLED - -class OptimizedSaver : public Reference { - - OBJ_TYPE(OptimizedSaver,Reference); -public: - - struct Property { - - StringName name; - Variant value; - }; - -private: - - String name; - String platform; - List<Property> *_list; -protected: - - - void set_target_platform(const String& p_platform); - void set_target_name(const String& p_name); - void add_property(const StringName& p_name, const Variant& p_value); - static void _bind_methods(); - - virtual bool optimize_object(const Object *p_object); - -public: - - - virtual bool is_bundle_resources_enabled() const { return false; } - - String get_target_platform() const; - String get_target_name() const; - void get_property_list(const Object* p_object, List<Property> *p_properties); - - - OptimizedSaver(); - -}; - - -class ObjectFormatSaver { -public: - - virtual Error save(const Object *p_object,const Variant &p_meta=Variant())=0; - - virtual ~ObjectFormatSaver() {} -}; - -class ObjectFormatSaverInstancer { -public: - - virtual void get_recognized_extensions(List<String> *p_extensions) const=0; - virtual ObjectFormatSaver* instance(const String& p_file,const String& p_magic="",uint32_t p_flags=0,const Ref<OptimizedSaver>& p_optimizer=Ref<OptimizedSaver>())=0; - bool recognize(const String& p_extension) const; - - virtual ~ObjectFormatSaverInstancer() {} -}; - -class ObjectSaver { - - enum { - MAX_LOADERS=64 - }; - - static ObjectFormatSaverInstancer *saver[MAX_LOADERS]; - static int saver_count; - -public: - - enum SaverFlags { - - FLAG_RELATIVE_PATHS=1, - FLAG_BUNDLE_RESOURCES=2, - FLAG_OMIT_EDITOR_PROPERTIES=4, - FLAG_SAVE_BIG_ENDIAN=8 - }; - - - static ObjectFormatSaver *instance_format_saver(const String& p_path,const String& p_magic,String p_force_extension="",uint32_t p_flags=0,const Ref<OptimizedSaver>& p_optimizer=Ref<OptimizedSaver>()); - static void get_recognized_extensions(List<String> *p_extensions); - - static void add_object_format_saver_instancer(ObjectFormatSaverInstancer *p_format_saver_instancer); - - -}; - -#endif -#endif diff --git a/core/io/object_saver_base.cpp b/core/io/object_saver_base.cpp deleted file mode 100644 index 94d715de28..0000000000 --- a/core/io/object_saver_base.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************/ -/* object_saver_base.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "object_saver_base.h" -#ifdef OLD_SCENE_FORMAT_ENABLED -void ObjectSaverBase::_find_resources(const Variant& p_variant) { - - switch(p_variant.get_type()) { - case Variant::OBJECT: { - - - RES res = p_variant.operator RefPtr(); - - if (res.is_null() || (res->get_path().length() && res->get_path().find("::") == -1 )) - return; - - if (resource_map.has(res)) - return; - - List<PropertyInfo> property_list; - - res->get_property_list( &property_list ); - - List<PropertyInfo>::Element *I=property_list.front(); - - while(I) { - - PropertyInfo pi=I->get(); - - if (pi.usage&PROPERTY_USAGE_STORAGE) { - - if (pi.type==Variant::OBJECT) { - - Variant v=res->get(I->get().name); - _find_resources(v); - } - } - - I=I->next(); - } - - resource_map[ res ] = resource_map.size(); //saved after, so the childs it needs are available when loaded - saved_resources.push_back(res); - - } break; - - case Variant::ARRAY: { - - Array varray=p_variant; - int len=varray.size(); - for(int i=0;i<len;i++) { - - Variant v=varray.get(i); - _find_resources(v); - } - - } break; - - case Variant::DICTIONARY: { - - Dictionary d=p_variant; - List<Variant> keys; - d.get_key_list(&keys); - for(List<Variant>::Element *E=keys.front();E;E=E->next()) { - - Variant v = d[E->get()]; - _find_resources(v); - } - } break; - default: {} - } - -} - - -Error ObjectSaverBase::save(const Object *p_object,const Variant &p_meta) { - - ERR_EXPLAIN("write_object should supply either an object, a meta, or both"); - ERR_FAIL_COND_V(!p_object && p_meta.get_type()==Variant::NIL, ERR_INVALID_PARAMETER); - - SavedObject *so = memnew( SavedObject ); - - if (p_object) { - so->type=p_object->get_type(); - }; - - _find_resources(p_meta); - so->meta=p_meta; - - if (p_object) { - - List<PropertyInfo> property_list; - p_object->get_property_list( &property_list ); - - List<PropertyInfo>::Element *I=property_list.front(); - - while(I) { - - if (I->get().usage&PROPERTY_USAGE_STORAGE) { - - SavedObject::SavedProperty sp; - sp.name=I->get().name; - sp.value = p_object->get(I->get().name); - _find_resources(sp.value); - so->properties.push_back(sp); - } - - I=I->next(); - } - - } - - saved_objects.push_back(so); - - return OK; -} - -ObjectSaverBase::ObjectSaverBase() { - -}; - -ObjectSaverBase::~ObjectSaverBase() { - -}; -#endif diff --git a/core/io/object_saver_base.h b/core/io/object_saver_base.h deleted file mode 100644 index d9ec4a3aba..0000000000 --- a/core/io/object_saver_base.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************/ -/* object_saver_base.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef OBJECT_SAVER_BASE_H -#define OBJECT_SAVER_BASE_H - - -#ifdef OLD_SCENE_FORMAT_ENABLED -#include "object_saver.h" - -#include "map.h" -#include "resource.h" - -class ObjectSaverBase : public ObjectFormatSaver { - -protected: - - Map<RES,int> resource_map; - - struct SavedObject { - - Variant meta; - String type; - - - struct SavedProperty { - - String name; - Variant value; - }; - - List<SavedProperty> properties; - }; - - List<RES> saved_resources; - - List<SavedObject*> saved_objects; - - void _find_resources(const Variant& p_variant); - - virtual Error write()=0; -public: - - virtual Error save(const Object *p_object,const Variant &p_meta); - - ObjectSaverBase(); - ~ObjectSaverBase(); -}; - -#endif -#endif // OBJECT_SAVER_BASE_H diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 37fc9c4a0a..f6d526b512 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,7 +36,7 @@ PacketPeer::PacketPeer() { - + last_get_error=OK; } Error PacketPeer::get_packet_buffer(DVector<uint8_t> &r_buffer) const { @@ -108,10 +108,29 @@ Variant PacketPeer::_bnd_get_var() const { return var; }; +Error PacketPeer::_put_packet(const DVector<uint8_t> &p_buffer) { + return put_packet_buffer(p_buffer); +} +DVector<uint8_t> PacketPeer::_get_packet() const { + + DVector<uint8_t> raw; + last_get_error=get_packet_buffer(raw); + return raw; +} + +Error PacketPeer::_get_packet_error() const { + + return last_get_error; +} + + void PacketPeer::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_var"),&PacketPeer::_bnd_get_var); - ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"),&PacketPeer::put_var); + ObjectTypeDB::bind_method(_MD("put_var", "var:var"),&PacketPeer::put_var); + ObjectTypeDB::bind_method(_MD("get_packet"),&PacketPeer::_get_packet); + ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"),&PacketPeer::_put_packet); + ObjectTypeDB::bind_method(_MD("get_packet_error:Error"),&PacketPeer::_get_packet_error); ObjectTypeDB::bind_method(_MD("get_available_packet_count"),&PacketPeer::get_available_packet_count); }; @@ -137,7 +156,6 @@ Error PacketPeerStream::_poll_buffer() const { Error err = peer->get_partial_data(&temp_buffer[0], ring_buffer.space_left(), read); if (err) return err; - if (read==0) return OK; @@ -183,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size) uint8_t lbuf[4]; ring_buffer.copy(lbuf,0,4); remaining-=4; - uint32_t len = decode_uint32(lbuf); + uint32_t len = decode_uint32(lbuf); ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE); ring_buffer.read(lbuf,4); //get rid of first 4 bytes diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index e9d6be4fb9..76d1eb22b5 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,6 +41,14 @@ class PacketPeer : public Reference { static void _bind_methods(); + + Error _put_packet(const DVector<uint8_t> &p_buffer); + DVector<uint8_t> _get_packet() const; + Error _get_packet_error() const; + + + mutable Error last_get_error; + public: virtual int get_available_packet_count() const=0; diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp new file mode 100644 index 0000000000..83217ffc41 --- /dev/null +++ b/core/io/packet_peer_udp.cpp @@ -0,0 +1,63 @@ +#include "packet_peer_udp.h" +#include "io/ip.h" + + +PacketPeerUDP* (*PacketPeerUDP::_create)()=NULL; + +int PacketPeerUDP::_get_packet_address() const { + + IP_Address ip = get_packet_address(); + return ip.host; +} + +String PacketPeerUDP::_get_packet_ip() const { + + return get_packet_address(); +} + +Error PacketPeerUDP::_set_send_address(const String& p_address,int p_port) { + + IP_Address ip; + if (p_address.is_valid_ip_address()) { + ip=p_address; + } else { + ip=IP::get_singleton()->resolve_hostname(p_address); + if (ip==IP_Address()) + return ERR_CANT_RESOLVE; + } + + set_send_address(ip,p_port); + return OK; +} + +void PacketPeerUDP::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("listen:Error","port","recv_buf_size"),&PacketPeerUDP::listen,DEFVAL(65536)); + ObjectTypeDB::bind_method(_MD("close"),&PacketPeerUDP::close); + ObjectTypeDB::bind_method(_MD("wait:Error"),&PacketPeerUDP::wait); + ObjectTypeDB::bind_method(_MD("is_listening"),&PacketPeerUDP::is_listening); + ObjectTypeDB::bind_method(_MD("get_packet_ip"),&PacketPeerUDP::_get_packet_ip); + ObjectTypeDB::bind_method(_MD("get_packet_address"),&PacketPeerUDP::_get_packet_address); + ObjectTypeDB::bind_method(_MD("get_packet_port"),&PacketPeerUDP::get_packet_port); + ObjectTypeDB::bind_method(_MD("set_send_address","host","port"),&PacketPeerUDP::_set_send_address); + + +} + +Ref<PacketPeerUDP> PacketPeerUDP::create_ref() { + + if (!_create) + return Ref<PacketPeerUDP>(); + return Ref<PacketPeerUDP>(_create()); +} + +PacketPeerUDP* PacketPeerUDP::create() { + + if (!_create) + return NULL; + return _create(); +} + +PacketPeerUDP::PacketPeerUDP() +{ +} diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h new file mode 100644 index 0000000000..73ff487b19 --- /dev/null +++ b/core/io/packet_peer_udp.h @@ -0,0 +1,37 @@ +#ifndef PACKET_PEER_UDP_H +#define PACKET_PEER_UDP_H + + +#include "io/packet_peer.h" + +class PacketPeerUDP : public PacketPeer { + OBJ_TYPE(PacketPeerUDP,PacketPeer); + +protected: + + static PacketPeerUDP* (*_create)(); + static void _bind_methods(); + + int _get_packet_address() const; + String _get_packet_ip() const; + + virtual Error _set_send_address(const String& p_address,int p_port); + +public: + + virtual Error listen(int p_port,int p_recv_buffer_size=65536)=0; + virtual void close()=0; + virtual Error wait()=0; + virtual bool is_listening() const=0; + virtual IP_Address get_packet_address() const=0; + virtual int get_packet_port() const=0; + virtual void set_send_address(const IP_Address& p_address,int p_port)=0; + + + static Ref<PacketPeerUDP> create_ref(); + static PacketPeerUDP* create(); + + PacketPeerUDP(); +}; + +#endif // PACKET_PEER_UDP_H diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index e2371fe24f..9a3a191b3b 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,7 @@ #include "globals.h" #include "io/file_access_compressed.h" #include "io/marshalls.h" +#include "os/dir_access.h" //#define print_bl(m_what) print_line(m_what) #define print_bl(m_what) @@ -99,7 +100,9 @@ enum { OBJECT_EMPTY=0, OBJECT_EXTERNAL_RESOURCE=1, OBJECT_INTERNAL_RESOURCE=2, - FORMAT_VERSION=0 + OBJECT_EXTERNAL_RESOURCE_INDEX=3, + FORMAT_VERSION=1, + FORMAT_VERSION_CAN_RENAME_DEPS=1 }; @@ -375,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { } break; case OBJECT_INTERNAL_RESOURCE: { uint32_t index=f->get_32(); - String path = res_path+"::"+itos(index); + String path = res_path+"::"+itos(index); RES res = ResourceLoader::load(path); if (res.is_null()) { WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data()); @@ -384,16 +387,21 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { } break; case OBJECT_EXTERNAL_RESOURCE: { + //old file format, still around for compatibility String type = get_unicode_string(); String path = get_unicode_string(); if (path.find("://")==-1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path - path=Globals::get_singleton()->localize_path(res_path.get_base_dir()+"/"+path); + path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path)); } + if (remaps.find(path)) { + path=remaps[path]; + } + RES res=ResourceLoader::load(path,type); if (res.is_null()) { @@ -402,6 +410,34 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { r_v=res; } break; + case OBJECT_EXTERNAL_RESOURCE_INDEX: { + //new file format, just refers to an index in the external list + uint32_t erindex = f->get_32(); + + if (erindex>=external_resources.size()) { + WARN_PRINT("Broken external resource! (index out of size"); + r_v=Variant(); + } else { + + String type = external_resources[erindex].type; + String path = external_resources[erindex].path; + + if (path.find("://")==-1 && path.is_rel_path()) { + // path is relative to file being loaded, so convert to a resource path + path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path)); + + } + + RES res=ResourceLoader::load(path,type); + + if (res.is_null()) { + WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data()); + } + r_v=res; + } + + + } break; default: { ERR_FAIL_V(ERR_FILE_CORRUPT); @@ -628,17 +664,20 @@ Error ResourceInteractiveLoaderBinary::poll(){ if (s<external_resources.size()) { - RES res = ResourceLoader::load(external_resources[s].path,external_resources[s].type); + String path = external_resources[s].path; + if (remaps.has(path)) { + path=remaps[path]; + } + RES res = ResourceLoader::load(path,external_resources[s].type); if (res.is_null()) { if (!ResourceLoader::get_abort_on_missing_resources()) { - ResourceLoader::notify_load_error("Resource Not Found: "+external_resources[s].path); + ResourceLoader::notify_dependency_error(local_path,path,external_resources[s].type); } else { - - error=ERR_FILE_CORRUPT; - ERR_EXPLAIN("Can't load dependency: "+external_resources[s].path); + error=ERR_FILE_MISSING_DEPENDENCIES; + ERR_EXPLAIN("Can't load dependency: "+path); ERR_FAIL_V(error); } @@ -663,14 +702,18 @@ Error ResourceInteractiveLoaderBinary::poll(){ //maybe it is loaded already String path; + int subindex=0; if (!main) { path=internal_resources[s].path; - if (path.begins_with("local://")) - path=path.replace("local://",res_path+"::"); + if (path.begins_with("local://")) { + path=path.replace_first("local://",""); + subindex = path.to_int(); + path=res_path+"::"+path; + } @@ -709,6 +752,7 @@ Error ResourceInteractiveLoaderBinary::poll(){ RES res = RES( r ); r->set_path(path); + r->set_subindex(subindex); int pc = f->get_32(); @@ -782,12 +826,35 @@ int ResourceInteractiveLoaderBinary::get_stage_count() const { return external_resources.size()+internal_resources.size(); } + +static void save_ustring(FileAccess* f,const String& p_string) { + + + CharString utf8 = p_string.utf8(); + f->store_32(utf8.length()+1); + f->store_buffer((const uint8_t*)utf8.get_data(),utf8.length()+1); +} + + +static String get_ustring(FileAccess *f) { + + int len = f->get_32(); + Vector<char> str_buf; + str_buf.resize(len); + f->get_buffer((uint8_t*)&str_buf[0],len); + String s; + s.parse_utf8(&str_buf[0]); + return s; +} + String ResourceInteractiveLoaderBinary::get_unicode_string() { int len = f->get_32(); if (len>str_buf.size()) { str_buf.resize(len); } + if (len==0) + return String(); f->get_buffer((uint8_t*)&str_buf[0],len); String s; s.parse_utf8(&str_buf[0]); @@ -796,7 +863,7 @@ String ResourceInteractiveLoaderBinary::get_unicode_string() { -void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies) { +void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies,bool p_add_types) { open(p_f); if (error) @@ -809,6 +876,10 @@ void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<Stri dep=ResourceLoader::guess_full_filename(dep,external_resources[i].type); } + if (p_add_types && external_resources[i].type!=String()) { + dep+="::"+external_resources[i].type; + } + p_dependencies->push_back(dep); } @@ -836,7 +907,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { error=ERR_FILE_UNRECOGNIZED; ERR_EXPLAIN("Unrecognized binary resource file: "+local_path); - ERR_FAIL_V(); + ERR_FAIL(); } bool big_endian = f->get_32(); @@ -861,7 +932,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { print_bl("minor: "+itos(ver_minor)); print_bl("format: "+itos(ver_format)); - if (ver_format<FORMAT_VERSION || ver_major>VERSION_MAJOR || (ver_major==VERSION_MAJOR && ver_minor>VERSION_MINOR)) { + if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) { f->close(); ERR_EXPLAIN("File Format '"+itos(FORMAT_VERSION)+"."+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+local_path); @@ -898,6 +969,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { } //see if the exporter has different set of external resources for more efficient loading + /* String preload_depts = "deps/"+res_path.md5_text(); if (Globals::get_singleton()->has(preload_depts)) { external_resources.clear(); @@ -908,7 +980,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { external_resources[i].path=depts.get_name(i); } print_line(res_path+" - EXTERNAL RESOURCES: "+itos(external_resources.size())); - } + }*/ print_bl("ext resources: "+itos(ext_resources_size)); uint32_t int_resources_size=f->get_32(); @@ -968,7 +1040,7 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) { uint32_t ver_minor=f->get_32(); uint32_t ver_format=f->get_32(); - if (ver_format<FORMAT_VERSION || ver_major>VERSION_MAJOR || (ver_major==VERSION_MAJOR && ver_minor>VERSION_MINOR)) { + if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) { f->close(); return ""; @@ -995,8 +1067,10 @@ ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() { } -Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path) { +Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, Error *r_error) { + if (r_error) + *r_error=ERR_FILE_CANT_OPEN; Error err; FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); @@ -1109,7 +1183,7 @@ Error ResourceFormatLoaderBinary::load_import_metadata(const String &p_path, Ref } -void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies) { +void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) { FileAccess *f = FileAccess::open(p_path,FileAccess::READ); ERR_FAIL_COND(!f); @@ -1118,7 +1192,217 @@ void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<Stri ria->local_path=Globals::get_singleton()->localize_path(p_path); ria->res_path=ria->local_path; // ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); - ria->get_dependencies(f,p_dependencies); + ria->get_dependencies(f,p_dependencies,p_add_types); +} + +Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path,const Map<String,String>& p_map) { + + +// Error error=OK; + + + FileAccess *f=FileAccess::open(p_path,FileAccess::READ); + ERR_FAIL_COND_V(!f,ERR_CANT_OPEN); + + FileAccess* fw=NULL;//=FileAccess::open(p_path+".depren"); + + String local_path=p_path.get_base_dir(); + + uint8_t header[4]; + f->get_buffer(header,4); + if (header[0]=='R' && header[1]=='S' && header[2]=='C' && header[3]=='C') { + //compressed + FileAccessCompressed *fac = memnew( FileAccessCompressed ); + fac->open_after_magic(f); + f=fac; + + FileAccessCompressed *facw = memnew( FileAccessCompressed ); + facw->configure("RSCC"); + Error err = facw->_open(p_path+".depren",FileAccess::WRITE); + if (err) { + memdelete(fac); + memdelete(facw); + ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT); + } + + fw=facw; + + + } else if (header[0]!='R' || header[1]!='S' || header[2]!='R' || header[3]!='C') { + //not normal + + //error=ERR_FILE_UNRECOGNIZED; + memdelete(f); + ERR_EXPLAIN("Unrecognized binary resource file: "+local_path); + ERR_FAIL_V(ERR_FILE_UNRECOGNIZED); + } else { + fw = FileAccess::open(p_path+".depren",FileAccess::WRITE); + if (!fw) { + memdelete(f); + } + ERR_FAIL_COND_V(!fw,ERR_CANT_CREATE); + } + + bool big_endian = f->get_32(); +#ifdef BIG_ENDIAN_ENABLED + endian_swap = !big_endian; +#else + bool endian_swap = big_endian; +#endif + + bool use_real64 = f->get_32(); + + f->set_endian_swap(big_endian!=0); //read big endian if saved as big endian + fw->store_32(endian_swap); + fw->set_endian_swap(big_endian!=0); + fw->store_32(use_real64); //use real64 + + uint32_t ver_major=f->get_32(); + uint32_t ver_minor=f->get_32(); + uint32_t ver_format=f->get_32(); + + if (ver_format<FORMAT_VERSION_CAN_RENAME_DEPS) { + + memdelete(f); + memdelete(fw); + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->remove(p_path+".depren"); + memdelete(da); + //fuck it, use the old approach; + + WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data()); + + Error err; + f = FileAccess::open(p_path,FileAccess::READ,&err); + if (err!=OK) { + ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN); + } + + Ref<ResourceInteractiveLoaderBinary> ria = memnew( ResourceInteractiveLoaderBinary ); + ria->local_path=Globals::get_singleton()->localize_path(p_path); + ria->res_path=ria->local_path; + ria->remaps=p_map; + // ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); + ria->open(f); + + err = ria->poll(); + + while(err==OK) { + err=ria->poll(); + } + + ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT); + RES res = ria->get_resource(); + ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT); + + return ResourceFormatSaverBinary::singleton->save(p_path,res); + } + + if (ver_format>FORMAT_VERSION || ver_major>VERSION_MAJOR) { + + memdelete(f); + memdelete(fw); + ERR_EXPLAIN("File Format '"+itos(FORMAT_VERSION)+"."+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+local_path); + ERR_FAIL_V(ERR_FILE_UNRECOGNIZED); + + } + + fw->store_32( VERSION_MAJOR ); //current version + fw->store_32( VERSION_MINOR ); + fw->store_32( FORMAT_VERSION ); + + save_ustring(fw,get_ustring(f)); //type + + + size_t md_ofs = f->get_pos(); + size_t importmd_ofs = f->get_64(); + fw->store_64(0); //metadata offset + + for(int i=0;i<14;i++) { + fw->store_32(0); + f->get_32(); + } + + //string table + uint32_t string_table_size=f->get_32(); + + fw->store_32(string_table_size); + + for(uint32_t i=0;i<string_table_size;i++) { + + String s = get_ustring(f); + save_ustring(fw,s); + } + + //external resources + uint32_t ext_resources_size=f->get_32(); + fw->store_32(ext_resources_size); + for(uint32_t i=0;i<ext_resources_size;i++) { + + String type = get_ustring(f); + String path = get_ustring(f); + + bool relative=false; + if (!path.begins_with("res://")) { + path=local_path.plus_file(path).simplify_path(); + relative=true; + } + + + if (p_map.has(path)) { + String np=p_map[path]; + path=np; + } + + if (relative) { + //restore relative + path=local_path.path_to_file(path); + } + + save_ustring(fw,type); + save_ustring(fw,path); + } + + int64_t size_diff = (int64_t)fw->get_pos() - (int64_t)f->get_pos(); + + //internal resources + uint32_t int_resources_size=f->get_32(); + fw->store_32(int_resources_size); + + for(uint32_t i=0;i<int_resources_size;i++) { + + + String path=get_ustring(f); + uint64_t offset=f->get_64(); + save_ustring(fw,path); + fw->store_64(offset+size_diff); + } + + //rest of file + uint8_t b = f->get_8(); + while(!f->eof_reached()) { + fw->store_8(b); + b = f->get_8(); + } + + bool all_ok = fw->get_error()==OK; + + fw->seek(md_ofs); + fw->store_64(importmd_ofs+size_diff); + + + memdelete(f); + memdelete(fw); + + if (!all_ok) { + return ERR_CANT_CREATE; + } + + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + da->remove(p_path); + da->rename(p_path+".depren",p_path); + memdelete(da); + return OK; } @@ -1428,20 +1712,18 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property, } if (res->get_path().length() && res->get_path().find("::")==-1) { - f->store_32(OBJECT_EXTERNAL_RESOURCE); - save_unicode_string(res->get_save_type()); - String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path(); - save_unicode_string(path); + f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX); + f->store_32(external_resources[res]); } else { - if (!resource_map.has(res)) { + if (!resource_set.has(res)) { f->store_32(OBJECT_EMPTY); ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); ERR_FAIL(); } f->store_32(OBJECT_INTERNAL_RESOURCE); - f->store_32(resource_map[res]); + f->store_32(res->get_subindex()); //internal resource } @@ -1589,16 +1871,17 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant RES res = p_variant.operator RefPtr(); - if (res.is_null()) + if (res.is_null() || external_resources.has(res)) return; if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) { - external_resources.insert(res); + int idx = external_resources.size(); + external_resources[res]=idx; return; } - if (resource_map.has(res)) + if (resource_set.has(res)) return; List<PropertyInfo> property_list; @@ -1613,7 +1896,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant } } - resource_map[ res ] = saved_resources.size(); + resource_set.insert(res); saved_resources.push_back(res); } break; @@ -1778,6 +2061,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ f->store_32(VERSION_MINOR); f->store_32(FORMAT_VERSION); + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + //f->store_32(saved_resources.size()+external_resources.size()); // load steps -not needed save_unicode_string(p_resource->get_type()); uint64_t md_at = f->get_pos(); @@ -1809,7 +2097,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ Property p; p.name_idx=get_string_index(F->get().name); p.value=E->get()->get(F->get().name); - if (F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero()) + if ((F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())||(F->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()) ) continue; p.pi=F->get(); @@ -1832,25 +2120,65 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ // save external resource table f->store_32(external_resources.size()); //amount of external resources - for(Set<RES>::Element *E=external_resources.front();E;E=E->next()) { + Vector<RES> save_order; + save_order.resize(external_resources.size()); + + for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) { + save_order[E->get()]=E->key(); + } + + for(int i=0;i<save_order.size();i++) { - save_unicode_string(E->get()->get_save_type()); - String path = E->get()->get_path(); + save_unicode_string(save_order[i]->get_save_type()); + String path = save_order[i]->get_path(); + path=relative_paths?local_path.path_to_file(path):path; save_unicode_string(path); } // save internal resource table f->store_32(saved_resources.size()); //amount of internal resources Vector<uint64_t> ofs_pos; + Set<int> used_indices; + for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { RES r = E->get(); if (r->get_path()=="" || r->get_path().find("::")!=-1) { - save_unicode_string("local://"+itos(ofs_pos.size())); + + if (r->get_subindex()!=0) { + if (used_indices.has(r->get_subindex())) { + r->set_subindex(0); //repeated + } else { + used_indices.insert(r->get_subindex()); + } + } + } + + } + + + for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { + + + RES r = E->get(); + if (r->get_path()=="" || r->get_path().find("::")!=-1) { + if (r->get_subindex()==0) { + int new_subindex=1; + if (used_indices.size()) { + new_subindex=used_indices.back()->get()+1; + } + + r->set_subindex(new_subindex); + used_indices.insert(new_subindex); + + } + + save_unicode_string("local://"+itos(r->get_subindex())); if (takeover_paths) { - r->set_path(p_path+"::"+itos(ofs_pos.size()),true); + r->set_path(p_path+"::"+itos(r->get_subindex()),true); } - } else + } else { save_unicode_string(r->get_path()); //actual external + } ofs_pos.push_back(f->get_pos()); f->store_64(0); //offset in 64 bits } @@ -1910,6 +2238,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ f->store_buffer((const uint8_t*)"RSRC",4); //magic at end + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + f->close(); @@ -1949,3 +2282,9 @@ void ResourceFormatSaverBinary::get_recognized_extensions(const RES& p_resource, } +ResourceFormatSaverBinary* ResourceFormatSaverBinary::singleton=NULL; + +ResourceFormatSaverBinary::ResourceFormatSaverBinary() { + + singleton=this; +} diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index cc26357bfb..8bf20bc574 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,6 +71,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader { String get_unicode_string(); void _advance_padding(uint32_t p_len); + Map<String,String> remaps; Error error; int stage; @@ -88,9 +89,10 @@ public: virtual int get_stage() const; virtual int get_stage_count() const; + void set_remaps(const Map<String,String>& p_remaps) { remaps=p_remaps; } void open(FileAccess *p_f); String recognize(FileAccess *p_f); - void get_dependencies(FileAccess *p_f,List<String> *p_dependencies); + void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types); ResourceInteractiveLoaderBinary(); @@ -101,13 +103,14 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL); virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String& p_type) const; virtual String get_resource_type(const String &p_path) const; - virtual void get_dependencies(const String& p_path,List<String> *p_dependencies); + virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false); virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const; + virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map); @@ -129,12 +132,12 @@ class ResourceFormatSaverBinaryInstance { int bin_meta_idx; FileAccess *f; String magic; - Map<RES,int> resource_map; + Set<RES> resource_set; Map<StringName,int> string_map; Vector<StringName> strings; - Set<RES> external_resources; + Map<RES,int> external_resources; List<RES> saved_resources; @@ -174,11 +177,12 @@ class ResourceFormatSaverBinary : public ResourceFormatSaver { public: + static ResourceFormatSaverBinary* singleton; virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0); virtual bool recognize(const RES& p_resource) const; virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const; - + ResourceFormatSaverBinary(); }; diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index e6eede7de6..48917a19ea 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,10 +29,10 @@ #include "resource_format_xml.h" #include "globals.h" #include "version.h" +#include "os/dir_access.h" - -ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool *r_exit,bool p_printerr) { +ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool *r_exit, bool p_printerr, List<String> *r_order) { while(get_char()!='<' && !f->eof_reached()) {} @@ -107,7 +107,11 @@ ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool if (r_value.size()) { r_value.push_back(0); - tag.args[name].parse_utf8(r_value.get_data()); + String str; + str.parse_utf8(r_value.get_data()); + tag.args[name]=str; + if (r_order) + r_order->push_back(name); } break; @@ -119,7 +123,11 @@ ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool } else if (reading_value && r_value.size()) { r_value.push_back(0); - tag.args[name].parse_utf8(r_value.get_data()); + String str; + str.parse_utf8(r_value.get_data()); + tag.args[name]=str; + if (r_order) + r_order->push_back(name); name=""; r_value.clear(); reading_value=false; @@ -193,6 +201,7 @@ Error ResourceInteractiveLoaderXML::close_tag(const String& p_name) { void ResourceInteractiveLoaderXML::unquote(String& p_str) { + p_str=p_str.strip_edges().replace("\"","").xml_unescape(); /*p_str=p_str.strip_edges(); @@ -308,6 +317,7 @@ Error ResourceInteractiveLoaderXML::_parse_array_element(Vector<char> &buff,bool buff_max++; buff.resize(buff_max); + buffptr=buff.ptr(); } @@ -457,8 +467,12 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) path=path.replace("local://",local_path+"::"); else if (path.find("://")==-1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path - path=Globals::get_singleton()->localize_path(local_path.get_base_dir()+"/"+path); + path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path)); + + } + if (remaps.has(path)) { + path=remaps[path]; } //take advantage of the resource loader cache. The resource is cached on it, even if @@ -471,10 +485,31 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) } r_v=res.get_ref_ptr(); + } else if (tag->args.has("external")) { + + int index = tag->args["external"].to_int(); + if (ext_resources.has(index)) { + String path=ext_resources[index].path; + String type=ext_resources[index].type; + + //take advantage of the resource loader cache. The resource is cached on it, even if + RES res=ResourceLoader::load(path,type); + + if (res.is_null()) { + + WARN_PRINT(String("Couldn't load externalresource: "+path).ascii().get_data()); + } + + r_v=res.get_ref_ptr(); + } else { + WARN_PRINT(String("Invalid external resource index: "+itos(index)).ascii().get_data()); + + } } + Error err=goto_end_of_tag(); if (err) { ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error closing <resource> tag."); @@ -571,7 +606,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) int w=width.to_int(); int h=height.to_int(); - if (w == 0 && w == 0) { + if (w == 0 && h == 0) { //r_v = Image(w, h, imgformat); r_v=Image(); String sdfsdfg; @@ -1205,47 +1240,47 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) r_v=Vector3( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double() + data.get_slicec(',',0).to_double(), + data.get_slicec(',',1).to_double(), + data.get_slicec(',',2).to_double() ); } else if (type=="vector2") { r_v=Vector2( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double() + data.get_slicec(',',0).to_double(), + data.get_slicec(',',1).to_double() ); } else if (type=="plane") { r_v=Plane( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() + data.get_slicec(',',0).to_double(), + data.get_slicec(',',1).to_double(), + data.get_slicec(',',2).to_double(), + data.get_slicec(',',3).to_double() ); } else if (type=="quaternion") { r_v=Quat( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() + data.get_slicec(',',0).to_double(), + data.get_slicec(',',1).to_double(), + data.get_slicec(',',2).to_double(), + data.get_slicec(',',3).to_double() ); } else if (type=="rect2") { r_v=Rect2( Vector2( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double() + data.get_slicec(',',0).to_double(), + data.get_slicec(',',1).to_double() ), Vector2( - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() + data.get_slicec(',',2).to_double(), + data.get_slicec(',',3).to_double() ) ); @@ -1254,14 +1289,14 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) r_v=AABB( Vector3( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double() + data.get_slicec(',',0).to_double(), + data.get_slicec(',',1).to_double(), + data.get_slicec(',',2).to_double() ), Vector3( - data.get_slice(",",3).to_double(), - data.get_slice(",",4).to_double(), - data.get_slice(",",5).to_double() + data.get_slicec(',',3).to_double(), + data.get_slicec(',',4).to_double(), + data.get_slicec(',',5).to_double() ) ); @@ -1270,7 +1305,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) Matrix32 m3; for (int i=0;i<3;i++) { for (int j=0;j<2;j++) { - m3.elements[i][j]=data.get_slice(",",i*2+j).to_double(); + m3.elements[i][j]=data.get_slicec(',',i*2+j).to_double(); } } r_v=m3; @@ -1280,7 +1315,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) Matrix3 m3; for (int i=0;i<3;i++) { for (int j=0;j<3;j++) { - m3.elements[i][j]=data.get_slice(",",i*3+j).to_double(); + m3.elements[i][j]=data.get_slicec(',',i*3+j).to_double(); } } r_v=m3; @@ -1290,24 +1325,24 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) Transform tr; for (int i=0;i<3;i++) { for (int j=0;j<3;j++) { - tr.basis.elements[i][j]=data.get_slice(",",i*3+j).to_double(); + tr.basis.elements[i][j]=data.get_slicec(',',i*3+j).to_double(); } } tr.origin=Vector3( - data.get_slice(",",9).to_double(), - data.get_slice(",",10).to_double(), - data.get_slice(",",11).to_double() + data.get_slicec(',',9).to_double(), + data.get_slicec(',',10).to_double(), + data.get_slicec(',',11).to_double() ); r_v=tr; } else if (type=="color") { r_v=Color( - data.get_slice(",",0).to_double(), - data.get_slice(",",1).to_double(), - data.get_slice(",",2).to_double(), - data.get_slice(",",3).to_double() + data.get_slicec(',',0).to_double(), + data.get_slicec(',',1).to_double(), + data.get_slicec(',',2).to_double(), + data.get_slicec(',',3).to_double() ); } else if (type=="node_path") { @@ -1362,32 +1397,6 @@ Error ResourceInteractiveLoaderXML::poll() { if (error!=OK) return error; - if (ext_resources.size()) { - - error=ERR_FILE_CORRUPT; - String path=ext_resources.front()->get(); - - RES res = ResourceLoader::load(path); - - if (res.is_null()) { - - if (ResourceLoader::get_abort_on_missing_resources()) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": editor exported unexisting resource at: "+path); - ERR_FAIL_V(error); - } else { - ResourceLoader::notify_load_error("Resource Not Found: "+path); - } - } else { - - resource_cache.push_back(res); - } - - error=OK; - ext_resources.pop_front(); - resource_current++; - return error; - } - bool exit; Tag *tag = parse_tag(&exit); @@ -1411,36 +1420,48 @@ Error ResourceInteractiveLoaderXML::poll() { ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field."); ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT); - String type; + String type="Resource"; if (tag->args.has("type")) type=tag->args["type"]; String path = tag->args["path"]; + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> can't use a local path, this is a bug?."); ERR_FAIL_COND_V(path.begins_with("local://"),ERR_FILE_CORRUPT); if (path.find("://")==-1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path - path=Globals::get_singleton()->localize_path(local_path.get_base_dir()+"/"+path); + path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path)); } + if (remaps.has(path)) { + path=remaps[path]; + } RES res = ResourceLoader::load(path,type); if (res.is_null()) { if (ResourceLoader::get_abort_on_missing_resources()) { - ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> referenced unexisting resource at: "+path); + ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> referenced nonexistent resource at: "+path); ERR_FAIL_V(error); } else { - ResourceLoader::notify_load_error("Resource Not Found: "+path); + ResourceLoader::notify_dependency_error(local_path,path,type); } } else { resource_cache.push_back(res); } + if (tag->args.has("index")) { + ExtResource er; + er.path=path; + er.type=type; + ext_resources[tag->args["index"].to_int()]=er; + } + + Error err = close_tag("ext_resource"); if (err) return error; @@ -1464,6 +1485,7 @@ Error ResourceInteractiveLoaderXML::poll() { String type; String path; + int subres=0; if (!main) { //loading resource @@ -1474,11 +1496,15 @@ Error ResourceInteractiveLoaderXML::poll() { ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'type' field."); ERR_FAIL_COND_V(!tag->args.has("type"),ERR_FILE_CORRUPT); path=tag->args["path"]; + error=OK; if (path.begins_with("local://")) { //built-in resource (but really external) - path=path.replace("local://",local_path+"::"); + + path=path.replace("local://",""); + subres=path.to_int(); + path=local_path+"::"+path; } @@ -1517,6 +1543,7 @@ Error ResourceInteractiveLoaderXML::poll() { res = RES( r ); if (path!="") r->set_path(path); + r->set_subindex(subres); //load properties @@ -1558,7 +1585,7 @@ int ResourceInteractiveLoaderXML::get_stage() const { } int ResourceInteractiveLoaderXML::get_stage_count() const { - return resources_total+ext_resources.size(); + return resources_total;//+ext_resources; } ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() { @@ -1566,7 +1593,7 @@ ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() { memdelete(f); } -void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *p_dependencies) { +void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *p_dependencies,bool p_add_types) { open(f); @@ -1600,7 +1627,7 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> * if (path.find("://")==-1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path - path=Globals::get_singleton()->localize_path(local_path.get_base_dir()+"/"+path); + path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path)); } if (path.ends_with("*")) { @@ -1609,6 +1636,10 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> * path = ResourceLoader::guess_full_filename(path,type); } + if (p_add_types && tag->args.has("type")) { + path+="::"+tag->args["type"]; + } + p_dependencies->push_back(path); Error err = close_tag("ext_resource"); @@ -1620,6 +1651,167 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> * } +Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) { + + open(p_f); + ERR_FAIL_COND_V(error!=OK,error); + + //FileAccess + + bool old_format=false; + + FileAccess *fw = NULL; + + String base_path=local_path.get_base_dir(); + + while(true) { + bool exit; + List<String> order; + + Tag *tag = parse_tag(&exit,true,&order); + + bool done=false; + + if (!tag) { + if (fw) { + memdelete(fw); + } + error=ERR_FILE_CORRUPT; + ERR_FAIL_COND_V(!exit,error); + error=ERR_FILE_EOF; + + return error; + } + + if (tag->name=="ext_resource") { + + if (!tag->args.has("index") || !tag->args.has("path") || !tag->args.has("type")) { + old_format=true; + break; + } + + if (!fw) { + + fw=FileAccess::open(p_path+".depren",FileAccess::WRITE); + fw->store_line("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); //no escape + fw->store_line("<resource_file type=\""+resource_type+"\" subresource_count=\""+itos(resources_total)+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\">"); + + } + + String path = tag->args["path"]; + String index = tag->args["index"]; + String type = tag->args["type"]; + + + bool relative=false; + if (!path.begins_with("res://")) { + path=base_path.plus_file(path).simplify_path(); + relative=true; + } + + + if (p_map.has(path)) { + String np=p_map[path]; + path=np; + } + + if (relative) { + //restore relative + path=base_path.path_to_file(path); + } + + tag->args["path"]=path; + tag->args["index"]=index; + tag->args["type"]=type; + + } else { + + done=true; + } + + String tagt="\t<"; + if (exit) + tagt+="/"; + tagt+=tag->name; + + for(List<String>::Element *E=order.front();E;E=E->next()) { + tagt+=" "+E->get()+"=\""+tag->args[E->get()]+"\""; + } + tagt+=">"; + fw->store_line(tagt); + if (done) + break; + close_tag("ext_resource"); + fw->store_line("\t</ext_resource>"); + + } + + + if (old_format) { + if (fw) + memdelete(fw); + + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->remove(p_path+".depren"); + memdelete(da); + //fuck it, use the old approach; + + WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data()); + + Error err; + FileAccess *f2 = FileAccess::open(p_path,FileAccess::READ,&err); + if (err!=OK) { + ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN); + } + + Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML ); + ria->local_path=Globals::get_singleton()->localize_path(p_path); + ria->res_path=ria->local_path; + ria->remaps=p_map; + // ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); + ria->open(f2); + + err = ria->poll(); + + while(err==OK) { + err=ria->poll(); + } + + ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT); + RES res = ria->get_resource(); + ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT); + + return ResourceFormatSaverXML::singleton->save(p_path,res); + } + + if (!fw) { + + return OK; //nothing to rename, do nothing + } + + uint8_t c=f->get_8(); + while(!f->eof_reached()) { + fw->store_8(c); + c=f->get_8(); + } + + bool all_ok = fw->get_error()==OK; + + memdelete(fw); + + if (!all_ok) { + return ERR_CANT_CREATE; + } + + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + da->remove(p_path); + da->rename(p_path+".depren",p_path); + memdelete(da); + + return OK; + +} + void ResourceInteractiveLoaderXML::open(FileAccess *p_f) { @@ -1666,10 +1858,10 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) { ERR_FAIL(); } - int major = version.get_slice(".",0).to_int(); - int minor = version.get_slice(".",1).to_int(); + int major = version.get_slicec('.',0).to_int(); + int minor = version.get_slicec('.',1).to_int(); - if (major>VERSION_MAJOR || (major==VERSION_MAJOR && minor>VERSION_MINOR)) { + if (major>VERSION_MAJOR) { error=ERR_FILE_UNRECOGNIZED; ResourceLoader::notify_load_error(local_path+": File Format '"+version+"' is too new. Please upgrade to a newer engine version."); @@ -1678,6 +1870,7 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) { } + /* String preload_depts = "deps/"+local_path.md5_text(); if (Globals::get_singleton()->has(preload_depts)) { ext_resources.clear(); @@ -1689,7 +1882,7 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) { } print_line(local_path+" - EXTERNAL RESOURCES: "+itos(ext_resources.size())); } - +*/ } @@ -1722,7 +1915,10 @@ String ResourceInteractiveLoaderXML::recognize(FileAccess *p_f) { ///////////////////// -Ref<ResourceInteractiveLoader> ResourceFormatLoaderXML::load_interactive(const String &p_path) { +Ref<ResourceInteractiveLoader> ResourceFormatLoaderXML::load_interactive(const String &p_path, Error *r_error) { + + if (r_error) + *r_error=ERR_CANT_OPEN; Error err; FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); @@ -1759,7 +1955,6 @@ void ResourceFormatLoaderXML::get_recognized_extensions_for_type(const String& p if (ext=="res") continue; p_extensions->push_back("x"+ext); - p_extensions->push_back(ext); } p_extensions->push_back("xml"); @@ -1808,7 +2003,7 @@ String ResourceFormatLoaderXML::get_resource_type(const String &p_path) const{ } -void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> *p_dependencies) { +void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) { FileAccess *f = FileAccess::open(p_path,FileAccess::READ); if (!f) { @@ -1820,11 +2015,27 @@ void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> ria->local_path=Globals::get_singleton()->localize_path(p_path); ria->res_path=ria->local_path; // ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); - ria->get_dependencies(f,p_dependencies); + ria->get_dependencies(f,p_dependencies,p_add_types); } +Error ResourceFormatLoaderXML::rename_dependencies(const String &p_path,const Map<String,String>& p_map) { + + FileAccess *f = FileAccess::open(p_path,FileAccess::READ); + if (!f) { + + ERR_FAIL_V(ERR_CANT_OPEN); + } + + Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML ); + ria->local_path=Globals::get_singleton()->localize_path(p_path); + ria->res_path=ria->local_path; +// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) ); + return ria->rename_dependencies(f,p_path,p_map); +} + + /****************************************************************************************/ /****************************************************************************************/ /****************************************************************************************/ @@ -1844,14 +2055,17 @@ void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> void ResourceFormatSaverXMLInstance::escape(String& p_str) { p_str=p_str.replace("&","&"); - p_str=p_str.replace("<",">"); - p_str=p_str.replace(">","<"); + p_str=p_str.replace("<","<"); + p_str=p_str.replace(">",">"); p_str=p_str.replace("'","'"); p_str=p_str.replace("\"","""); - for (int i=1;i<32;i++) { + for (char i=1;i<32;i++) { char chr[2]={i,0}; - p_str=p_str.replace(chr,"&#"+String::num(i)+";"); + const char hexn[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + const char hex[8]={'&','#','0','0',hexn[i>>4],hexn[i&0xf],';',0}; + + p_str=p_str.replace(chr,hex); } @@ -2013,20 +2227,26 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V return; // don't save it } - params="resource_type=\""+res->get_save_type()+"\""; + if (external_resources.has(res)) { - if (res->get_path().length() && res->get_path().find("::")==-1) { - //external resource - String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path(); - escape(path); - params+=" path=\""+path+"\""; + params="external=\""+itos(external_resources[res])+"\""; } else { + params="resource_type=\""+res->get_save_type()+"\""; + - //internal resource - ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); - ERR_FAIL_COND(!resource_map.has(res)); + if (res->get_path().length() && res->get_path().find("::")==-1) { + //external resource + String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path(); + escape(path); + params+=" path=\""+path+"\""; + } else { + + //internal resource + ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); + ERR_FAIL_COND(!resource_set.has(res)); - params+=" path=\"local://"+itos(resource_map[res])+"\""; + params+=" path=\"local://"+itos(res->get_subindex())+"\""; + } } } break; @@ -2239,12 +2459,12 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V List<Variant> keys; dict.get_key_list(&keys); + keys.sort(); for(List<Variant>::Element *E=keys.front();E;E=E->next()) { //if (!_check_type(dict[E->get()])) // continue; - bool ok; write_property("",E->get(),&ok); ERR_CONTINUE(!ok); @@ -2430,20 +2650,22 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo RES res = p_variant.operator RefPtr(); - if (res.is_null()) + if (res.is_null() || external_resources.has(res)) return; if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) { - external_resources.insert(res); + int index = external_resources.size(); + external_resources[res]=index; return; } - if (resource_map.has(res)) + if (resource_set.has(res)) return; List<PropertyInfo> property_list; res->get_property_list( &property_list ); + property_list.sort(); List<PropertyInfo>::Element *I=property_list.front(); @@ -2460,7 +2682,7 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo I=I->next(); } - resource_map[ res ] = resource_map.size(); //saved after, so the childs it needs are available when loaded + resource_set.insert( res ); //saved after, so the childs it needs are available when loaded saved_resources.push_back(res); } break; @@ -2521,22 +2743,37 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res enter_tag("resource_file","type=\""+p_resource->get_type()+"\" subresource_count=\""+itos(saved_resources.size()+external_resources.size())+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\""); write_string("\n",false); - for(Set<RES>::Element *E=external_resources.front();E;E=E->next()) { + for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) { write_tabs(); - String p = E->get()->get_path(); + String p = E->key()->get_path(); - enter_tag("ext_resource","path=\""+p+"\" type=\""+E->get()->get_save_type()+"\""); //bundled + enter_tag("ext_resource","path=\""+p+"\" type=\""+E->key()->get_save_type()+"\" index=\""+itos(E->get())+"\""); //bundled exit_tag("ext_resource"); //bundled write_string("\n",false); } + Set<int> used_indices; + + for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { + RES res = E->get(); + if (E->next() && (res->get_path()=="" || res->get_path().find("::") != -1 )) { + + if (res->get_subindex()!=0) { + if (used_indices.has(res->get_subindex())) { + res->set_subindex(0); //repeated + } else { + used_indices.insert(res->get_subindex()); + } + } + } + } for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { RES res = E->get(); - ERR_CONTINUE(!resource_map.has(res)); + ERR_CONTINUE(!resource_set.has(res)); bool main = (E->next()==NULL); write_tabs(); @@ -2546,7 +2783,18 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res else if (res->get_path().length() && res->get_path().find("::") == -1 ) enter_tag("resource","type=\""+res->get_type()+"\" path=\""+res->get_path()+"\""); //bundled else { - int idx = resource_map[res]; + + if (res->get_subindex()==0) { + int new_subindex=1; + if (used_indices.size()) { + new_subindex=used_indices.back()->get()+1; + } + + res->set_subindex(new_subindex); + used_indices.insert(new_subindex); + } + + int idx = res->get_subindex(); enter_tag("resource","type=\""+res->get_type()+"\" path=\"local://"+itos(idx)+"\""); if (takeover_paths) { res->set_path(p_path+"::"+itos(idx),true); @@ -2558,6 +2806,7 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res List<PropertyInfo> property_list; res->get_property_list(&property_list); +// property_list.sort(); for(List<PropertyInfo>::Element *PE = property_list.front();PE;PE=PE->next()) { @@ -2568,9 +2817,12 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res String name = PE->get().name; Variant value = res->get(name); - if (PE->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero()) + + + if ((PE->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero())||(PE->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && value.is_one()) ) continue; + write_property(name,value); } @@ -2588,6 +2840,11 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res } exit_tag("resource_file"); + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + f->close(); //memdelete(f); @@ -2620,3 +2877,8 @@ void ResourceFormatSaverXML::get_recognized_extensions(const RES& p_resource,Lis } } + +ResourceFormatSaverXML* ResourceFormatSaverXML::singleton=NULL; +ResourceFormatSaverXML::ResourceFormatSaverXML() { + singleton=this; +} diff --git a/core/io/resource_format_xml.h b/core/io/resource_format_xml.h index 40aaa01451..77987c6a5b 100644 --- a/core/io/resource_format_xml.h +++ b/core/io/resource_format_xml.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -46,13 +46,21 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader { String name; HashMap<String,String> args; + }; _FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end); + struct ExtResource { + String path; + String type; + }; + - List<StringName> ext_resources; + Map<String,String> remaps; + + Map<int,ExtResource> ext_resources; int resources_total; int resource_current; @@ -66,7 +74,7 @@ friend class ResourceFormatLoaderXML; List<Tag> tag_stack; List<RES> resource_cache; - Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true); + Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true,List<String> *r_order=NULL); Error close_tag(const String& p_name); _FORCE_INLINE_ void unquote(String& p_str); Error goto_end_of_tag(); @@ -87,7 +95,8 @@ public: void open(FileAccess *p_f); String recognize(FileAccess *p_f); - void get_dependencies(FileAccess *p_f,List<String> *p_dependencies); + void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types); + Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map); ~ResourceInteractiveLoaderXML(); @@ -97,12 +106,13 @@ public: class ResourceFormatLoaderXML : public ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL); virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String& p_type) const; virtual String get_resource_type(const String &p_path) const; - virtual void get_dependencies(const String& p_path,List<String> *p_dependencies); + virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false); + virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map); }; @@ -123,9 +133,9 @@ class ResourceFormatSaverXMLInstance { bool skip_editor; FileAccess *f; int depth; - Map<RES,int> resource_map; + Set<RES> resource_set; List<RES> saved_resources; - Set<RES> external_resources; + Map<RES,int> external_resources; void enter_tag(const char* p_tag,const String& p_args=String()); void exit_tag(const char* p_tag); @@ -148,11 +158,12 @@ public: class ResourceFormatSaverXML : public ResourceFormatSaver { public: + static ResourceFormatSaverXML* singleton; virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0); virtual bool recognize(const RES& p_resource) const; virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const; - + ResourceFormatSaverXML(); }; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index d2610d5d4f..3862790b02 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -103,10 +103,10 @@ public: -Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path) { +Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, Error *r_error) { //either this - Ref<Resource> res = load(p_path); + Ref<Resource> res = load(p_path,p_path,r_error); if (res.is_null()) return Ref<ResourceInteractiveLoader>(); @@ -115,11 +115,13 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const Stri return ril; } -RES ResourceFormatLoader::load(const String &p_path,const String& p_original_path) { +RES ResourceFormatLoader::load(const String &p_path, const String& p_original_path, Error *r_error) { + String path=p_path; + //or this must be implemented - Ref<ResourceInteractiveLoader> ril = load_interactive(p_path); + Ref<ResourceInteractiveLoader> ril = load_interactive(p_path,r_error); if (!ril.is_valid()) return RES(); ril->set_local_path(p_original_path); @@ -129,9 +131,14 @@ RES ResourceFormatLoader::load(const String &p_path,const String& p_original_pat Error err = ril->poll(); if (err==ERR_FILE_EOF) { + if (r_error) + *r_error=OK; return ril->get_resource(); } + if (r_error) + *r_error=err; + ERR_FAIL_COND_V(err!=OK,RES()); } @@ -139,7 +146,7 @@ RES ResourceFormatLoader::load(const String &p_path,const String& p_original_pat } -void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) { +void ResourceFormatLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) { //do nothing by default } @@ -148,11 +155,18 @@ void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p /////////////////////////////////// -RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_no_cache) { +RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p_no_cache, Error *r_error) { - String local_path = Globals::get_singleton()->localize_path(p_path); + if (r_error) + *r_error=ERR_CANT_OPEN; - local_path=find_complete_path(p_path,p_type_hint); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); + + local_path=find_complete_path(local_path,p_type_hint); ERR_FAIL_COND_V(local_path=="",RES()); if (!p_no_cache && ResourceCache::has(local_path)) { @@ -178,7 +192,7 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) continue; found=true; - RES res = loader[i]->load(remapped_path,local_path); + RES res = loader[i]->load(remapped_path,local_path,r_error); if (res.is_null()) continue; if (!p_no_cache) @@ -209,17 +223,20 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p_path) { - String local_path = Globals::get_singleton()->localize_path(p_path); + + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); String extension=p_path.extension(); - bool found=false; Ref<ResourceImportMetadata> ret; for (int i=0;i<loader_count;i++) { if (!loader[i]->recognize(extension)) continue; - found=true; Error err = loader[i]->load_import_metadata(local_path,ret); if (err==OK) @@ -279,13 +296,19 @@ String ResourceLoader::find_complete_path(const String& p_path,const String& p_t return local_path; } -Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache) { +Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache,Error *r_error) { + if (r_error) + *r_error=ERR_CANT_OPEN; - String local_path = Globals::get_singleton()->localize_path(p_path); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); - local_path=find_complete_path(p_path,p_type_hint); + local_path=find_complete_path(local_path,p_type_hint); ERR_FAIL_COND_V(local_path=="",Ref<ResourceInteractiveLoader>()); @@ -313,7 +336,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) continue; found=true; - Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path); + Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path,r_error); if (ril.is_null()) continue; if (!p_no_cache) @@ -338,9 +361,15 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l loader[loader_count++]=p_format_loader; } -void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) { +void ResourceLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) { + + + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); - String local_path = Globals::get_singleton()->localize_path(p_path); String remapped_path = PathRemap::get_singleton()->get_remap(local_path); String extension=remapped_path.extension(); @@ -352,14 +381,47 @@ void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_depen //if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) // continue; - loader[i]->get_dependencies(remapped_path,p_dependencies); + loader[i]->get_dependencies(remapped_path,p_dependencies,p_add_types); } } +Error ResourceLoader::rename_dependencies(const String &p_path,const Map<String,String>& p_map) { + + + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); + + String remapped_path = PathRemap::get_singleton()->get_remap(local_path); + + String extension=remapped_path.extension(); + + for (int i=0;i<loader_count;i++) { + + if (!loader[i]->recognize(extension)) + continue; + //if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) + // continue; + + return loader[i]->rename_dependencies(p_path,p_map); + + } + + return OK; // ?? + +} + + String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) { - String local_path = Globals::get_singleton()->localize_path(p_path); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); return find_complete_path(local_path,p_type); @@ -367,7 +429,12 @@ String ResourceLoader::guess_full_filename(const String &p_path,const String& p_ String ResourceLoader::get_resource_type(const String &p_path) { - String local_path = Globals::get_singleton()->localize_path(p_path); + String local_path; + if (p_path.is_rel_path()) + local_path="res://"+p_path; + else + local_path = Globals::get_singleton()->localize_path(p_path); + String remapped_path = PathRemap::get_singleton()->get_remap(local_path); String extension=remapped_path.extension(); @@ -385,6 +452,9 @@ String ResourceLoader::get_resource_type(const String &p_path) { ResourceLoadErrorNotify ResourceLoader::err_notify=NULL; void *ResourceLoader::err_notify_ud=NULL; +DependencyErrorNotify ResourceLoader::dep_err_notify=NULL; +void *ResourceLoader::dep_err_notify_ud=NULL; + bool ResourceLoader::abort_on_missing_resource=true; bool ResourceLoader::timestamp_on_load=false; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index ab23158785..00a05dcb43 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -57,21 +57,23 @@ public: class ResourceFormatLoader { public: - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path); - virtual RES load(const String &p_path,const String& p_original_path=""); + virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL); + virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const=0; virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const; bool recognize(const String& p_extension) const; virtual bool handles_type(const String& p_type) const=0; virtual String get_resource_type(const String &p_path) const=0; - virtual void get_dependencies(const String& p_path,List<String> *p_dependencies); + virtual void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false); virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const { return ERR_UNAVAILABLE; } + virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map) { return OK; } virtual ~ResourceFormatLoader() {} }; typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text); +typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type); class ResourceLoader { @@ -86,6 +88,8 @@ class ResourceLoader { static void* err_notify_ud; static ResourceLoadErrorNotify err_notify; + static void* dep_err_notify_ud; + static DependencyErrorNotify dep_err_notify; static bool abort_on_missing_resource; static String find_complete_path(const String& p_path,const String& p_type); @@ -93,14 +97,15 @@ public: - static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false); - static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false); + static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL); + static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL); static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path); static void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions); static void add_resource_format_loader(ResourceFormatLoader *p_format_loader); static String get_resource_type(const String &p_path); - static void get_dependencies(const String& p_path,List<String> *p_dependencies); + static void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false); + static Error rename_dependencies(const String &p_path,const Map<String,String>& p_map); static String guess_full_filename(const String &p_path,const String& p_type); @@ -108,6 +113,11 @@ public: static void notify_load_error(const String& p_err) { if (err_notify) err_notify(err_notify_ud,p_err); } static void set_error_notify_func(void* p_ud,ResourceLoadErrorNotify p_err_notify) { err_notify=p_err_notify; err_notify_ud=p_ud;} + + static void notify_dependency_error(const String& p_path,const String& p_dependency,const String& p_type) { if (dep_err_notify) dep_err_notify(dep_err_notify_ud,p_path,p_dependency,p_type); } + static void set_dependency_error_notify_func(void* p_ud,DependencyErrorNotify p_err_notify) { dep_err_notify=p_err_notify; dep_err_notify_ud=p_ud;} + + static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource=p_abort; } static bool get_abort_on_missing_resources() { return abort_on_missing_resource; } }; diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 598f517d76..fdb9a53f0d 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index e307668721..8382b65290 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -46,7 +46,7 @@ public: virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0; virtual bool recognize(const RES& p_resource) const=0; virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0; - + virtual ~ResourceFormatSaver() {} }; diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 0eae660373..b00b462eb6 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index 84552cfd3e..e83fc71b93 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index 0e75e22767..c2343790ea 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,7 +32,7 @@ StreamPeerTCP* (*StreamPeerTCP::_create)()=NULL; void StreamPeerTCP::_bind_methods() { - ObjectTypeDB::bind_method(_MD("connect","host","ip"),&StreamPeerTCP::connect); + ObjectTypeDB::bind_method(_MD("connect","host","port"),&StreamPeerTCP::connect); ObjectTypeDB::bind_method(_MD("is_connected"),&StreamPeerTCP::is_connected); ObjectTypeDB::bind_method(_MD("get_status"),&StreamPeerTCP::get_status); ObjectTypeDB::bind_method(_MD("get_connected_host"),&StreamPeerTCP::get_connected_host); diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index d447ded78b..0e37303516 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index bce9e19ae3..803df87086 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index fff00e5ce0..b59f3293d7 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index 0d42cebb41..020d168208 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,7 +30,10 @@ #include "os/file_access.h" #include "translation.h" -RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path) { +RES TranslationLoaderPO::load(const String &p_path, const String& p_original_path, Error *r_error) { + + if (r_error) + *r_error=ERR_CANT_OPEN; FileAccess *f=FileAccess::open(p_path,FileAccess::READ); ERR_FAIL_COND_V(!f,RES()); @@ -49,6 +52,8 @@ RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path String msg_id; String msg_str; String config; + if (r_error) + *r_error=ERR_FILE_CORRUPT; Ref<Translation> translation = Ref<Translation>( memnew( Translation )); int line = 1; @@ -174,6 +179,8 @@ RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path } } + if (r_error) + *r_error=OK; return translation; diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index 7a0c4e10dc..e07ae15e28 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,7 +34,7 @@ class TranslationLoaderPO : public ResourceFormatLoader { public: - virtual RES load(const String &p_path,const String& p_original_path=""); + virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String& p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/io/unzip.c b/core/io/unzip.c index 0cd975211e..b438021ad7 100644 --- a/core/io/unzip.c +++ b/core/io/unzip.c @@ -1788,7 +1788,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) return UNZ_PARAMERROR; - if ((pfile_in_zip_read_info->read_buffer == NULL)) + if (pfile_in_zip_read_info->read_buffer==NULL) return UNZ_END_OF_LIST_OF_FILE; if (len==0) return 0; diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index 5d3e4f61ad..1ff458f325 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,9 +30,11 @@ #include "print_string.h" //#define DEBUG_XML +VARIANT_ENUM_CAST(XMLParser::NodeType); + static bool _equalsn(const CharType* str1, const CharType* str2, int len) { int i; - for(i=0; str1[i] && str2[i] && i < len; ++i) + for(i=0; i < len && str1[i] && str2[i] ; ++i) if (str1[i] != str2[i]) return false; diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index 9debbf9e2f..418a8efa70 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/core/io/zip.c b/core/io/zip.c index 8f6aeb922f..c4ab93ab81 100644 --- a/core/io/zip.c +++ b/core/io/zip.c @@ -1114,9 +1114,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, zi->ci.flag = flagBase; if ((level==8) || (level==9)) zi->ci.flag |= 2; - if ((level==2)) + if (level==2) zi->ci.flag |= 4; - if ((level==1)) + if (level==1) zi->ci.flag |= 6; if (password != NULL) zi->ci.flag |= 1; diff --git a/core/io/zip.h b/core/io/zip.h index cca06c2ee8..85f93568c9 100644 --- a/core/io/zip.h +++ b/core/io/zip.h @@ -39,6 +39,8 @@ #ifndef _zip12_H #define _zip12_H +#include <stdlib.h> + #ifdef __cplusplus extern "C" { #endif diff --git a/core/io/zip_io.h b/core/io/zip_io.h index 798265cc48..dd3c371a4a 100644 --- a/core/io/zip_io.h +++ b/core/io/zip_io.h @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,6 +34,7 @@ #include "os/file_access.h" #include "os/copymem.h" + static void* zipio_open(void* data, const char* p_fname, int mode) { FileAccess *&f = *(FileAccess**)data; |