mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
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:
+110
-13
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user