/* Based on code from Dave Winer (http://www.scripting.com/midas/base64/) */ #include "precomp_wasabi_bfc.h" #include "base64.h" char Base64::encodingTable [64] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; int Base64::encode(MemBlock &htext, MemBlock &h64, int linelength) { /* encode the handle. some funny stuff about linelength -- it only makes sense to make it a multiple of 4. if it's not a multiple of 4, we make it so (by only checking it every 4 characters. further, if it's 0, we don't add any line breaks at all. */ unsigned long ixtext; unsigned long lentext; unsigned long origsize; long ctremaining; unsigned char inbuf [3] = {0}, outbuf [4] = {0}; short i; short charsonline = 0, ctcopy; ixtext = 0; lentext = htext.getSize(); while (1) { ctremaining = lentext - ixtext; if (ctremaining <= 0) break; for (i = 0; i < 3; i++) { unsigned long ix = ixtext + i; if (ix < lentext) inbuf [i] = *htext.getMemory(ix); else inbuf [i] = 0; } outbuf [0] = (inbuf [0] & 0xFC) >> 2; outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); outbuf [3] = inbuf [2] & 0x3F; origsize = h64.getSize(); h64.setSize(origsize + 4); ctcopy = 4; switch (ctremaining) { case 1: ctcopy = 2; break; case 2: ctcopy = 3; break; } for (i = 0; i < ctcopy; i++) *h64.getMemory(origsize + i) = encodingTable[outbuf[i]]; for (i = ctcopy; i < 4; i++) *h64.getMemory(origsize + i) = '='; ixtext += 3; charsonline += 4; if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/ if (charsonline >= linelength) { charsonline = 0; origsize = h64.getSize(); h64.setSize(origsize + 1); *h64.getMemory() = '\n'; } } } return 1; } int Base64::encode(MemBlock &htext, MemBlock &h64, int linelength) { /* encode the handle. some funny stuff about linelength -- it only makes sense to make it a multiple of 4. if it's not a multiple of 4, we make it so (by only checking it every 4 characters. further, if it's 0, we don't add any line breaks at all. */ unsigned long ixtext; unsigned long lentext; unsigned long origsize; long ctremaining; unsigned char inbuf [3] = {0}, outbuf [4] = {0}; short i; short charsonline = 0, ctcopy; ixtext = 0; lentext = htext.getSize(); while (1) { ctremaining = lentext - ixtext; if (ctremaining <= 0) break; for (i = 0; i < 3; i++) { unsigned long ix = ixtext + i; if (ix < lentext) inbuf [i] = *htext.getMemory(ix); else inbuf [i] = 0; } outbuf [0] = (inbuf [0] & 0xFC) >> 2; outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); outbuf [3] = inbuf [2] & 0x3F; origsize = h64.getSize(); h64.setSize(origsize + 4); ctcopy = 4; switch (ctremaining) { case 1: ctcopy = 2; break; case 2: ctcopy = 3; break; } for (i = 0; i < ctcopy; i++) *h64.getMemory(origsize + i) = encodingTable[outbuf[i]]; for (i = ctcopy; i < 4; i++) *h64.getMemory(origsize + i) = '='; ixtext += 3; charsonline += 4; if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/ if (charsonline >= linelength) { charsonline = 0; origsize = h64.getSize(); h64.setSize(origsize + 1); *h64.getMemory() = '\n'; } } } return 1; } int Base64::decode(MemBlock &h64, MemBlock &htext) { unsigned long ixtext; unsigned long lentext; unsigned long origsize; unsigned char ch; unsigned char inbuf [4] = {0}, outbuf [4] = {0}; short i, ixinbuf; boolean flignore; boolean flendtext = false; ixtext = 0; lentext = h64.getSize(); ixinbuf = 0; while (true) { if (ixtext >= lentext) break; ch = *h64.getMemory(ixtext++); flignore = 0; if ((ch >= 'A') && (ch <= 'Z')) ch = ch - 'A'; else if ((ch >= 'a') && (ch <= 'z')) ch = ch - 'a' + 26; else if ((ch >= '0') && (ch <= '9')) ch = ch - '0' + 52; else if (ch == '+') ch = 62; else if (ch == '=') /*no op -- can't ignore this one*/ flendtext = true; else if (ch == '/') ch = 63; else flignore = true; if (!flignore) { short ctcharsinbuf = 3; boolean flbreak = false; if (flendtext) { if (ixinbuf == 0) break; if ((ixinbuf == 1) || (ixinbuf == 2)) ctcharsinbuf = 1; else ctcharsinbuf = 2; ixinbuf = 3; flbreak = 1; } inbuf [ixinbuf++] = ch; if (ixinbuf == 4) { ixinbuf = 0; outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); origsize = htext.getSize(); htext.setSize(origsize + ctcharsinbuf); for (i = 0; i < ctcharsinbuf; i++) *htext.getMemory(origsize + i) = outbuf[i]; } if (flbreak) break; } } return 1; } int Base64::decode(MemBlock &h64, MemBlock &htext) { unsigned long ixtext; unsigned long lentext; unsigned long origsize; unsigned char ch; unsigned char inbuf [4] = {0}, outbuf [4] = {0}; short i, ixinbuf; boolean flignore; boolean flendtext = false; ixtext = 0; lentext = h64.getSize(); ixinbuf = 0; while (true) { if (ixtext >= lentext) break; ch = (unsigned char)*h64.getMemory(ixtext++); flignore = 0; if ((ch >= 'A') && (ch <= 'Z')) ch = ch - 'A'; else if ((ch >= 'a') && (ch <= 'z')) ch = ch - 'a' + 26; else if ((ch >= '0') && (ch <= '9')) ch = ch - '0' + 52; else if (ch == '+') ch = 62; else if (ch == '=') /*no op -- can't ignore this one*/ flendtext = true; else if (ch == '/') ch = 63; else flignore = true; if (!flignore) { short ctcharsinbuf = 3; boolean flbreak = false; if (flendtext) { if (ixinbuf == 0) break; if ((ixinbuf == 1) || (ixinbuf == 2)) ctcharsinbuf = 1; else ctcharsinbuf = 2; ixinbuf = 3; flbreak = 1; } inbuf [ixinbuf++] = ch; if (ixinbuf == 4) { ixinbuf = 0; outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); origsize = htext.getSize(); htext.setSize(origsize + ctcharsinbuf); for (i = 0; i < ctcharsinbuf; i++) *htext.getMemory(origsize + i) = outbuf[i]; } if (flbreak) break; } } return 1; }