xpcom/base/nsGZFileWriter.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xpcom/base/nsGZFileWriter.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,98 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "nsGZFileWriter.h"
    1.11 +#include "nsIFile.h"
    1.12 +#include "nsString.h"
    1.13 +#include "zlib.h"
    1.14 +
    1.15 +#ifdef XP_WIN
    1.16 +#include <io.h>
    1.17 +#define _dup dup
    1.18 +#else
    1.19 +#include <unistd.h>
    1.20 +#endif
    1.21 +
    1.22 +NS_IMPL_ISUPPORTS(nsGZFileWriter, nsIGZFileWriter)
    1.23 +
    1.24 +nsGZFileWriter::nsGZFileWriter()
    1.25 +  : mInitialized(false)
    1.26 +  , mFinished(false)
    1.27 +{}
    1.28 +
    1.29 +nsGZFileWriter::~nsGZFileWriter()
    1.30 +{
    1.31 +  if (mInitialized && !mFinished) {
    1.32 +    Finish();
    1.33 +  }
    1.34 +}
    1.35 +
    1.36 +NS_IMETHODIMP
    1.37 +nsGZFileWriter::Init(nsIFile* aFile)
    1.38 +{
    1.39 +  if (NS_WARN_IF(mInitialized) ||
    1.40 +      NS_WARN_IF(mFinished))
    1.41 +    return NS_ERROR_FAILURE;
    1.42 +
    1.43 +  // Get a FILE out of our nsIFile.  Convert that into a file descriptor which
    1.44 +  // gzip can own.  Then close our FILE, leaving only gzip's fd open.
    1.45 +
    1.46 +  FILE* file;
    1.47 +  nsresult rv = aFile->OpenANSIFileDesc("wb", &file);
    1.48 +  if (NS_WARN_IF(NS_FAILED(rv)))
    1.49 +    return rv;
    1.50 +
    1.51 +  mGZFile = gzdopen(dup(fileno(file)), "wb");
    1.52 +  fclose(file);
    1.53 +
    1.54 +  // gzdopen returns nullptr on error.
    1.55 +  if (NS_WARN_IF(!mGZFile))
    1.56 +    return NS_ERROR_FAILURE;
    1.57 +
    1.58 +  mInitialized = true;
    1.59 +
    1.60 +  return NS_OK;
    1.61 +}
    1.62 +
    1.63 +NS_IMETHODIMP
    1.64 +nsGZFileWriter::Write(const nsACString& aStr)
    1.65 +{
    1.66 +  if (NS_WARN_IF(!mInitialized) ||
    1.67 +      NS_WARN_IF(mFinished))
    1.68 +    return NS_ERROR_FAILURE;
    1.69 +
    1.70 +  // gzwrite uses a return value of 0 to indicate failure.  Otherwise, it
    1.71 +  // returns the number of uncompressed bytes written.  To ensure we can
    1.72 +  // distinguish between success and failure, don't call gzwrite when we have 0
    1.73 +  // bytes to write.
    1.74 +  if (aStr.IsEmpty()) {
    1.75 +    return NS_OK;
    1.76 +  }
    1.77 +
    1.78 +  // gzwrite never does a short write -- that is, the return value should
    1.79 +  // always be either 0 or aStr.Length(), and we shouldn't have to call it
    1.80 +  // multiple times in order to get it to read the whole buffer.
    1.81 +  int rv = gzwrite(mGZFile, aStr.BeginReading(), aStr.Length());
    1.82 +  if (NS_WARN_IF(rv != static_cast<int>(aStr.Length())))
    1.83 +    return NS_ERROR_FAILURE;
    1.84 +
    1.85 +  return NS_OK;
    1.86 +}
    1.87 +
    1.88 +NS_IMETHODIMP
    1.89 +nsGZFileWriter::Finish()
    1.90 +{
    1.91 +  if (NS_WARN_IF(!mInitialized) ||
    1.92 +      NS_WARN_IF(mFinished))
    1.93 +    return NS_ERROR_FAILURE;
    1.94 +
    1.95 +  mFinished = true;
    1.96 +  gzclose(mGZFile);
    1.97 +
    1.98 +  // Ignore errors from gzclose; it's not like there's anything we can do about
    1.99 +  // it, at this point!
   1.100 +  return NS_OK;
   1.101 +}

mercurial