]>
git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c++-lib/src/sm_buffer.cpp
b0d87e9d26f4a7c17a0e8c89c125ae84ec8721e7
   2  * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. 
   4  * The contents of this file constitute Original Code as defined in and are 
   5  * subject to the Apple Public Source License Version 1.2 (the 'License'). 
   6  * You may not use this file except in compliance with the License. Please obtain 
   7  * a copy of the License at http://www.apple.com/publicsource and read it before 
  10  * This Original Code and all software distributed under the License are 
  11  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 
  12  * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 
  13  * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
  14  * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 
  15  * specific language governing rights and limitations under the License. 
  20 static char SccsId
[ ] = "@(#) sm_buffer.cpp 1.17 5/7/98 16:36:20";  
  24 ////////////////////////////////////////////////////////////////////////// 
  26 // This source file implements various members of the CSM_Buffer class. 
  27 // Be careful when you modify these 
  28 // members because code is being written based on the characteristics 
  29 // of these members... 
  30 ////////////////////////////////////////////////////////////////////////// 
  33 #if !defined(macintosh) && !defined(__APPLE__) 
  34 #include <sys/types.h> 
  40 #include <unistd.h>   // for SEEK_CUR and SEEK_END 
  43 #include "sm_vdasnacc.h" 
  48 #if     defined(macintosh) || defined(__APPLE__) 
  50 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h> 
  52 #define SME_SETUP(A)  try { 
  53 #define SME_THROW(A, B, C)  throw(static_cast<SM_RET_VAL>(A)) 
  55 #define SME_CATCH_SETUP catch(SM_RET_VAL) { 
  56 #define SME_CATCH_FINISH } 
  57 #define SM_RET_VAL  long 
  59 #define SME_FINISH_CATCH } catch(SM_RET_VAL) {} 
  62 #define SM_MEMORY_ERROR memFullErr 
  63 #define SM_MISSING_PARAM paramErr 
  64 #define SM_FILEIO_ERROR ioErr 
  68 #define SME_SETUP(A)  do {} while (0) 
  69 #define SME_THROW(A, B, C)  do {} while (0) 
  71 #define SME_CATCH_SETUP 
  72 #define SME_CATCH_FINISH 
  73 #define SM_RET_VAL  long 
  75 #define SME_FINISH_CATCH 
  80 ////////////////////////////////////////////////////////////////////////// 
  81 void CSM_Buffer::Clear() 
  85 #if     !defined(macintosh) && !defined(__APPLE__) 
  94 ////////////////////////////////////////////////////////////////////////// 
  95 CSM_Buffer::CSM_Buffer() 
  97    SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)"); 
 101    if ((m_pMemory 
= (char *)calloc(1, 1)) == NULL
) 
 102       SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 108 ////////////////////////////////////////////////////////////////////////// 
 109 CSM_Buffer::CSM_Buffer(size_t lSize
) 
 111    SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)"); 
 115    if ((m_pMemory 
= (char *)calloc(1, lSize 
+ 1)) == NULL
) 
 116       SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 117    SME(SetLength(lSize
)); 
 122 ////////////////////////////////////////////////////////////////////////// 
 123 #if !defined(macintosh) && !defined(__APPLE__) 
 124 CSM_Buffer::CSM_Buffer(char *pszFileName
) 
 126    SME_SETUP("CSM_Buffer::CSM_Buffer(char*)"); 
 130    if (pszFileName 
== NULL
) 
 131       SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
); 
 133    if ((m_pszFN 
= strdup(pszFileName
)) == NULL
) 
 134       SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 140 ////////////////////////////////////////////////////////////////////////// 
 141 CSM_Buffer::CSM_Buffer(const char *pBuf
, SM_SIZE_T lSize
)  
 143    SME_SETUP("CSM_Buffer::CSM_Buffer(char *, size_t)"); 
 148       SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
); 
 150    SME(Set(pBuf
, lSize
)); 
 155 ////////////////////////////////////////////////////////////////////////// 
 156 CSM_Buffer::CSM_Buffer(const CSM_Buffer 
&b
)  
 158    SME_SETUP("CSM_Buffer::CSM_Buffer(CSM_Buffer&)"); 
 167 ////////////////////////////////////////////////////////////////////////// 
 168 CSM_Buffer::~CSM_Buffer() 
 172 #if !defined(macintosh) && !defined(__APPLE__) 
 182 ////////////////////////////////////////////////////////////////////////// 
 183 SM_SIZE_T 
