~ubuntu-branches/ubuntu/precise/p7zip/precise-updates

« back to all changes in this revision

Viewing changes to CPP/7zip/Compress/ArjDecoder2.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mohammed Adnène Trojette
  • Date: 2009-02-14 20:12:27 UTC
  • mfrom: (1.1.11 upstream) (2.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090214201227-go63qxm9ozfdma60
Tags: 4.65~dfsg.1-1
* New upstream release.
* Remove wx2.8 Build-Depends added by mistakes (7zG is not yet
  intended to be built).
* Use dh_clean without -k.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ArjDecoder2.cpp
 
2
 
 
3
#include "StdAfx.h"
 
4
 
 
5
#include "ArjDecoder2.h"
 
6
 
 
7
namespace NCompress{
 
8
namespace NArj {
 
9
namespace NDecoder2 {
 
10
 
 
11
static const UInt32 kHistorySize = 26624;
 
12
static const UInt32 kMatchMinLen = 3;
 
13
 
 
14
HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
 
15
    const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo * /* progress */)
 
16
{
 
17
  if (outSize == NULL)
 
18
    return E_INVALIDARG;
 
19
 
 
20
  if (!m_OutWindowStream.Create(kHistorySize))
 
21
    return E_OUTOFMEMORY;
 
22
  if (!m_InBitStream.Create(1 << 20))
 
23
    return E_OUTOFMEMORY;
 
24
 
 
25
  UInt64 pos = 0;
 
26
  m_OutWindowStream.SetStream(outStream);
 
27
  m_OutWindowStream.Init(false);
 
28
  m_InBitStream.SetStream(inStream);
 
29
  m_InBitStream.Init();
 
30
  CCoderReleaser coderReleaser(this);
 
31
 
 
32
  while(pos < *outSize)
 
33
  {
 
34
    const UInt32 kStartWidth = 0;
 
35
    const UInt32 kStopWidth = 7;
 
36
    UInt32 power = 1 << kStartWidth;
 
37
    UInt32 width;
 
38
    UInt32 len = 0;
 
39
    for (width = kStartWidth; width < kStopWidth; width++)
 
40
    {
 
41
      if (m_InBitStream.ReadBits(1) == 0)
 
42
        break;
 
43
      len += power;
 
44
      power <<= 1;
 
45
    }
 
46
    if (width != 0)
 
47
      len += m_InBitStream.ReadBits(width);
 
48
    if (len == 0)
 
49
    {
 
50
      m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
 
51
      pos++;
 
52
      continue;
 
53
    }
 
54
    else
 
55
    {
 
56
      len = len - 1 + kMatchMinLen;
 
57
      const UInt32 kStartWidth = 9;
 
58
      const UInt32 kStopWidth = 13;
 
59
      UInt32 power = 1 << kStartWidth;
 
60
      UInt32 width;
 
61
      UInt32 distance = 0;
 
62
      for (width = kStartWidth; width < kStopWidth; width++)
 
63
      {
 
64
        if (m_InBitStream.ReadBits(1) == 0)
 
65
          break;
 
66
        distance += power;
 
67
        power <<= 1;
 
68
      }
 
69
      if (width != 0)
 
70
        distance += m_InBitStream.ReadBits(width);
 
71
      if (distance >= pos)
 
72
        return S_FALSE;
 
73
      m_OutWindowStream.CopyBlock(distance, len);
 
74
        pos += len;
 
75
    }
 
76
  }
 
77
  coderReleaser.NeedFlush = false;
 
78
  return m_OutWindowStream.Flush();
 
79
}
 
80
 
 
81
STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
 
82
    const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
 
83
{
 
84
  try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
 
85
  catch(const CInBufferException &e) { return e.ErrorCode; }
 
86
  catch(const CLzOutWindowException &e) { return e.ErrorCode; }
 
87
  catch(...) { return S_FALSE; }
 
88
}
 
89
 
 
90
}}}