js/src/vm/Compression.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "vm/Compression.h"
     9 #include "js/Utility.h"
    11 using namespace js;
    13 #if USE_ZLIB
    14 static void *
    15 zlib_alloc(void *cx, uInt items, uInt size)
    16 {
    17     return js_calloc(items, size);
    18 }
    20 static void
    21 zlib_free(void *cx, void *addr)
    22 {
    23     js_free(addr);
    24 }
    26 Compressor::Compressor(const unsigned char *inp, size_t inplen)
    27     : inp(inp),
    28       inplen(inplen),
    29       outbytes(0),
    30       initialized(false)
    31 {
    32     JS_ASSERT(inplen > 0);
    33     zs.opaque = nullptr;
    34     zs.next_in = (Bytef *)inp;
    35     zs.avail_in = 0;
    36     zs.next_out = nullptr;
    37     zs.avail_out = 0;
    38     zs.zalloc = zlib_alloc;
    39     zs.zfree = zlib_free;
    40 }
    43 Compressor::~Compressor()
    44 {
    45     if (initialized) {
    46         int ret = deflateEnd(&zs);
    47         if (ret != Z_OK) {
    48             // If we finished early, we can get a Z_DATA_ERROR.
    49             JS_ASSERT(ret == Z_DATA_ERROR);
    50             JS_ASSERT(uInt(zs.next_in - inp) < inplen || !zs.avail_out);
    51         }
    52     }
    53 }
    55 bool
    56 Compressor::init()
    57 {
    58     if (inplen >= UINT32_MAX)
    59         return false;
    60     // zlib is slow and we'd rather be done compression sooner
    61     // even if it means decompression is slower which penalizes
    62     // Function.toString()
    63     int ret = deflateInit(&zs, Z_BEST_SPEED);
    64     if (ret != Z_OK) {
    65         JS_ASSERT(ret == Z_MEM_ERROR);
    66         return false;
    67     }
    68     initialized = true;
    69     return true;
    70 }
    72 void
    73 Compressor::setOutput(unsigned char *out, size_t outlen)
    74 {
    75     JS_ASSERT(outlen > outbytes);
    76     zs.next_out = out + outbytes;
    77     zs.avail_out = outlen - outbytes;
    78 }
    80 Compressor::Status
    81 Compressor::compressMore()
    82 {
    83     JS_ASSERT(zs.next_out);
    84     uInt left = inplen - (zs.next_in - inp);
    85     bool done = left <= CHUNKSIZE;
    86     if (done)
    87         zs.avail_in = left;
    88     else if (zs.avail_in == 0)
    89         zs.avail_in = CHUNKSIZE;
    90     Bytef *oldout = zs.next_out;
    91     int ret = deflate(&zs, done ? Z_FINISH : Z_NO_FLUSH);
    92     outbytes += zs.next_out - oldout;
    93     if (ret == Z_MEM_ERROR) {
    94         zs.avail_out = 0;
    95         return OOM;
    96     }
    97     if (ret == Z_BUF_ERROR || (done && ret == Z_OK)) {
    98         JS_ASSERT(zs.avail_out == 0);
    99         return MOREOUTPUT;
   100     }
   101     JS_ASSERT_IF(!done, ret == Z_OK);
   102     JS_ASSERT_IF(done, ret == Z_STREAM_END);
   103     return done ? DONE : CONTINUE;
   104 }
   106 bool
   107 js::DecompressString(const unsigned char *inp, size_t inplen, unsigned char *out, size_t outlen)
   108 {
   109     JS_ASSERT(inplen <= UINT32_MAX);
   110     z_stream zs;
   111     zs.zalloc = zlib_alloc;
   112     zs.zfree = zlib_free;
   113     zs.opaque = nullptr;
   114     zs.next_in = (Bytef *)inp;
   115     zs.avail_in = inplen;
   116     zs.next_out = out;
   117     JS_ASSERT(outlen);
   118     zs.avail_out = outlen;
   119     int ret = inflateInit(&zs);
   120     if (ret != Z_OK) {
   121         JS_ASSERT(ret == Z_MEM_ERROR);
   122         return false;
   123     }
   124     ret = inflate(&zs, Z_FINISH);
   125     JS_ASSERT(ret == Z_STREAM_END);
   126     ret = inflateEnd(&zs);
   127     JS_ASSERT(ret == Z_OK);
   128     return true;
   129 }
   130 #endif /* USE_ZLIB */

mercurial