CSM_Buffer::Length() const 
 187    SME_SETUP("CSM_Buffer::Length"); 
 189 #if !defined(macintosh) && !defined(__APPLE__) 
 194       // how big is data in file 
 195       if (stat(m_pszFN
, &statBuf
) == -1) 
 198          sprintf(szMsg
, "Couldn't stat file %s", m_pszFN
); 
 199          SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
); 
 201       lRet 
= statBuf
.st_size
; 
 215 ////////////////////////////////////////////////////////////////////////// 
 216 void CSM_Buffer::Set(const char *psz
) 
 218    SME_SETUP("CSM_Buffer::Set(char *)"); 
 220       SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
); 
 223 #if !defined(macintosh) && !defined(__APPLE__) 
 224    int len 
= strlen(psz
); 
 225    m_pMemory 
= (char*)malloc(len 
+ 1); 
 226    if (m_pMemory 
== NULL
) 
 227       SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 228    strcpy(m_pMemory
, psz
); 
 231    if ((m_pMemory 
= strdup(psz
)) == NULL
) 
 232       SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 233    SME(SetLength(strlen(psz
))); 
 238 ////////////////////////////////////////////////////////////////////////// 
 239 void CSM_Buffer::Set(const char *p
, SM_SIZE_T lSize
) 
 241    SME_SETUP("CSM_Buffer::Set(char *, size_t)"); 
 252       m_pMemory 
= (char *)calloc(1, lSize 
+ 1); 
 253       if (m_pMemory 
== NULL
) 
 254          SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 255       memcpy(m_pMemory
, p
, lSize
); 
 256       SME(SetLength(lSize
)); 
 261 ////////////////////////////////////////////////////////////////////////// 
 262 // allocate memory in the cache 
 263 char* CSM_Buffer::Alloc(SM_SIZE_T lSize
) 
 265    SME_SETUP("CSM_Buffer::Alloc"); 
 269    if ((m_pCache 
= (char *)calloc(1, lSize
)) == NULL
) 
 270       SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 271    m_lCacheSize 
= lSize
; 
 278 ////////////////////////////////////////////////////////////////////////// 
 279 void CSM_Buffer::AllocMoreMem(SM_SIZE_T lSize
) 
 282    SM_SIZE_T lLength 
= Length(); 
 284    SME_SETUP("CSM_Buffer::AllocMoreMem"); 
 286    if ((pNew 
= (char *)calloc(1, lLength 
+ lSize
)) == NULL
) 
 287       SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 288    memcpy(pNew
, m_pMemory
, lLength
); 
 289    SetLength(lLength 
+ lSize
); 
 290    m_pMemFP 
= pNew 
+ (m_pMemFP 
- m_pMemory
); 
 297 ////////////////////////////////////////////////////////////////////////// 
 298 const char* CSM_Buffer::Access() const 
 300    SME_SETUP("CSM_Buffer::Access"); 
 301 #if !defined(macintosh) && !defined(__APPLE__) 
 304       // if the data is in a file AND 
 305       // if there's already memory in m_pMemory then free it 
 306       if (m_pMemory 
!= NULL
) 
 308       SME(m_pMemory 
= Get()); 
 315 ////////////////////////////////////////////////////////////////////////// 
 316 // return a copy of the actual data and return the size 
 317 char* CSM_Buffer::Get(SM_SIZE_T 
&l
) const 
 320    SME_SETUP("CSM_Buffer::Get"); 
 322    SM_SIZE_T lSize 
= Length(); 
 324 #if !defined(macintosh) && !defined(__APPLE__) 
 325    if (InFile()) // data in file 
 328       if ((pRet 
= (char *)calloc(1, lSize 
+ 1)) == NULL
) 
 329          SME_THROW(SM_MEMORY_ERROR
, "calloc failure", NULL
); 
 330       // close file if present 
 334       if ((m_pFP 
= fopen(m_pszFN
, SM_FOPEN_READ
)) == NULL
) 
 337          sprintf(szMsg
, "Couldn't open file %s", m_pszFN
); 
 338          SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
); 
 341       long lRead 
= fread(pRet
, 1, lSize
, m_pFP
); 
 342       if (ferror(m_pFP
) != 0) 
 345          sprintf(szMsg
, "Couldn't read file %s", m_pszFN
); 
 346          SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
); 
 348       // close and clear FP 
 351       l 
