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

« back to all changes in this revision

Viewing changes to CPP/7zip/Compress/Arj/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
 
// Arj/Decoder2.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 kMatchMaxLen = 256;
13
 
static const UInt32 kMatchMinLen = 3;
14
 
 
15
 
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
16
 
    ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
17
 
    ICompressProgressInfo * /* progress */)
18
 
{
19
 
  if (outSize == NULL)
20
 
    return E_INVALIDARG;
21
 
 
22
 
  if (!m_OutWindowStream.Create(kHistorySize))
23
 
    return E_OUTOFMEMORY; 
24
 
  if (!m_InBitStream.Create(1 << 20))
25
 
    return E_OUTOFMEMORY;
26
 
 
27
 
  UInt64 pos = 0;
28
 
  m_OutWindowStream.SetStream(outStream);
29
 
  m_OutWindowStream.Init(false);
30
 
  m_InBitStream.SetStream(inStream);
31
 
  m_InBitStream.Init();
32
 
  CCoderReleaser coderReleaser(this);
33
 
 
34
 
  while(pos < *outSize)
35
 
  {
36
 
    const UInt32 kStartWidth = 0;
37
 
    const UInt32 kStopWidth = 7;
38
 
    UInt32 power = 1 << kStartWidth;
39
 
    UInt32 width;
40
 
    UInt32 len = 0;
41
 
    for (width = kStartWidth; width < kStopWidth; width++)
42
 
    {
43
 
      if (m_InBitStream.ReadBits(1) == 0)
44
 
        break;
45
 
      len += power;
46
 
      power <<= 1;
47
 
    }
48
 
    if (width != 0)
49
 
      len += m_InBitStream.ReadBits(width);
50
 
    if (len == 0)
51
 
    {
52
 
      m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
53
 
      pos++;
54
 
      continue;
55
 
    }
56
 
    else
57
 
    {
58
 
      len = len - 1 + kMatchMinLen;
59
 
      const UInt32 kStartWidth = 9;
60
 
      const UInt32 kStopWidth = 13;
61
 
      UInt32 power = 1 << kStartWidth;
62
 
      UInt32 width;
63
 
      UInt32 distance = 0;
64
 
      for (width = kStartWidth; width < kStopWidth; width++)
65
 
      {
66
 
        if (m_InBitStream.ReadBits(1) == 0)
67
 
          break;
68
 
        distance += power;
69
 
        power <<= 1;
70
 
      }
71
 
      if (width != 0)
72
 
        distance += m_InBitStream.ReadBits(width);
73
 
      if (distance >= pos)
74
 
        return S_FALSE;
75
 
      m_OutWindowStream.CopyBlock(distance, len);
76
 
        pos += len;
77
 
    }
78
 
  }
79
 
  coderReleaser.NeedFlush = false;
80
 
  return m_OutWindowStream.Flush();
81
 
}
82
 
 
83
 
STDMETHODIMP CCoder::Code(ISequentialInStream *inStream,
84
 
    ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
85
 
    ICompressProgressInfo *progress)
86
 
{
87
 
  try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
88
 
  catch(const CInBufferException &e) { return e.ErrorCode; }
89
 
  catch(const CLZOutWindowException &e) { return e.ErrorCode; }
90
 
  catch(...) { return S_FALSE; }
91
 
}
92
 
 
93
 
}}}