intl/uconv/util/ugen.c

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "unicpriv.h"
     6 /*=================================================================================
     8 =================================================================================*/
     9 typedef  int (*uSubGeneratorFunc) (uint16_t in, unsigned char* out);
    10 /*=================================================================================
    12 =================================================================================*/
    14 typedef int (*uGeneratorFunc) (
    15                                int32_t*    state,
    16                                uint16_t    in,
    17                                unsigned char*  out,
    18                                uint32_t     outbuflen,
    19                                uint32_t*    outlen
    20                                );
    22 int uGenerate(
    23               uScanClassID scanClass,
    24               int32_t*    state,
    25               uint16_t    in,
    26               unsigned char*  out,
    27               uint32_t     outbuflen,
    28               uint32_t*    outlen
    29               );
    31 #define uSubGenerator(sub,in,out) (* m_subgenerator[sub])((in),(out))
    33 int uCheckAndGenAlways1Byte(
    34                                int32_t*   state,
    35                                uint16_t   in,
    36                                unsigned char* out,
    37                                uint32_t    outbuflen,
    38                                uint32_t*   outlen
    39                                );
    40 int uCheckAndGenAlways2Byte(
    41                             int32_t*   state,
    42                             uint16_t   in,
    43                             unsigned char* out,
    44                             uint32_t    outbuflen,
    45                             uint32_t*   outlen
    46                             );
    47 int uCheckAndGenAlways2ByteShiftGR(
    48                                    int32_t*    state,
    49                                    uint16_t    in,
    50                                    unsigned char*  out,
    51                                    uint32_t     outbuflen,
    52                                    uint32_t*    outlen
    53                                    );
    54 int uGenerateShift(
    55                    uShiftOutTable   *shift,
    56                    int32_t*   state,
    57                    uint16_t   in,
    58                    unsigned char* out,
    59                    uint32_t    outbuflen,
    60                    uint32_t*   outlen
    61                    );
    62 int uCheckAndGen2ByteGRPrefix8F(
    63                                 int32_t*   state,
    64                                 uint16_t   in,
    65                                 unsigned char* out,
    66                                 uint32_t    outbuflen,
    67                                 uint32_t*   outlen
    68                                 );
    69 int uCheckAndGen2ByteGRPrefix8EA2(
    70                                   int32_t*   state,
    71                                   uint16_t   in,
    72                                   unsigned char* out,
    73                                   uint32_t    outbuflen,
    74                                   uint32_t*   outlen
    75                                   );
    77 int uCheckAndGen2ByteGRPrefix8EA3(
    78                                   int32_t*   state,
    79                                   uint16_t   in,
    80                                   unsigned char* out,
    81                                   uint32_t    outbuflen,
    82                                   uint32_t*   outlen
    83                                   );
    85 int uCheckAndGen2ByteGRPrefix8EA4(
    86                                   int32_t*   state,
    87                                   uint16_t   in,
    88                                   unsigned char* out,
    89                                   uint32_t    outbuflen,
    90                                   uint32_t*   outlen
    91                                   );
    93 int uCheckAndGen2ByteGRPrefix8EA5(
    94                                   int32_t*   state,
    95                                   uint16_t   in,
    96                                   unsigned char* out,
    97                                   uint32_t    outbuflen,
    98                                   uint32_t*   outlen
    99                                   );
   101 int uCheckAndGen2ByteGRPrefix8EA6(
   102                                   int32_t*   state,
   103                                   uint16_t   in,
   104                                   unsigned char* out,
   105                                   uint32_t    outbuflen,
   106                                   uint32_t*   outlen
   107                                   );
   109 int uCheckAndGen2ByteGRPrefix8EA7(
   110                                   int32_t*   state,
   111                                   uint16_t   in,
   112                                   unsigned char* out,
   113                                   uint32_t    outbuflen,
   114                                   uint32_t*   outlen
   115                                   );
   116 int uCnGAlways8BytesDecomposedHangul(
   117                                      int32_t*    state,
   118                                      uint16_t    in,
   119                                      unsigned char*  out,
   120                                      uint32_t     outbuflen,
   121                                      uint32_t*    outlen
   122                                      );
   124 int uCheckAndGenJohabHangul(
   125                             int32_t*   state,
   126                             uint16_t   in,
   127                             unsigned char* out,
   128                             uint32_t    outbuflen,
   129                             uint32_t*   outlen
   130                             );
   132 int uCheckAndGenJohabSymbol(
   133                             int32_t*   state,
   134                             uint16_t   in,
   135                             unsigned char* out,
   136                             uint32_t    outbuflen,
   137                             uint32_t*   outlen
   138                             );
   141 int uCheckAndGen4BytesGB18030(
   142                               int32_t*   state,
   143                               uint16_t   in,
   144                               unsigned char* out,
   145                               uint32_t    outbuflen,
   146                               uint32_t*   outlen
   147                               );
   149 int uGenAlways2Byte(
   150                     uint16_t    in,
   151                     unsigned char* out
   152                     );
   153 int uGenAlways2ByteShiftGR(
   154                            uint16_t     in,
   155                            unsigned char*  out
   156                            );
   157 int uGenAlways1Byte(
   158                     uint16_t    in,
   159                     unsigned char* out
   160                     );
   161 int uGenAlways1BytePrefix8E(
   162                             uint16_t    in,
   163                             unsigned char* out
   164                             );
   165 /*=================================================================================
   167 =================================================================================*/
   168 const uGeneratorFunc m_generator[uNumOfCharsetType] =
   169 {
   170     uCheckAndGenAlways1Byte,
   171     uCheckAndGenAlways2Byte,
   172     uCheckAndGenAlways2ByteShiftGR,
   173     uCheckAndGen2ByteGRPrefix8F,
   174     uCheckAndGen2ByteGRPrefix8EA2,
   175     uCheckAndGen2ByteGRPrefix8EA3,
   176     uCheckAndGen2ByteGRPrefix8EA4,
   177     uCheckAndGen2ByteGRPrefix8EA5,
   178     uCheckAndGen2ByteGRPrefix8EA6,
   179     uCheckAndGen2ByteGRPrefix8EA7,
   180     uCnGAlways8BytesDecomposedHangul,
   181     uCheckAndGenJohabHangul,
   182     uCheckAndGenJohabSymbol,
   183     uCheckAndGen4BytesGB18030,
   184     uCheckAndGenAlways2Byte   /* place-holder for GR128 */
   185 };
   187 /*=================================================================================
   189 =================================================================================*/
   191 const uSubGeneratorFunc m_subgenerator[uNumOfCharType] =
   192 {
   193     uGenAlways1Byte,
   194     uGenAlways2Byte,
   195     uGenAlways2ByteShiftGR,
   196     uGenAlways1BytePrefix8E
   197 };
   198 /*=================================================================================
   200 =================================================================================*/
   201 int uGenerate(
   202               uScanClassID scanClass,
   203               int32_t*    state,
   204               uint16_t    in,
   205               unsigned char*  out,
   206               uint32_t     outbuflen,
   207               uint32_t*    outlen
   208               )
   209 {
   210     return (* m_generator[scanClass]) (state,in,out,outbuflen,outlen);
   211 }
   212 /*=================================================================================
   214 =================================================================================*/
   215 int uGenAlways1Byte(
   216                     uint16_t    in,
   217                     unsigned char* out
   218                     )
   219 {
   220     out[0] = (unsigned char)in;
   221     return 1;
   222 }
   224 /*=================================================================================
   226 =================================================================================*/
   227 int uGenAlways2Byte(
   228                     uint16_t    in,
   229                     unsigned char* out
   230                     )
   231 {
   232     out[0] = (unsigned char)((in >> 8) & 0xff);
   233     out[1] = (unsigned char)(in & 0xff);
   234     return 1;
   235 }
   236 /*=================================================================================
   238 =================================================================================*/
   239 int uGenAlways2ByteShiftGR(
   240                            uint16_t     in,
   241                            unsigned char*  out
   242                            )
   243 {
   244     out[0] = (unsigned char)(((in >> 8) & 0xff) | 0x80);
   245     out[1] = (unsigned char)((in & 0xff) | 0x80);
   246     return 1;
   247 }
   248 /*=================================================================================
   250 =================================================================================*/
   251 int uGenAlways1BytePrefix8E(
   252                             uint16_t    in,
   253                             unsigned char* out
   254                             )
   255 {
   256     out[0] = 0x8E;
   257     out[1] = (unsigned char)(in  & 0xff);
   258     return 1;
   259 }
   260 /*=================================================================================
   262 =================================================================================*/
   263 int uCheckAndGenAlways1Byte(
   264                             int32_t*   state,
   265                             uint16_t   in,
   266                             unsigned char* out,
   267                             uint32_t    outbuflen,
   268                             uint32_t*   outlen
   269                             )
   270 {
   271     /* Don't check inlen. The caller should ensure it is larger than 0 */
   272     /*  Oops, I don't agree. Code changed to check every time. [CATA] */
   273     if(outbuflen < 1)
   274         return 0;
   275     else
   276     {
   277         *outlen = 1;
   278         out[0] = in & 0xff;
   279         return 1;
   280     }
   281 }
   283 /*=================================================================================
   285 =================================================================================*/
   286 int uCheckAndGenAlways2Byte(
   287                             int32_t*   state,
   288                             uint16_t   in,
   289                             unsigned char* out,
   290                             uint32_t    outbuflen,
   291                             uint32_t*   outlen
   292                             )
   293 {
   294     if(outbuflen < 2)
   295         return 0;
   296     else
   297     {
   298         *outlen = 2;
   299         out[0] = ((in >> 8 ) & 0xff);
   300         out[1] = in  & 0xff;
   301         return 1;
   302     }
   303 }
   304 /*=================================================================================
   306 =================================================================================*/
   307 int uCheckAndGenAlways2ByteShiftGR(
   308                                    int32_t*    state,
   309                                    uint16_t    in,
   310                                    unsigned char*  out,
   311                                    uint32_t     outbuflen,
   312                                    uint32_t*    outlen
   313                                    )
   314 {
   315     if(outbuflen < 2)
   316         return 0;
   317     else
   318     {
   319         *outlen = 2;
   320         out[0] = ((in >> 8 ) & 0xff) | 0x80;
   321         out[1] = (in  & 0xff)  | 0x80;
   322         return 1;
   323     }
   324 }
   325 /*=================================================================================
   327 =================================================================================*/
   328 int uGenerateShift(
   329                    uShiftOutTable   *shift,
   330                    int32_t*   state,
   331                    uint16_t   in,
   332                    unsigned char* out,
   333                    uint32_t    outbuflen,
   334                    uint32_t*   outlen
   335                    )
   336 {
   337     int16_t i;
   338     const uShiftOutCell* cell = &(shift->shiftcell[0]);
   339     int16_t itemnum = shift->numOfItem;
   340     unsigned char inH, inL;
   341     inH = (in >> 8) & 0xff;
   342     inL = (in & 0xff );
   343     for(i=0;i<itemnum;i++)
   344     {
   345         if( ( inL >=  cell[i].shiftout_MinLB) &&
   346             ( inL <=  cell[i].shiftout_MaxLB) &&
   347             ( inH >=  cell[i].shiftout_MinHB) &&
   348             ( inH <=  cell[i].shiftout_MaxHB) )
   349         {
   350             if(outbuflen < cell[i].reserveLen)
   351               {
   352                 return 0;
   353               }
   354             else
   355             {
   356                 *outlen = cell[i].reserveLen;
   357                 return (uSubGenerator(cell[i].classID,in,out));
   358             }
   359         }
   360     }
   361     return 0;
   362 }
   363 /*=================================================================================
   365 =================================================================================*/
   366 int uCheckAndGen2ByteGRPrefix8F(int32_t*   state,
   367                                 uint16_t   in,
   368                                 unsigned char* out,
   369                                 uint32_t    outbuflen,
   370                                 uint32_t*   outlen
   371                                 )
   372 {
   373     if(outbuflen < 3)
   374         return 0;
   375     else
   376     {
   377         *outlen = 3;
   378         out[0] = 0x8F;
   379         out[1] = ((in >> 8 ) & 0xff) | 0x80;
   380         out[2] = (in  & 0xff)  | 0x80;
   381         return 1;
   382     }
   383 }
   384 /*=================================================================================
   386 =================================================================================*/
   387 int uCheckAndGen2ByteGRPrefix8EA2(int32_t*   state,
   388                                   uint16_t   in,
   389                                   unsigned char* out,
   390                                   uint32_t    outbuflen,
   391                                   uint32_t*   outlen
   392                                   )
   393 {
   394     if(outbuflen < 4)
   395         return 0;
   396     else
   397     {
   398         *outlen = 4;
   399         out[0] = 0x8E;
   400         out[1] = 0xA2;
   401         out[2] = ((in >> 8 ) & 0xff) | 0x80;
   402         out[3] = (in  & 0xff)  | 0x80;
   403         return 1;
   404     }
   405 }
   408 /*=================================================================================
   410 =================================================================================*/
   411 int uCheckAndGen2ByteGRPrefix8EA3(int32_t*   state,
   412                                   uint16_t   in,
   413                                   unsigned char* out,
   414                                   uint32_t    outbuflen,
   415                                   uint32_t*   outlen
   416                                   )
   417 {
   418     if(outbuflen < 4)
   419         return 0;
   420     else
   421     {
   422         *outlen = 4;
   423         out[0] = 0x8E;
   424         out[1] = 0xA3;
   425         out[2] = ((in >> 8 ) & 0xff) | 0x80;
   426         out[3] = (in  & 0xff)  | 0x80;
   427         return 1;
   428     }
   429 }
   430 /*=================================================================================
   432 =================================================================================*/
   433 int uCheckAndGen2ByteGRPrefix8EA4(int32_t*   state,
   434                                   uint16_t   in,
   435                                   unsigned char* out,
   436                                   uint32_t    outbuflen,
   437                                   uint32_t*   outlen
   438                                   )
   439 {
   440     if(outbuflen < 4)
   441         return 0;
   442     else
   443     {
   444         *outlen = 4;
   445         out[0] = 0x8E;
   446         out[1] = 0xA4;
   447         out[2] = ((in >> 8 ) & 0xff) | 0x80;
   448         out[3] = (in  & 0xff)  | 0x80;
   449         return 1;
   450     }
   451 }
   452 /*=================================================================================
   454 =================================================================================*/
   455 int uCheckAndGen2ByteGRPrefix8EA5(int32_t*   state,
   456                                   uint16_t   in,
   457                                   unsigned char* out,
   458                                   uint32_t    outbuflen,
   459                                   uint32_t*   outlen
   460                                   )
   461 {
   462     if(outbuflen < 4)
   463         return 0;
   464     else
   465     {
   466         *outlen = 4;
   467         out[0] = 0x8E;
   468         out[1] = 0xA5;
   469         out[2] = ((in >> 8 ) & 0xff) | 0x80;
   470         out[3] = (in  & 0xff)  | 0x80;
   471         return 1;
   472     }
   473 }
   474 /*=================================================================================
   476 =================================================================================*/
   477 int uCheckAndGen2ByteGRPrefix8EA6(int32_t*   state,
   478                                   uint16_t   in,
   479                                   unsigned char* out,
   480                                   uint32_t    outbuflen,
   481                                   uint32_t*   outlen
   482                                   )
   483 {
   484     if(outbuflen < 4)
   485         return 0;
   486     else
   487     {
   488         *outlen = 4;
   489         out[0] = 0x8E;
   490         out[1] = 0xA6;
   491         out[2] = ((in >> 8 ) & 0xff) | 0x80;
   492         out[3] = (in  & 0xff)  | 0x80;
   493         return 1;
   494     }
   495 }
   496 /*=================================================================================
   498 =================================================================================*/
   499 int uCheckAndGen2ByteGRPrefix8EA7(int32_t*   state,
   500                                   uint16_t   in,
   501                                   unsigned char* out,
   502                                   uint32_t    outbuflen,
   503                                   uint32_t*   outlen
   504                                   )
   505 {
   506     if(outbuflen < 4)
   507         return 0;
   508     else
   509     {
   510         *outlen = 4;
   511         out[0] = 0x8E;
   512         out[1] = 0xA7;
   513         out[2] = ((in >> 8 ) & 0xff) | 0x80;
   514         out[3] = (in  & 0xff)  | 0x80;
   515         return 1;
   516     }
   517 }
   518 /*=================================================================================
   520 =================================================================================*/
   521 #define SBase 0xAC00
   522 #define LCount 19
   523 #define VCount 21
   524 #define TCount 28
   525 #define NCount (VCount * TCount)
   526 /*=================================================================================
   528 =================================================================================*/
   529 int uCnGAlways8BytesDecomposedHangul(
   530                                      int32_t*    state,
   531                                      uint16_t    in,
   532                                      unsigned char*  out,
   533                                      uint32_t     outbuflen,
   534                                      uint32_t*    outlen
   535                                      )
   536 {
   537     static const uint8_t lMap[LCount] = {
   538         0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xa9, 0xb1, 0xb2, 0xb3, 0xb5,
   539             0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe
   540     };
   542     static const uint8_t tMap[TCount] = {
   543         0xd4, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa9, 0xaa, 
   544             0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb4, 0xb5, 
   545             0xb6, 0xb7, 0xb8, 0xba, 0xbb, 0xbc, 0xbd, 0xbe
   546     };
   548     uint16_t SIndex, LIndex, VIndex, TIndex;
   550     if(outbuflen < 8)
   551         return 0;
   553     /* the following line are copy from Unicode 2.0 page 3-13 */
   554     /* item 1 of Hangul Syllabel Decomposition */
   555     SIndex =  in - SBase;
   557     /* the following lines are copy from Unicode 2.0 page 3-14 */
   558     /* item 2 of Hangul Syllabel Decomposition w/ modification */
   559     LIndex = SIndex / NCount;
   560     VIndex = (SIndex % NCount) / TCount;
   561     TIndex = SIndex % TCount;
   563     /* 
   564      * A Hangul syllable not enumerated in KS X 1001 is represented
   565      * by a sequence of 8 bytes beginning with Hangul-filler
   566      * (0xA4D4 in EUC-KR and 0x2454 in ISO-2022-KR) followed by three 
   567      * Jamos (2 bytes each the first of which is 0xA4 in EUC-KR) making 
   568      * up the syllable.  ref. KS X 1001:1998 Annex 3
   569      */
   570     *outlen = 8;
   571     out[0] = out[2] = out[4] = out[6] = 0xa4;
   572     out[1] = 0xd4;
   573     out[3] = lMap[LIndex] ;
   574     out[5] = (VIndex + 0xbf);
   575     out[7] = tMap[TIndex];
   577     return 1;
   578 }
   580 int uCheckAndGenJohabHangul(
   581                             int32_t*   state,
   582                             uint16_t   in,
   583                             unsigned char* out,
   584                             uint32_t    outbuflen,
   585                             uint32_t*   outlen
   586                             )
   587 {
   588     if(outbuflen < 2)
   589         return 0;
   590     else
   591     {
   592     /*
   593     See Table 4-45 (page 183) of CJKV Information Processing
   594     for detail explanation of the following table.
   595         */
   596         /*
   597         static const uint8_t lMap[LCount] = {
   598         2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
   599         };
   600         Therefore lMap[i] == i+2;
   601         */
   603         static const uint8_t vMap[VCount] = {
   604             /* no 0,1,2 */
   605             3,4,5,6,7,            /* no 8,9   */
   606                 10,11,12,13,14,15,    /* no 16,17 */
   607                 18,19,20,21,22,23,    /* no 24,25 */
   608                 26,27,28,29
   609         };
   610         static const uint8_t tMap[TCount] = {
   611             1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17, /* no 18 */
   612                 19,20,21,22,23,24,25,26,27,28,29
   613         };
   614         uint16_t SIndex, LIndex, VIndex, TIndex, ch;
   615         /* the following line are copy from Unicode 2.0 page 3-13 */
   616         /* item 1 of Hangul Syllabel Decomposition */
   617         SIndex =  in - SBase;
   619         /* the following lines are copy from Unicode 2.0 page 3-14 */
   620         /* item 2 of Hangul Syllabel Decomposition w/ modification */
   621         LIndex = SIndex / NCount;
   622         VIndex = (SIndex % NCount) / TCount;
   623         TIndex = SIndex % TCount;
   625         *outlen = 2;
   626         ch = 0x8000 | 
   627             ((LIndex+2)<<10) | 
   628             (vMap[VIndex]<<5)| 
   629             tMap[TIndex];
   630         out[0] = (ch >> 8);
   631         out[1] = ch & 0x00FF;
   632 #if 0
   633         printf("Johab Hangul %x %x in=%x L=%d V=%d T=%d\n", out[0], out[1], in, LIndex, VIndex, TIndex); 
   634 #endif 
   635         return 1;
   636     }
   637 }
   638 int uCheckAndGenJohabSymbol(
   639                             int32_t*   state,
   640                             uint16_t   in,
   641                             unsigned char* out,
   642                             uint32_t    outbuflen,
   643                             uint32_t*   outlen
   644                             )
   645 {
   646     if(outbuflen < 2)
   647         return 0;
   648     else
   649     {
   650     /* The following code are based on the Perl code listed under
   651     * "ISO-2022-KR or EUC-KR to Johab Conversion" (page 1013)
   652     * in the book "CJKV Information Processing" by 
   653     * Ken Lunde <lunde@adobe.com>
   654     *
   655     * sub convert2johab($) { # Convert ISO-2022-KR or EUC-KR to Johab
   656     *  my @euc = unpack("C*", $_[0]);
   657     *  my ($fe_off, $hi_off, $lo_off) = (0,0,1);
   658     *  my @out = ();
   659     *  while(($hi, $lo) = splice(@euc, 0, 2)) {
   660     *    $hi &= 127; $lo &= 127;
   661     *    $fe_off = 21 if $hi == 73;
   662     *    $fe_off = 34 if $hi == 126;
   663     *    ($hi_off, $lo_off) = ($lo_off, $hi_off) if ($hi <74 or $hi >125);
   664     *    push(@out, ((($hi+$hi_off) >> 1)+ ($hi <74 ? 200:187)- $fe_off),
   665     *      $lo + ((($hi+$lo_off) & 1) ? ($lo > 110 ? 34:16):128));    
   666     *  }
   667     *  return pack("C*", @out);
   668         */
   670         unsigned char fe_off = 0;
   671         unsigned char hi_off = 0;
   672         unsigned char lo_off = 1;
   673         unsigned char hi = (in >> 8) & 0x7F;
   674         unsigned char lo = in & 0x7F;
   675         if(73 == hi)
   676             fe_off = 21;
   677         if(126 == hi)
   678             fe_off = 34;
   679         if( (hi < 74) || ( hi > 125) )
   680         {
   681             hi_off = 1;
   682             lo_off = 0;
   683         }
   684         *outlen = 2;
   685         out[0] =  ((hi+hi_off) >> 1) + ((hi<74) ? 200 : 187 ) - fe_off;
   686         out[1] =  lo + (((hi+lo_off) & 1) ? ((lo > 110) ? 34 : 16) : 
   687         128);
   688 #if 0
   689         printf("Johab Symbol %x %x in=%x\n", out[0], out[1], in); 
   690 #endif
   691         return 1;
   692     }
   693 }
   694 int uCheckAndGen4BytesGB18030(
   695                               int32_t*   state,
   696                               uint16_t   in,
   697                               unsigned char* out,
   698                               uint32_t    outbuflen,
   699                               uint32_t*   outlen
   700                               )
   701 {
   702     if(outbuflen < 4)
   703         return 0;
   704     out[0] = (in / (10*126*10)) + 0x81;
   705     in %= (10*126*10);
   706     out[1] = (in / (10*126)) + 0x30;
   707     in %= (10*126);
   708     out[2] = (in / (10)) + 0x81;
   709     out[3] = (in % 10) + 0x30;
   710     *outlen = 4;
   711     return 1;
   712 }

mercurial