= lRead
; // store the size that will be returned 
 356       // if there is data, duplicate it 
 359          pRet 
= (char *)calloc(1, lSize
); 
 360          memcpy(pRet
, m_pMemory
, lSize
); 
 361          l 
= lSize
; // store the size that will be returned 
 372 #if !defined(macintosh) && !defined(__APPLE__) 
 383 ////////////////////////////////////////////////////////////////////////// 
 384 // compare buffers regardless of memory/file status 
 385 long CSM_Buffer::Compare(const CSM_Buffer 
&b
) 
 387    const char *p1 
= NULL
; 
 388    const char *p2 
= NULL
; 
 391    SME_SETUP("CSM_Buffer::Compare"); 
 392    // use AccessAll on both buffers for comparison.  If buffer is in 
 393    // file, then this results in a CopyAll which isn't as efficient, 
 394    // but this can be fixed later... 
 395    if ((p1 
= Access()) != NULL
) 
 397       if ((p2 
= b
.Access()) != NULL
) 
 399          if (Length() == b
.Length()) 
 400             lRet 
= (long)memcmp(p1
, p2
, Length()); 
 401          // p1 and p2 are the same as the memory pointers in 
 402          // the buffers so they do not need to be freed, they 
 403          // will be freed by the buffer's destructor 
 405 #if !defined(macintosh) && !defined(__APPLE__) 
 415 ////////////////////////////////////////////////////////////////////////// 
 417 SM_RET_VAL 
CSM_Buffer::ReSet(const CSM_Buffer 
&b
) 
 421    SME_SETUP("CSM_Buffer::ReSet"); 
 423 #if !defined(macintosh) && !defined(__APPLE__) 
 430    m_pMemory 
= m_pMemFP 
= NULL
; 
 446 #if !defined(macintosh) && !defined(__APPLE__) 
 447 ////////////////////////////////////////////////////////////////////////// 
 448 // ConvertFileToMemory makes a CSM_Buffer storing its contents in 
 449 // file into a CSM_Buffer storing its contents in memory 
 450 SM_RET_VAL 
CSM_Buffer::ConvertFileToMemory() 
 454    SME_SETUP("CSM_Buffer::ConvertFileToMemory"); 
 457       // we're already in memory 
 460    // read everything into memory 
 461    SME(m_pMemory 
= Get(l
)); 
 463    // free the file name 
 467    // store the new size 
 475 ////////////////////////////////////////////////////////////////////////// 
 476 // ConvertMemoryToFile makes a CSM_Buffer storing its contents in 
 477 // buffer into a CSM_Buffer storing its contents in file 
 478 SM_RET_VAL 
CSM_Buffer::ConvertMemoryToFile(char *pszFN
) 
 482    SME_SETUP("CSM_Buffer::ConvertMemoryToFile"); 
 485       SME_THROW(SM_NO_FILENAME
, NULL
, NULL
); 
 489      if (strcmp(m_pszFN
, pszFN
) == 0)   // we're already in file 
 493         SM_SIZE_T lBytesRead
; 
 494         SM_SIZE_T lSize
=4096; 
 496         FILE *fp
=fopen(pszFN
, "w"); 
 497         this->Open(SM_FOPEN_READ
); 
 498         while ((ptr
=this->nRead(lSize
, lBytesRead
)) != NULL 
&& lBytesRead 
> 0) 
 500             fwrite(ptr
, 1, lBytesRead
, fp
); 
 509    if ((m_pFP 
= fopen(pszFN
, SM_FOPEN_WRITE
)) == NULL
) 
 512       sprintf(szMsg
, "Couldn't stat file %s", pszFN
); 
 513       SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
); 
 517    SM_SIZE_T lLength 
= Length(); 
 518    // store the file name 
 519    if ((m_pszFN 
= strdup(pszFN
)) == NULL
) 
 520       SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 522    if ((lRet 
= fwrite(m_pMemory
, 1, lLength
, m_pFP
)) != lLength
) 
 525       sprintf(szMsg
, "Couldn't write file %s", m_pszFN
); 
 526       SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
); 
 534       // cleanup/catch code 
 535       if ((m_pszFN 
!= NULL
) && (pszFN 
!= NULL
)) 
 546 ////////////////////////////////////////////////////////////////////////// 
 547 SM_RET_VAL 
