mingodad пре 9 година
родитељ
комит
d338834c60
1 измењених фајлова са 161 додато и 16 уклоњено
  1. 161 16
      SquiLu-ext/sq_base64.cpp

+ 161 - 16
SquiLu-ext/sq_base64.cpp

@@ -6,20 +6,160 @@
 * This code is hereby placed in the public domain.
 * Ported to Squrrel by Domingo Alvarez Duarte
 */
+/*
+* lascii85.c
+* ascii85 encoding and decoding for Lua 5.1
+* Luiz Henrique de Figueiredo <[email protected]>
+* 23 Mar 2010 22:25:18
+* This code is hereby placed in the public domain.
+* Ported to Squrrel by Domingo Alvarez Duarte
+*/
 
 #include "squirrel.h"
 #include <string.h>
 #include "sqstdblobimpl.h"
 
-#define MYNAME		_SC("base64")
-#define MYVERSION	_SC(MYNAME " library for " LUA_VERSION " / Jun 2007")
-
 #define uint unsigned int
+#define ROUND_BLOB_SIZE(x) (x < 8192 ? 8192 : x*2)
+
+static void encode85(SQBlob &b, uint c1, uint c2, uint c3, uint c4, int n)
+{
+    unsigned long tuple=c4+256UL*(c3+256UL*(c2+256UL*c1));
+    if (tuple==0 && n==4)
+        b.Write("z",1);
+    else
+    {
+        int i;
+        char s[5];
+        for (i=0; i<5; i++)
+        {
+            s[4-i] = '!' + (tuple % 85);
+            tuple /= 85;
+        }
+        b.Write(s,n+1);
+    }
+}
+
+static SQRESULT ascii85_encode(HSQUIRRELVM v)		/** encode(s) */
+{
+    SQInteger l;
+    const unsigned char *s;
+    SQRESULT rc;
+    if((rc = sq_getstr_and_size(v,2, (const SQChar**)&s, &l)) != SQ_OK) return rc;
+    SQBlob b(0, ROUND_BLOB_SIZE(l));
+    int n;
+
+    b.Write("<~",2);
+    for (n=l/4; n--; s+=4) encode85(b,s[0],s[1],s[2],s[3],4);
+    switch (l%4)
+    {
+    case 1:
+        encode85(b,s[0],0,0,0,1);
+        break;
+    case 2:
+        encode85(b,s[0],s[1],0,0,2);
+        break;
+    case 3:
+        encode85(b,s[0],s[1],s[2],0,3);
+        break;
+    }
+    b.Write("~>",2);
+    sq_pushstring(v, (SQChar*)b.GetBuf(), b.Len());
+    return 1;
+}
+
+static void decode85(SQBlob &b, int c1, int c2, int c3, int c4, int c5, int n)
+{
+    unsigned long tuple=c5+85L*(c4+85L*(c3+85L*(c2+85L*c1)));
+    char s[4];
+    switch (--n)
+    {
+    case 4:
+        s[3]=tuple;
+    case 3:
+        s[2]=tuple >> 8;
+    case 2:
+        s[1]=tuple >> 16;
+    case 1:
+        s[0]=tuple >> 24;
+    }
+    b.Write(s,n);
+}
+
+static SQRESULT ascii85_decode(HSQUIRRELVM v)		/** decode(s) */
+{
+    SQInteger l;
+    const unsigned char *s;
+    SQRESULT rc;
+    if((rc = sq_getstr_and_size(v,2, (const SQChar**)&s, &l)) != SQ_OK) return rc;
+    SQBlob b(0, ROUND_BLOB_SIZE(l));
+    int n=0;
+    char t[5];
+    if (*s++!='<') return 0;
+    if (*s++!='~') return 0;
+    for (;;)
+    {
+        int c=*s++;
+        switch (c)
+        {
+        default:
+            if (c<'!' || c>'u') return 0;
+            t[n++]=c-'!';
+            if (n==5)
+            {
+                decode85(b,t[0],t[1],t[2],t[3],t[4],5);
+                n=0;
+            }
+            break;
+        case 'z':
+            b.Write("\0\0\0\0",4);
+            break;
+        case '~':
+            if (*s!='>') return 0;
+            switch (n)
+            {
+            case 1:
+                decode85(b, t[0],85,0,0,0,1);
+                break;
+            case 2:
+                decode85(b, t[0],t[1],85,0,0,2);
+                break;
+            case 3:
+                decode85(b,t[0],t[1],t[2],85,0,3);
+                break;
+            case 4:
+                decode85(b,t[0],t[1],t[2],t[3],85,4);
+                break;
+            }
+            sq_pushstring(v, (SQChar*)b.GetBuf(), b.Len());
+            return 1;
+        case '\n':
+        case '\r':
+        case '\t':
+        case ' ':
+        case '\0':
+        case '\f':
+        case '\b':
+        case 0177:
+            break;
+        }
+    }
+    return 0;
+}
+
+#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),ascii85_##name,nparams,tycheck}
+static SQRegFunction ascii85_methods[] =
+{
+    _DECL_FUNC(encode,2,_SC(".s")),
+    _DECL_FUNC(decode,2,_SC(".s")),
+    {0,0}
+};
+#undef _DECL_FUNC
 
 static const char code[]=
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
-static void encode(SQBlob &b, uint c1, uint c2, uint c3, int n)
+static void encode64(SQBlob &b, uint c1, uint c2, uint c3, int n)
 {
     unsigned long tuple=c3+256UL*(c2+256UL*c1);
     int i;
@@ -38,24 +178,24 @@ static SQRESULT base64_encode(HSQUIRRELVM v)		/** encode(s) */
     SQInteger l;
     const unsigned char *s;
     SQRESULT rc;
-    if((rc = sq_getstr_and_size(v,2, (const char **)&s, &l)) != SQ_OK) return rc;
-    SQBlob b(0, l*2);
+    if((rc = sq_getstr_and_size(v,2, (const SQChar**)&s, &l)) != SQ_OK) return rc;
+    SQBlob b(0, ROUND_BLOB_SIZE(l));
     int n;
-    for (n=l/3; n--; s+=3) encode(b,s[0],s[1],s[2],3);
+    for (n=l/3; n--; s+=3) encode64(b,s[0],s[1],s[2],3);
     switch (l%3)
     {
     case 1:
-        encode(b,s[0],0,0,1);
+        encode64(b,s[0],0,0,1);
         break;
     case 2:
-        encode(b,s[0],s[1],0,2);
+        encode64(b,s[0],s[1],0,2);
         break;
     }
     sq_pushstring(v, (SQChar*)b.GetBuf(), b.Len());
     return 1;
 }
 
