Added love.math.encode(format, data | string [, linelength]) and love.math.decode(format, data | string). Current formats are "base64" and "hex". The optional line length only applies to base64 and specifies the maximum number of characters per line in the encoded string.

Removed the variant of love.filesystem.newFileData which decoded a base64-encoded string since it's redundant.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2016-03-28 19:28:40 -03:00
parent 9efbe4892c
commit 734789eb93
15 changed files with 394 additions and 141 deletions
+110 -13
View File
@@ -19,12 +19,98 @@
**/
#include "b64.h"
#include "Exception.h"
#include <limits>
#include <stdio.h>
namespace love
{
// Translation table as described in RFC1113
static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// Translation table to decode (created by Bob Trower)
static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
/**
* encode 3 8-bit binary bytes as 4 '6-bit' characters
**/
static void b64_encode_block(char in[3], char out[4], int len)
{
out[0] = (char) cb64[(int)(in[0] >> 2)];
out[1] = (char) cb64[(int)(((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4))];
out[2] = (char) (len > 1 ? cb64[(int)(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6))] : '=');
out[3] = (char) (len > 2 ? cb64[(int)(in[2] & 0x3f)] : '=');
}
char *b64_encode(const char *src, size_t srclen, size_t linelen, size_t &dstlen)
{
if (linelen == 0)
linelen = std::numeric_limits<size_t>::max();
size_t blocksout = 0;
size_t srcpos = 0;
size_t adjustment = (srclen % 3) ? (3 - (srclen % 3)) : 0;
size_t paddedlen = ((srclen + adjustment) / 3) * 4;
dstlen = paddedlen + paddedlen / linelen;
if (dstlen == 0)
return nullptr;
char *dst = nullptr;
try
{
dst = new char[dstlen + 1];
}
catch (std::exception &)
{
throw love::Exception("Out of memory.");
}
size_t dstpos = 0;
while (srcpos < srclen)
{
char in[3] = {0};
char out[4] = {0};
int len = 0;
for (int i = 0; i < 3; i++)
{
if (srcpos >= srclen)
break;
in[i] = src[srcpos++];
len++;
}
if (len > 0)
{
b64_encode_block(in, out, len);
for (int i = 0; i < 4 && dstpos < dstlen; i++, dstpos++)
dst[dstpos] = out[i];
blocksout++;
}
if (blocksout >= linelen / 4 || srcpos >= srclen)
{
if (blocksout > 0 && dstpos < dstlen)
dst[dstpos++] = '\n';
blocksout = 0;
}
}
dst[dstpos] = '\0';
return dst;
}
static void b64_decode_block(char in[4], char out[3])
{
out[0] = (char)(in[0] << 2 | in[1] >> 4);
@@ -32,34 +118,44 @@ static void b64_decode_block(char in[4], char out[3])
out[2] = (char)(((in[2] << 6) & 0xc0) | in[3]);
}
char *b64_decode(const char *src, int slen, int &size)
char *b64_decode(const char *src, size_t srclen, size_t &size)
{
size = (slen / 4) * 3;
size_t paddedsize = (srclen / 4) * 3;
char *dst = nullptr;
try
{
dst = new char[paddedsize];
}
catch (std::exception &)
{
throw love::Exception("Out of memory.");
}
char *dst = new char[size];
char *d = dst;
char in[4] = {0}, out[3], v;
int i, len, pos = 0;
char in[4] = {0};
char out[3] = {0};
size_t i, len, srcpos = 0;
while (pos <= slen)
while (srcpos <= srclen)
{
for (len = 0, i = 0; i < 4 && pos <= slen; i++)
for (len = 0, i = 0; i < 4 && srcpos <= srclen; i++)
{
v = 0;
char v = 0;
while (pos <= slen && v == 0)
while (srcpos <= srclen && v == 0)
{
v = src[pos++];
v = src[srcpos++];
v = (char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
if (v)
if (v != 0)
v = (char)((v == '$') ? 0 : v - 61);
}
if (pos <= slen)
if (srcpos <= srclen)
{
len++;
if (v)
if (v != 0)
in[i] = (char)(v - 1);
}
else
@@ -74,6 +170,7 @@ char *b64_decode(const char *src, int slen, int &size)
}
}
size = (size_t)(ptrdiff_t) (d - dst);
return dst;
}
+17 -3
View File
@@ -20,21 +20,35 @@
#include "config.h"
#include <stddef.h>
#ifndef LOVE_B64_H
#define LOVE_B64_H
namespace love
{
/**
* Base64-encode data.
*
* @param src The data to encode.
* @param srclen The size in bytes of the data.
* @param linelen The maximum length of each line in the encoded string.
* 0 indicates no maximum length.
* @param dstlen The length of the encoded string is stored here.
* @return A string containing the base64-encoded data (allocated with new[]).
*/
char *b64_encode(const char *src, size_t srclen, size_t linelen, size_t &dstlen);
/**
* Decode base64 encoded data.
*
* @param src The string containing the base64 data.
* @param slen The length of the string.
* @param size The size of the binary data is stored here.
* @param srclen The length of the string.
* @param dstlen The size of the binary data is stored here.
* @return A chunk of memory containing the binary data (allocated with new[]).
*/
char *b64_decode(const char *src, int slen, int &size);
char *b64_decode(const char *src, size_t srclen, size_t &dstlen);
} // love