CSM_Buffer::Open(char *pszMode
) 
 549    SME_SETUP("CSM_Buffer::Open"); 
 552       SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
); 
 554 #if !defined(macintosh) && !defined(__APPLE__) 
 558       m_pMemFP 
= m_pMemory
; // set current pointer to start 
 559 #if !defined(macintosh) && !defined(__APPLE__) 
 562       if ((m_pFP 
= fopen(m_pszFN
, pszMode
)) == NULL
) 
 565          sprintf(szMsg
, "Couldn't open file %s", m_pszFN
); 
 566          SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
); 
 574 ////////////////////////////////////////////////////////////////////////// 
 575 SM_RET_VAL 
CSM_Buffer::Seek(SM_SIZE_T lOffset
, SM_SIZE_T lOrigin
) 
 577    SM_RET_VAL lRet 
= SM_NO_ERROR
; 
 579    SME_SETUP("CSM_Buffer::Seek"); 
 581 #if !defined(macintosh) && !defined(__APPLE__) 
 586       char *pSave 
= m_pMemFP
; 
 588       if (m_pMemFP 
== NULL
) 
 589          SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 591       SM_SIZE_T lLength 
= Length(); 
 599          m_pMemFP 
= (m_pMemory 
+ lLength 
- 1) + lOffset
; 
 602          m_pMemFP 
= m_pMemory 
+ lOffset
; 
 605       if ((m_pMemFP 
> (m_pMemory 
+ lLength 
- 1)) || 
 606           (m_pMemFP 
< m_pMemory
)) 
 612 #if !defined(macintosh) && !defined(__APPLE__) 
 617          SME_THROW(SM_FILEIO_ERROR
, "FP is NULL", NULL
); 
 619       lRet 
= fseek(m_pFP
, lOffset
, lOrigin
); 
 628 ////////////////////////////////////////////////////////////////////////// 
 629 void CSM_Buffer::Close() 
 631 #if !defined(macintosh) && !defined(__APPLE__) 
 647 ////////////////////////////////////////////////////////////////////////// 
 648 AsnType 
*CSM_Buffer::Clone() const 
 650   return new CSM_Buffer
; 
 653 ////////////////////////////////////////////////////////////////////////// 
 654 AsnType 
*CSM_Buffer::Copy() const 
 656   return new CSM_Buffer (*this); 
 659 ////////////////////////////////////////////////////////////////////////// 
 660 AsnLen 
CSM_Buffer::BEnc(BUF_TYPE BBuf
) 
 667     this->Open(SM_FOPEN_READ
); 
 668     for (jj 
= 0; jj 
< this->Length() && lRead 
> 0; jj 
+= lRead
) 
 670         if (jj 
== 0)    // first time, only get last X bytes within 4096 block. 
 672             lOffset 
= this->Length() - (this->Length() % 4096); 
 676          this->Seek(lOffset
, 0); 
 677          ptr 
= this->nRead(4096, lRead
); 
 678          BBuf
.PutSegRvs(ptr
, lRead
); 
 682         return this->Length(); 
 685 ////////////////////////////////////////////////////////////////////////// 
 686 void CSM_Buffer::Print (ostream 
&os
) const 
 692         os 
<< "{ -- ANY --" << endl
; 
 693         indentG 
+= stdIndentG
; 
 694     Indent (os
, indentG
); 
 696         long oFlags 
= os
.flags(); 
 698         for (i 
= 0; i 
< len
; i
++) 
 700                 os 
<< setw(2) << setfill('0')  
 701                         << static_cast<unsigned int>(static_cast<unsigned char>(m_pMemory
[i
])) << " "; 
 703                 if (i 
== len 
- 1 || i 
% 16 == 15) 
 707                         for (j 
= i 
> 15 ? i 
- 15 : 0; j 
<= i
; j
++) 
 709                                 if (m_pMemory
[j
] >= 0x20 && m_pMemory
[j
] < 0x80) 
 720         indentG 
-= stdIndentG
; 
 721         Indent (os
, indentG
); 
 726 ////////////////////////////////////////////////////////////////////////// 
 727 SM_RET_VAL 