-static void decode(SQBlob &b, int c1, int c2, int c3, int c4, int n)
+static void decode64(SQBlob &b, int c1, int c2, int c3, int c4, int n)
 {
     unsigned long tuple=c4+64L*(c3+64L*(c2+64L*c1));
     char s[3];
@@ -76,8 +216,8 @@ static SQRESULT base64_decode(HSQUIRRELVM v)		/** decode(s) */
     SQInteger l;
     const unsigned char *s;
     SQRESULT rc;
-    if((rc = sq_getstr_and_size(v,2, (const char **)&s, &l)) != SQ_OK) return rc;
-    SQBlob b(0, l*2);
+    if((rc = sq_getstr_and_size(v,2, (const SQChar**)&s, &l)) != SQ_OK) return rc;
+    SQBlob b(0, ROUND_BLOB_SIZE(l));
     int n=0;
     char t[4];
     for (;;)
@@ -92,7 +232,7 @@ static SQRESULT base64_decode(HSQUIRRELVM v)		/** decode(s) */
             t[n++]= p-code;
             if (n==4)
             {
-                decode(b,t[0],t[1],t[2],t[3],4);
+                decode64(b,t[0],t[1],t[2],t[3],4);
                 n=0;
             }
             break;
@@ -100,13 +240,13 @@ static SQRESULT base64_decode(HSQUIRRELVM v)		/** decode(s) */
             switch (n)
             {
             case 1:
-                decode(b,t[0],0,0,0,1);
+                decode64(b,t[0],0,0,0,1);
                 break;
             case 2:
-                decode(b,t[0],t[1],0,0,2);
+                decode64(b,t[0],t[1],0,0,2);
                 break;
             case 3:
-                decode(b,t[0],t[1],t[2],0,3);
+                decode64(b,t[0],t[1],t[2],0,3);
                 break;
             }
         case 0:
@@ -143,6 +283,11 @@ SQRESULT sqext_register_base64(HSQUIRRELVM v)
     sq_newtable(v);
     sq_insert_reg_funcs(v, base64_methods);
     sq_newslot(v,-3,SQTrue);
+
+    sq_pushstring(v,_SC("ascii85"),-1);
+    sq_newtable(v);
+    sq_insert_reg_funcs(v, ascii85_methods);
+    sq_newslot(v,-3,SQTrue);
     return 0;
 }