Subversion Repositories autosfx

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3.  
  4. #include "DZRaw.h"
  5.  
  6. #include <assert.h>
  7. #include "dz_errs.h"
  8.  
  9. #undef _DZ_FILE_
  10. #define _DZ_FILE_ DZ_DZRAW_CPP
  11.  
  12. /* DZRaw.cpp * Copyright (C)  2009 Russell Peters
  13. * Permission is granted to any individual or institution to use, copy, or
  14. * redistribute this software so long as all of the original files are included,
  15. * that it is not sold for profit, and that this copyright notice is retained.
  16. ** distributed under LGPL license
  17. ** see license.txt for details
  18.  
  19. ************************************************************************
  20.  Copyright (C) 2009, 2010  by Russell J. Peters, Roger Aelbrecht
  21.  
  22.    This file is part of TZipMaster Version 1.9.
  23.  
  24.     TZipMaster is free software: you can redistribute it and/or modify
  25.     it under the terms of the GNU Lesser General Public License as published by
  26.     the Free Software Foundation, either version 3 of the License, or
  27.     (at your option) any later version.
  28.  
  29.     TZipMaster is distributed in the hope that it will be useful,
  30.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  31.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  32.     GNU Lesser General Public License for more details.
  33.  
  34.     You should have received a copy of the GNU Lesser General Public License
  35.     along with TZipMaster.  If not, see <http://www.gnu.org/licenses/>.
  36.  
  37.     contact: problems@delphizip.org (include ZipMaster in the subject).
  38.     updates: http://www.delphizip.org
  39.     DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
  40. ************************************************************************/
  41.  
  42. dzraw_imp* __fastcall DZRawData::NewImp(unsigned siz)
  43. {
  44.     unsigned rawsize = sizeof(dzraw_imp) + siz - (8 * sizeof(char));
  45.     if (rawsize & 63)
  46.         rawsize = (rawsize | 63) + 1;
  47.     if (rawsize > 0xFFF0)
  48.         rawsize = 0xFFF0;
  49.  
  50.     dzraw_imp* _imp = (dzraw_imp*) (new char[rawsize]);
  51.     if (! _imp)
  52.         throw DZException(DZ_ERM_MEMORY);
  53.  
  54.     _imp->refs      = 1;
  55.         _imp->capacity  = (WORD)((rawsize - sizeof(dzraw_imp)) + (8 * sizeof(char)));
  56.         _imp->len       = 0;
  57.     return _imp;
  58. }
  59.  
  60. dzraw_imp* DZRawData::NewImp(const unsigned char* src, int Len, int Space)
  61. {
  62.     if (!src)
  63.         Len = 0;
  64.     if (Space >= 0 && Len > Space)
  65.         Len = Space;
  66.  
  67.     int siz = (Space >= 0) ? Space : Len;
  68.  
  69.     if (!siz)
  70.         return NULL;    // empty
  71.  
  72.     dzraw_imp* nimp = NewImp(siz); // make new
  73.     if (src && Len)
  74.     {
  75.         memcpy(nimp->data, src, Len);
  76.         nimp->len = (WORD)Len;
  77.     }
  78.     return nimp;
  79. }
  80.  
  81. void __fastcall DZRawData::Release(void)
  82. {
  83.     if (imp)
  84.     {
  85.         if (!DecRefs())
  86.         {
  87.             void *_imp = imp;
  88.             imp = NULL;
  89. //            free(_imp);
  90.             delete[] _imp;
  91.         }
  92.         imp = NULL;
  93.     }
  94. }
  95.  
  96. int __fastcall DZRawData::IncRefs(void)
  97. {
  98.     if (imp)
  99.         return InterlockedIncrement(&(imp->refs));
  100.     return 0;
  101. }
  102.  
  103. int __fastcall DZRawData::DecRefs(void)
  104. {
  105.     if (imp && imp->refs)
  106.         return InterlockedDecrement(&(imp->refs));
  107.     return -1;
  108. }
  109.  
  110. void __fastcall DZRawData::Append(const unsigned char* src, int Len)
  111. {
  112.     if (!src)
  113.         Len = 0;
  114.  
  115.     // check something to append
  116.     if (Len)
  117.     {
  118.         if (!imp)
  119.             imp = NewImp(src, Len);
  120.         else
  121.         {
  122.             unsigned nlen = imp->len + Len;
  123.             if (nlen > 0xFFF0)
  124.                 return;
  125.  
  126.             // do we need a new one
  127.             if (imp->refs > 1 || (WORD)nlen > imp->capacity)
  128.             {
  129.                 // need new imp - make copy with enough space
  130.                 dzraw_imp* nimp = NewImp(imp->data, imp->len, nlen);
  131.                 Release();      // out with the old
  132.                 imp = nimp;     // in with the new
  133.             }
  134.             // append data
  135.             unsigned char *bf = &imp->data[imp->len];
  136.             memcpy(bf, src, Len);
  137.             imp->len = (WORD)nlen;
  138.         }
  139.     }
  140. }
  141.  
  142. void __fastcall DZRawData::Assign(const unsigned char* src, int Len)
  143. {
  144.     Release();
  145.     imp = NewImp(src, Len);
  146. }
  147.  
  148. unsigned char * __fastcall DZRawData::GetBuffer(unsigned size)
  149. {
  150.     Release();
  151.     imp = NewImp(size);
  152.         imp->len = (WORD)size;
  153.     return imp->data;
  154. }
  155.  
  156. void __fastcall DZRawData::SetLength(unsigned Len)
  157. {
  158.     if (!Len)
  159.         Release();
  160.         else
  161.     {
  162.         dzraw_imp* nimp;
  163.         // do we need a new one
  164.         if (!imp || imp->refs > 1 || (WORD)Len > imp->capacity)
  165.         {
  166.             // need new imp - make copy with enough space
  167.             if (!imp)
  168.                 nimp = NewImp(Len);
  169.             else
  170.                 nimp = NewImp(imp->data, imp->len, Len);
  171.             Release();      // out with the old
  172.             imp = nimp;     // in with the new
  173.         }
  174.         imp->len = (WORD)Len;
  175.     }
  176. }
  177.  
  178. __fastcall DZRawData::DZRawData(const DZRawData& other)
  179. {
  180.     imp = NULL;
  181.     if (!other.IsEmpty())
  182.     {
  183.         imp = other.imp;
  184.         IncRefs();
  185.     }
  186. }
  187.  
  188. __fastcall DZRawData::DZRawData(unsigned size)
  189. {
  190.     imp = NULL;
  191.     if (size)
  192.         imp = NewImp(size);
  193. }
  194.  
  195. __fastcall DZRawData::DZRawData(const unsigned char* str, unsigned len)
  196. {
  197.     imp = NULL;
  198.     if (str && len)
  199.     {
  200.         imp = NewImp(str, len);
  201.     }
  202. }
  203.  
  204. unsigned __fastcall DZRawData::Capacity(void) const
  205. {
  206.     if (imp)
  207.         return imp->capacity;
  208.     return NULL;
  209. }
  210.  
  211. unsigned __fastcall DZRawData::Length(void) const
  212. {
  213.     if (imp)
  214.         return imp->len;
  215.     return 0;
  216. }
  217.  
  218. const unsigned char* DZRawData::begin(void) const
  219. {
  220.     if (imp)
  221.         return imp->data;
  222.     return NULL;
  223. }
  224.  
  225. const unsigned char* DZRawData::end(void) const
  226. {
  227.     if (imp)
  228.         return imp->data + imp->len;
  229.     return NULL;
  230. }
  231.  
  232. const unsigned char* DZRawData::Find(WORD tag) const
  233. {
  234.     if (Length() < sizeof(XWord))
  235.         return NULL;
  236.     const unsigned char *p = begin();
  237.     const unsigned char *q;
  238.     const unsigned char *e = end();
  239.     XWord tg, sz;
  240.     while (p + 3 < e)
  241.     {
  242.         q = p;
  243.         tg.b[0] = *p++;
  244.         tg.b[1] = *p++;
  245.         if (tg.w == tag)
  246.             return q;   // found
  247.         sz.b[0] = *p++;
  248.         sz.b[1] = *p++;
  249.         p += sz.w;
  250.     }
  251.     return NULL;
  252. }
  253.  
  254. DZRawData& __fastcall DZRawData::operator =(const DZRawData& other)
  255. {
  256.     if (this != &other)
  257.     {
  258.         Release();
  259.         if (!other.IsEmpty())
  260.         {
  261.             imp = other.imp;
  262.             IncRefs();
  263.         }
  264.     }
  265.     return *this;
  266. }
  267.  
  268. DZRawData __fastcall DZRawData::operator +(const DZRawData& other)
  269. {
  270.     DZRawData res(*this);
  271.     res.Append(other.begin(), other.Length());
  272.     return res;
  273. }
  274.  
  275. DZRawData& __fastcall DZRawData::operator +=(const DZRawData& other)
  276. {
  277.     Append(other.begin(), other.Length());
  278.     return *this;
  279. }
  280.  
  281. DZRawData& __fastcall DZRawData::operator +=(unsigned char ch)
  282. {
  283.     Append(&ch, 1);
  284.     return *this;
  285. }
  286.  
  287. DZRawData& __fastcall DZRawData::operator +=(WORD w)
  288. {
  289.     Append((const unsigned char*)&w, sizeof(WORD));
  290.     return *this;
  291. }
  292.  
  293. //unsigned char __fastcall DZRawData::operator [](unsigned idx) const
  294. //{
  295. //    if (!imp || idx >= Length())
  296. //        return 0;
  297. //    return *(imp + idx);
  298. //}
  299.  
  300.  
  301. WORD  __fastcall DZRawData::operator [](unsigned idx) const
  302. {
  303.     unsigned widx = idx * sizeof(WORD);
  304.     if (!imp || widx >= Length() - (sizeof(WORD)-1))
  305.         return 0;
  306.     return ((WORD*)idx)[idx];
  307. }
  308.  
  309. DZRawData __fastcall DZRawData::operator -(WORD tag)
  310. {
  311.     DZRawData res(Capacity());
  312.     if (imp)
  313.     {
  314.         const unsigned char *p = begin();
  315.         const unsigned char *e = end();
  316.         XWord tg, sz;
  317.         while (p + 3 < e)
  318.         {
  319.             tg.b[0] = *p++;
  320.             tg.b[1] = *p++;
  321.             sz.b[0] = *p++;
  322.             sz.b[1] = *p++;
  323.  
  324.             if (tg.w != tag)
  325.             {
  326.                 res += tg.w;
  327.                 res += sz.w;
  328.  
  329.                 while (p < e && sz.w-- > 0)
  330.                     res += *p++;
  331.             }
  332.             else
  333.                 p += sz.w;
  334.         }
  335.  
  336.         while (p < e)
  337.             res += *p++;
  338.     }
  339.     return res;
  340. }
  341.  
  342.  
  343. DZRawData& __fastcall DZRawData::operator -=(WORD tag)
  344. {
  345.     if (Find(tag))
  346.     {
  347.         DZRawData tmp = (*this) - tag;
  348.         (*this) = tmp;
  349.     }
  350.     return *this;
  351. }
  352.  
  353.