CSM_Buffer::cRead(char *pBuffer
, SM_SIZE_T lSize
) 
 731    SME_SETUP("CSM_Buffer::cRead"); 
 733    if ((pBuffer 
== NULL
) || (lSize 
<= 0)) 
 734       SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
); 
 736 #if !defined(macintosh) && !defined(__APPLE__) 
 741       if (m_pMemFP 
== NULL
) 
 742          SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 744       SM_SIZE_T lReadSize 
= lSize
; 
 745       SM_SIZE_T lLength 
= Length(); 
 746       // adjust the read size to what's possible 
 747       if ((m_pMemFP 
+ lReadSize
) > (m_pMemory 
+ lLength
)) 
 748          lReadSize 
= (m_pMemory 
+ lLength
) - m_pMemFP
; 
 749       memcpy(pBuffer
, m_pMemFP
, lReadSize
); 
 750       // adjust the current pointer 
 753          m_pMemFP 
+= lReadSize
; 
 759 #if !defined(macintosh) && !defined(__APPLE__) 
 764          SME_THROW(SM_FILEIO_ERROR
, "FP is NULL", NULL
); 
 766       lRet 
= fread(pBuffer
, 1, lSize
, m_pFP
); 
 775 ////////////////////////////////////////////////////////////////////////// 
 776 SM_RET_VAL 
CSM_Buffer::Write(const char *pBuffer
, SM_SIZE_T lSize
) 
 780    SME_SETUP("CSM_Buffer::Write"); 
 782    if ((pBuffer 
== NULL
) || (lSize 
<= 0)) 
 783       SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
); 
 785 #if !defined(macintosh) && !defined(__APPLE__) 
 790       if (m_pMemFP 
== NULL
) 
 792          if (m_pMemory 
== NULL
) 
 794             // if we get here, we assume that the memory 
 795             // hasn't been allocated yet, allocate it... 
 796             if ((m_pMemFP 
= m_pMemory 
= (char *)calloc(1, lSize
)) == NULL
) 
 797                SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 801             m_pMemFP 
= m_pMemory
; 
 804       // do we have enough space to write to this buffer? 
 805       if ((SM_SIZE_T
)(((m_pMemory 
+ Length()) - m_pMemFP
)) < lSize
) 
 806          // nope, get lSize more bytes 
 808       memcpy(m_pMemFP
, pBuffer
, lSize
); 
 812 #if !defined(macintosh) && !defined(__APPLE__) 
 817          SME_THROW(SM_FILEIO_ERROR
, "FP is NULL", NULL
); 
 819       if ((lRet 
= fwrite(pBuffer
, 1, lSize
, m_pFP
)) > 0) 
 820          SetLength(m_lSize 
+ lRet
); 
 829 ////////////////////////////////////////////////////////////////////////// 
 830 char* CSM_Buffer::nRead(SM_SIZE_T lSize
, SM_SIZE_T 
&lBytesRead
) 
 834    SME_SETUP("CSM_Buffer::nRead"); 
 837       SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
); 
 839 #if !defined(macintosh) && !defined(__APPLE__) 
 844       if (m_pMemFP 
== NULL
) 
 845          SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 847       SM_SIZE_T lReadSize 
= lSize
; 
 848       SM_SIZE_T lLength 
= Length(); 
 849       // adjust the read size to what's possible 
 850       if ((m_pMemFP 
+ lReadSize
) > (m_pMemory 
+ lLength
)) 
 851          lReadSize 
= (m_pMemory 
+ lLength
) - m_pMemFP
; 
 853       // adjust the current pointer 
 856          m_pMemFP 
+= lReadSize
; 
 857          lBytesRead 
= lReadSize
; 
 862 #if !defined(macintosh) && !defined(__APPLE__) 
 867          SME_THROW(SM_FILEIO_ERROR
, "FP is NULL", NULL
); 
 868       // if there's something already in the memory, free it 
 869       if (m_pMemory 
!= NULL
) 
 871       // allocate memory to receive the read data 
 872       if ((m_pMemory 
= (char *)calloc(1, lSize 
+ 1)) == NULL
) 
 873          SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
); 
 874       // now, read into the memory cache 
 875       lBytesRead 
= fread(m_pMemory
, 1, lSize
, m_pFP
); 
 876       // now set what we'll return 
 886 ////////////////////////////////////////////////////////////////////////// 
 887 void CSM_Buffer::Flush() 
 889    if (m_pCache 
!= NULL
) 
 891       Write(m_pCache
, m_lCacheSize
);