~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Frontier Kernel
Frontier/Common/source/base64.c

Version: ~ [ 10.0 ] ~

** Warning: Cannot open xref database.

1 2 /* $Id: base64.c,v 1.4 2005/01/24 02:22:13 terry_teague Exp $ */ 3 4 /****************************************************************************** 5 6 UserLand Frontier(tm) -- High performance Web content management, 7 object database, system-level and Internet scripting environment, 8 including source code editing and debugging. 9 10 Copyright (C) 1992-2004 UserLand Software, Inc. 11 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; either version 2 of the License, or 15 (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 26 ******************************************************************************/ 27 28 #include "frontier.h" 29 #include "standard.h" 30 31 #include "memory.h" 32 #include "lang.h" 33 #include "BASE64.H" 34 35 36 static char encodingTable [64] = { 37 38 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 39 40 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 41 42 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 43 44 'w','x','y','z','','1','2','3','4','5','6','7','8','9','+','/' 45 }; 46 47 48 static unsigned char gethandlechar (Handle h, unsigned long ix) { 49 50 return ((*h) [ix]); 51 } /*gethandlechar*/ 52 53 54 static void sethandlechar (Handle h, unsigned long ix, unsigned char ch) { 55 56 (*h) [ix] = ch; 57 } /*sethandlechar*/ 58 59 60 #define new_base64 1 61 62 #ifdef new_base64 63 64 boolean base64encodehandle (Handle htext, Handle h64, short linelength) { 65 66 /* 67 encode the handle. some funny stuff about linelength -- it only makes 68 sense to make it a multiple of 4. if it's not a multiple of 4, we make it 69 so (by only checking it every 4 characters. 70 71 further, if it's 0, we don't add any line breaks at all. 72 73 5.0a18 dmb: line breaks are /r, not /n 74 75 6.1d4 AR: updated to grow h64 in one go instead of once for every 76 three bytes of htext. 77 */ 78 79 unsigned long ixtext; 80 unsigned long lentext; 81 unsigned long len64; 82 unsigned long pos64 = 0; 83 long ctremaining; 84 unsigned char inbuf [3], outbuf [4]; 85 short i; 86 short charsonline = 0, ctcopy; 87 88 ixtext = 0; 89 90 lentext = gethandlesize (htext); 91 92 len64 = (lentext / 3) * 4; 93 94 if (lentext % 3 > 0) 95 len64 += 4; 96 97 if (linelength > 0) { /* add room for linebreaks */ 98 99 unsigned long ctquadruplets = linelength / 4; 100 101 if (linelength % 4 > 0) 102 ++ctquadruplets; 103 104 linelength = ctquadruplets * 4; 105 106 len64 += (len64 / linelength); 107 } 108 109 if (!sethandlesize (h64, len64)) 110 return (false); 111 112 while (true) { 113 114 ctremaining = lentext - ixtext; 115 116 if (ctremaining <= 0) 117 break; 118 119 for (i = 0; i < 3; i++) { 120 121 unsigned long ix = ixtext + i; 122 123 if (ix < lentext) 124 inbuf [i] = gethandlechar (htext, ix); 125 else 126 inbuf [i] = 0; 127 } /*for*/ 128 129 outbuf [0] = (inbuf [0] & 0xFC) >> 2; 130 131 outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); 132 133 outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); 134 135 outbuf [3] = inbuf [2] & 0x3F; 136 137 ctcopy = 4; 138 139 switch (ctremaining) { 140 141 case 1: 142 ctcopy = 2; 143 144 break; 145 146 case 2: 147 ctcopy = 3; 148 149 break; 150 } /*switch*/ 151 152 for (i = 0; i < ctcopy; i++) 153 sethandlechar (h64, pos64 + i, encodingTable [outbuf [i]]); 154 155 for (i = ctcopy; i < 4; i++) 156 sethandlechar (h64, pos64 + i, '='); 157 158 ixtext += 3; 159 160 charsonline += 4; 161 162 pos64 += 4; 163 164 if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/ 165 166 if (charsonline >= linelength) { 167 168 charsonline = 0; 169 170 sethandlechar (h64, pos64++, '\r'); 171 } 172 } 173 } /*while*/ 174 175 assert (pos64 == len64); /*there's a bug in here if this assertion doesn't hold*/ 176 177 return (true); 178 } /*encodehandle*/ 179 180 #elif 181 182 boolean base64encodehandle (Handle htext, Handle h64, short linelength) { 183 184 /* 185 encode the handle. some funny stuff about linelength -- it only makes 186 sense to make it a multiple of 4. if it's not a multiple of 4, we make it 187 so (by only checking it every 4 characters. 188 189 further, if it's 0, we don't add any line breaks at all. 190 191 5.0a18 dmb: line breaks are /r, not /n 192 */ 193 194 unsigned long ixtext; 195 unsigned long lentext; 196 unsigned long origsize; 197 long ctremaining; 198 unsigned char inbuf [3], outbuf [4]; 199 short i; 200 short charsonline = 0, ctcopy; 201 202 ixtext = 0; 203 204 lentext = gethandlesize (htext); 205 206 while (true) { 207 208 ctremaining = lentext - ixtext; 209 210 if (ctremaining <= 0) 211 break; 212 213 for (i = 0; i < 3; i++) { 214 215 unsigned long ix = ixtext + i; 216 217 if (ix < lentext) 218 inbuf [i] = gethandlechar (htext, ix); 219 else 220 inbuf [i] = 0; 221 } /*for*/ 222 223 outbuf [0] = (inbuf [0] & 0xFC) >> 2; 224 225 outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); 226 227 outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); 228 229 outbuf [3] = inbuf [2] & 0x3F; 230 231 origsize = gethandlesize (h64); 232 233 if (!sethandlesize (h64, origsize + 4)) 234 return (false); 235 236 ctcopy = 4; 237 238 switch (ctremaining) { 239 240 case 1: 241 ctcopy = 2; 242 243 break; 244 245 case 2: 246 ctcopy = 3; 247 248 break; 249 } /*switch*/ 250 251 for (i = 0; i < ctcopy; i++) 252 sethandlechar (h64, origsize + i, encodingTable [outbuf [i]]); 253 254 for (i = ctcopy; i < 4; i++) 255 sethandlechar (h64, origsize + i, '='); 256 257 ixtext += 3; 258 259 charsonline += 4; 260 261 if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/ 262 263 if (charsonline >= linelength) { 264 265 charsonline = 0; 266 267 origsize = gethandlesize (h64); 268 269 if (!sethandlesize (h64, origsize + 1)) 270 return (false); 271 272 sethandlechar (h64, origsize, '\r'); 273 } 274 } 275 } /*while*/ 276 277 return (true); 278 } /*encodehandle*/ 279 280 #endif 281 282 283 #ifdef new_base64 284 285 boolean base64decodehandle (Handle h64, Handle htext) { 286 287 unsigned long ixtext; 288 unsigned long lentext; 289 unsigned char ch; 290 unsigned char inbuf [4], outbuf [3]; 291 short ixinbuf; 292 boolean flendtext = false; 293 handlestream s; 294 295 ixtext = 0; 296 297 lentext = gethandlesize (h64); 298 299 ixinbuf = 0; 300 301 openhandlestream (htext, &s); 302 303 while (true) { 304 short ctcharsinbuf = 3; 305 306 if (ixtext >= lentext) 307 break; 308 309 ch = gethandlechar (h64, ixtext++); 310 311 if ((ch >= 'A') && (ch <= 'Z')) 312 ch = ch - 'A'; 313 314 else if ((ch >= 'a') && (ch <= 'z')) 315 ch = ch - 'a' + 26; 316 317 else if ((ch >= '') && (ch <= '9')) 318 ch = ch - '' + 52; 319 320 else if (ch == '+') 321 ch = 62; 322 323 else if (ch == '/') 324 ch = 63; 325 326 else if (ch == '=') /*no op -- can't ignore this one*/ 327 flendtext = true; 328 329 else 330 continue; 331 332 if (flendtext) { 333 334 if (ixinbuf == 0) 335 break; 336 337 if ((ixinbuf == 1) || (ixinbuf == 2)) 338 ctcharsinbuf = 1; 339 else 340 ctcharsinbuf = 2; 341 342 ixinbuf = 3; 343 } 344 345 inbuf [ixinbuf++] = ch; 346 347 if (ixinbuf == 4) { 348 349 ixinbuf = 0; 350 351 outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); 352 353 outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); 354 355 outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); 356 357 if (!writehandlestream (&s, outbuf, ctcharsinbuf)) 358 return (false); 359 } 360 361 if (flendtext) 362 break; 363 } /*while*/ 364 365 closehandlestream (&s); 366 367 return (true); 368 } /*decodehandle*/ 369 370 #elif 371 372 boolean base64decodehandle (Handle h64, Handle htext) { 373 374 unsigned long ixtext; 375 unsigned long lentext; 376 unsigned long origsize; 377 unsigned char ch; 378 unsigned char inbuf [4], outbuf [3]; 379 short i, ixinbuf; 380 boolean flignore; 381 boolean flendtext = false; 382 383 ixtext = 0; 384 385 lentext = gethandlesize (h64); 386 387 ixinbuf = 0; 388 389 while (true) { 390 391 if (ixtext >= lentext) 392 break; 393 394 ch = gethandlechar (h64, ixtext++); 395 396 flignore = false; 397 398 if ((ch >= 'A') && (ch <= 'Z')) 399 ch = ch - 'A'; 400 401 else if ((ch >= 'a') && (ch <= 'z')) 402 ch = ch - 'a' + 26; 403 404 else if ((ch >= '') && (ch <= '9')) 405 ch = ch - '' + 52; 406 407 else if (ch == '+') 408 ch = 62; 409 410 else if (ch == '=') /*no op -- can't ignore this one*/ 411 flendtext = true; 412 413 else if (ch == '/') 414 ch = 63; 415 416 else 417 flignore = true; 418 419 if (!flignore) { 420 421 short ctcharsinbuf = 3; 422 boolean flbreak = false; 423 424 if (flendtext) { 425 426 if (ixinbuf == 0) 427 break; 428 429 if ((ixinbuf == 1) || (ixinbuf == 2)) 430 ctcharsinbuf = 1; 431 else 432 ctcharsinbuf = 2; 433 434 ixinbuf = 3; 435 436 flbreak = true; 437 } 438 439 inbuf [ixinbuf++] = ch; 440 441 if (ixinbuf == 4) { 442 443 ixinbuf = 0; 444 445 outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); 446 447 outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); 448 449 outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); 450 451 origsize = gethandlesize (htext); 452 453 if (!sethandlesize (htext, origsize + ctcharsinbuf)) 454 return (false); 455 456 for (i = 0; i < ctcharsinbuf; i++) 457 sethandlechar (htext, origsize + i, outbuf [i]); 458 } 459 460 if (flbreak) 461 break; 462 } 463 } /*while*/ 464 465 return (true); 466 } /*decodehandle*/ 467 468 #endif 469 470 471 boolean base64encodeverb (hdltreenode hparam1, tyvaluerecord *vreturned) { 472 473 Handle h64, htext; 474 short linelength; 475 476 if (!gettextvalue (hparam1, 1, &htext)) 477 return (false); 478 479 flnextparamislast = true; 480 481 if (!getintvalue (hparam1, 2, &linelength)) 482 return (false); 483 484 if (!newemptyhandle (&h64)) 485 return (false); 486 487 if (!base64encodehandle (htext, h64, linelength)) { 488 489 disposehandle (h64); 490 491 return (false); 492 } 493 494 return (setheapvalue (h64, stringvaluetype, vreturned)); 495 } /*base64encodeverb*/ 496 497 498 boolean base64decodeverb (hdltreenode hparam1, tyvaluerecord *vreturned) { 499 500 /* 501 5.0.1 dmb: return a string, not an unknown binary type 502 */ 503 504 Handle h64, htext; 505 506 flnextparamislast = true; 507 508 if (!gettextvalue (hparam1, 1, &h64)) 509 return (false); 510 511 if (!newemptyhandle (&htext)) 512 return (false); 513 514 if (!base64decodehandle (h64, htext)) { 515 516 disposehandle (htext); 517 518 return (false); 519 } 520 521 return (setheapvalue (htext, stringvaluetype, vreturned)); 522 } /*base64decodeverb*/ 523 524 525

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.