]>
git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c++-lib/src/sm_buffer.cpp
68f9ae961d83fbfaea223ba440ef4b05490a9bdd
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"
46 #if defined(macintosh) || defined(__APPLE__)
48 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
50 #define SME_SETUP(A) try {
51 #define SME_THROW(A, B, C) throw(static_cast<SM_RET_VAL>(A))
53 #define SME_CATCH_SETUP catch(SM_RET_VAL) {
54 #define SME_CATCH_FINISH }
55 #define SM_RET_VAL long
57 #define SME_FINISH_CATCH } catch(SM_RET_VAL) {}
60 #define SM_MEMORY_ERROR memFullErr
61 #define SM_MISSING_PARAM paramErr
62 #define SM_FILEIO_ERROR ioErr
66 #define SME_SETUP(A) do {} while (0)
67 #define SME_THROW(A, B, C) do {} while (0)
69 #define SME_CATCH_SETUP
70 #define SME_CATCH_FINISH
71 #define SM_RET_VAL long
73 #define SME_FINISH_CATCH
78 //////////////////////////////////////////////////////////////////////////
79 void CSM_Buffer::Clear()
83 #if !defined(macintosh) && !defined(__APPLE__)
92 //////////////////////////////////////////////////////////////////////////
93 CSM_Buffer::CSM_Buffer()
95 SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)");
99 if ((m_pMemory
= (char *)calloc(1, 1)) == NULL
)
100 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
106 //////////////////////////////////////////////////////////////////////////
107 CSM_Buffer::CSM_Buffer(size_t lSize
)
109 SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)");
113 if ((m_pMemory
= (char *)calloc(1, lSize
+ 1)) == NULL
)
114 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
115 SME(SetLength(lSize
));
120 //////////////////////////////////////////////////////////////////////////
121 #if !defined(macintosh) && !defined(__APPLE__)
122 CSM_Buffer::CSM_Buffer(char *pszFileName
)
124 SME_SETUP("CSM_Buffer::CSM_Buffer(char*)");
128 if (pszFileName
== NULL
)
129 SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
);
131 if ((m_pszFN
= strdup(pszFileName
)) == NULL
)
132 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
138 //////////////////////////////////////////////////////////////////////////
139 CSM_Buffer::CSM_Buffer(const char *pBuf
, SM_SIZE_T lSize
)
141 SME_SETUP("CSM_Buffer::CSM_Buffer(char *, size_t)");
146 SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
);
148 SME(Set(pBuf
, lSize
));
153 //////////////////////////////////////////////////////////////////////////
154 CSM_Buffer::CSM_Buffer(const CSM_Buffer
&b
)
156 SME_SETUP("CSM_Buffer::CSM_Buffer(CSM_Buffer&)");
165 //////////////////////////////////////////////////////////////////////////
166 CSM_Buffer::~CSM_Buffer()
170 #if !defined(macintosh) && !defined(__APPLE__)
180 //////////////////////////////////////////////////////////////////////////
181 SM_SIZE_T
CSM_Buffer::Length() const
185 SME_SETUP("CSM_Buffer::Length");
187 #if !defined(macintosh) && !defined(__APPLE__)
192 // how big is data in file
193 if (stat(m_pszFN
, &statBuf
) == -1)
196 sprintf(szMsg
, "Couldn't stat file %s", m_pszFN
);
197 SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
);
199 lRet
= statBuf
.st_size
;
213 //////////////////////////////////////////////////////////////////////////
214 void CSM_Buffer::Set(const char *psz
)
216 SME_SETUP("CSM_Buffer::Set(char *)");
218 SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
);
221 #if !defined(macintosh) && !defined(__APPLE__)
222 int len
= strlen(psz
);
223 m_pMemory
= (char*)malloc(len
+ 1);
224 if (m_pMemory
== NULL
)
225 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
226 strcpy(m_pMemory
, psz
);
229 if ((m_pMemory
= strdup(psz
)) == NULL
)
230 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
231 SME(SetLength(strlen(psz
)));
236 //////////////////////////////////////////////////////////////////////////
237 void CSM_Buffer::Set(const char *p
, SM_SIZE_T lSize
)
239 SME_SETUP("CSM_Buffer::Set(char *, size_t)");
250 m_pMemory
= (char *)calloc(1, lSize
+ 1);
251 if (m_pMemory
== NULL
)
252 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
253 memcpy(m_pMemory
, p
, lSize
);
254 SME(SetLength(lSize
));
259 //////////////////////////////////////////////////////////////////////////
260 // allocate memory in the cache
261 char* CSM_Buffer::Alloc(SM_SIZE_T lSize
)
263 SME_SETUP("CSM_Buffer::Alloc");
267 if ((m_pCache
= (char *)calloc(1, lSize
)) == NULL
)
268 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
269 m_lCacheSize
= lSize
;
276 //////////////////////////////////////////////////////////////////////////
277 void CSM_Buffer::AllocMoreMem(SM_SIZE_T lSize
)
280 SM_SIZE_T lLength
= Length();
282 SME_SETUP("CSM_Buffer::AllocMoreMem");
284 if ((pNew
= (char *)calloc(1, lLength
+ lSize
)) == NULL
)
285 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
286 memcpy(pNew
, m_pMemory
, lLength
);
287 SetLength(lLength
+ lSize
);
288 m_pMemFP
= pNew
+ (m_pMemFP
- m_pMemory
);
295 //////////////////////////////////////////////////////////////////////////
296 const char* CSM_Buffer::Access() const
298 SME_SETUP("CSM_Buffer::Access");
299 #if !defined(macintosh) && !defined(__APPLE__)
302 // if the data is in a file AND
303 // if there's already memory in m_pMemory then free it
304 if (m_pMemory
!= NULL
)
306 SME(m_pMemory
= Get());
313 //////////////////////////////////////////////////////////////////////////
314 // return a copy of the actual data and return the size
315 char* CSM_Buffer::Get(SM_SIZE_T
&l
) const
318 SME_SETUP("CSM_Buffer::Get");
320 SM_SIZE_T lSize
= Length();
322 #if !defined(macintosh) && !defined(__APPLE__)
323 if (InFile()) // data in file
326 if ((pRet
= (char *)calloc(1, lSize
+ 1)) == NULL
)
327 SME_THROW(SM_MEMORY_ERROR
, "calloc failure", NULL
);
328 // close file if present
332 if ((m_pFP
= fopen(m_pszFN
, SM_FOPEN_READ
)) == NULL
)
335 sprintf(szMsg
, "Couldn't open file %s", m_pszFN
);
336 SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
);
339 long lRead
= fread(pRet
, 1, lSize
, m_pFP
);
340 if (ferror(m_pFP
) != 0)
343 sprintf(szMsg
, "Couldn't read file %s", m_pszFN
);
344 SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
);
346 // close and clear FP
349 l
= lRead
; // store the size that will be returned
354 // if there is data, duplicate it
357 pRet
= (char *)calloc(1, lSize
);
358 memcpy(pRet
, m_pMemory
, lSize
);
359 l
= lSize
; // store the size that will be returned
370 #if !defined(macintosh) && !defined(__APPLE__)
381 //////////////////////////////////////////////////////////////////////////
382 // compare buffers regardless of memory/file status
383 long CSM_Buffer::Compare(const CSM_Buffer
&b
)
385 const char *p1
= NULL
;
386 const char *p2
= NULL
;
389 SME_SETUP("CSM_Buffer::Compare");
390 // use AccessAll on both buffers for comparison. If buffer is in
391 // file, then this results in a CopyAll which isn't as efficient,
392 // but this can be fixed later...
393 if ((p1
= Access()) != NULL
)
395 if ((p2
= b
.Access()) != NULL
)
397 if (Length() == b
.Length())
398 lRet
= (long)memcmp(p1
, p2
, Length());
399 // p1 and p2 are the same as the memory pointers in
400 // the buffers so they do not need to be freed, they
401 // will be freed by the buffer's destructor
403 #if !defined(macintosh) && !defined(__APPLE__)
413 //////////////////////////////////////////////////////////////////////////
415 SM_RET_VAL
CSM_Buffer::ReSet(const CSM_Buffer
&b
)
419 SME_SETUP("CSM_Buffer::ReSet");
421 #if !defined(macintosh) && !defined(__APPLE__)
428 m_pMemory
= m_pMemFP
= NULL
;
444 #if !defined(macintosh) && !defined(__APPLE__)
445 //////////////////////////////////////////////////////////////////////////
446 // ConvertFileToMemory makes a CSM_Buffer storing its contents in
447 // file into a CSM_Buffer storing its contents in memory
448 SM_RET_VAL
CSM_Buffer::ConvertFileToMemory()
452 SME_SETUP("CSM_Buffer::ConvertFileToMemory");
455 // we're already in memory
458 // read everything into memory
459 SME(m_pMemory
= Get(l
));
461 // free the file name
465 // store the new size
473 //////////////////////////////////////////////////////////////////////////
474 // ConvertMemoryToFile makes a CSM_Buffer storing its contents in
475 // buffer into a CSM_Buffer storing its contents in file
476 SM_RET_VAL
CSM_Buffer::ConvertMemoryToFile(char *pszFN
)
480 SME_SETUP("CSM_Buffer::ConvertMemoryToFile");
483 SME_THROW(SM_NO_FILENAME
, NULL
, NULL
);
487 if (strcmp(m_pszFN
, pszFN
) == 0) // we're already in file
491 SM_SIZE_T lBytesRead
;
492 SM_SIZE_T lSize
=4096;
494 FILE *fp
=fopen(pszFN
, "w");
495 this->Open(SM_FOPEN_READ
);
496 while ((ptr
=this->nRead(lSize
, lBytesRead
)) != NULL
&& lBytesRead
> 0)
498 fwrite(ptr
, 1, lBytesRead
, fp
);
507 if ((m_pFP
= fopen(pszFN
, SM_FOPEN_WRITE
)) == NULL
)
510 sprintf(szMsg
, "Couldn't stat file %s", pszFN
);
511 SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
);
515 SM_SIZE_T lLength
= Length();
516 // store the file name
517 if ((m_pszFN
= strdup(pszFN
)) == NULL
)
518 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
520 if ((lRet
= fwrite(m_pMemory
, 1, lLength
, m_pFP
)) != lLength
)
523 sprintf(szMsg
, "Couldn't write file %s", m_pszFN
);
524 SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
);
532 // cleanup/catch code
533 if ((m_pszFN
!= NULL
) && (pszFN
!= NULL
))
544 //////////////////////////////////////////////////////////////////////////
545 SM_RET_VAL
CSM_Buffer::Open(char *pszMode
)
547 SME_SETUP("CSM_Buffer::Open");
550 SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
);
552 #if !defined(macintosh) && !defined(__APPLE__)
556 m_pMemFP
= m_pMemory
; // set current pointer to start
557 #if !defined(macintosh) && !defined(__APPLE__)
560 if ((m_pFP
= fopen(m_pszFN
, pszMode
)) == NULL
)
563 sprintf(szMsg
, "Couldn't open file %s", m_pszFN
);
564 SME_THROW(SM_FILEIO_ERROR
, szMsg
, NULL
);
572 //////////////////////////////////////////////////////////////////////////
573 SM_RET_VAL
CSM_Buffer::Seek(SM_SIZE_T lOffset
, SM_SIZE_T lOrigin
)
575 SM_RET_VAL lRet
= SM_NO_ERROR
;
577 SME_SETUP("CSM_Buffer::Seek");
579 #if !defined(macintosh) && !defined(__APPLE__)
584 char *pSave
= m_pMemFP
;
586 if (m_pMemFP
== NULL
)
587 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
589 SM_SIZE_T lLength
= Length();
597 m_pMemFP
= (m_pMemory
+ lLength
- 1) + lOffset
;
600 m_pMemFP
= m_pMemory
+ lOffset
;
603 if ((m_pMemFP
> (m_pMemory
+ lLength
- 1)) ||
604 (m_pMemFP
< m_pMemory
))
610 #if !defined(macintosh) && !defined(__APPLE__)
615 SME_THROW(SM_FILEIO_ERROR
, "FP is NULL", NULL
);
617 lRet
= fseek(m_pFP
, lOffset
, lOrigin
);
626 //////////////////////////////////////////////////////////////////////////
627 void CSM_Buffer::Close()
629 #if !defined(macintosh) && !defined(__APPLE__)
645 //////////////////////////////////////////////////////////////////////////
646 AsnType
*CSM_Buffer::Clone() const
648 return new CSM_Buffer
;
651 //////////////////////////////////////////////////////////////////////////
652 AsnType
*CSM_Buffer::Copy() const
654 return new CSM_Buffer (*this);
657 //////////////////////////////////////////////////////////////////////////
658 AsnLen
CSM_Buffer::BEnc(BUF_TYPE BBuf
)
665 this->Open(SM_FOPEN_READ
);
666 for (jj
= 0; jj
< this->Length() && lRead
> 0; jj
+= lRead
)
668 if (jj
== 0) // first time, only get last X bytes within 4096 block.
670 lOffset
= this->Length() - (this->Length() % 4096);
674 this->Seek(lOffset
, 0);
675 ptr
= this->nRead(4096, lRead
);
676 BBuf
.PutSegRvs(ptr
, lRead
);
680 return this->Length();
683 //////////////////////////////////////////////////////////////////////////
684 void CSM_Buffer::Print (ostream
&os
) const
690 os
<< "{ -- ANY --" << endl
;
691 indentG
+= stdIndentG
;
692 Indent (os
, indentG
);
694 long oFlags
= os
.flags();
696 for (i
= 0; i
< len
; i
++)
698 os
<< setw(2) << setfill('0')
699 << static_cast<unsigned int>(static_cast<unsigned char>(m_pMemory
[i
])) << " ";
701 if (i
== len
- 1 || i
% 16 == 15)
705 for (j
= i
> 15 ? i
- 15 : 0; j
<= i
; j
++)
707 if (m_pMemory
[j
] >= 0x20 && m_pMemory
[j
] < 0x80)
718 indentG
-= stdIndentG
;
719 Indent (os
, indentG
);
724 //////////////////////////////////////////////////////////////////////////
725 SM_RET_VAL
CSM_Buffer::cRead(char *pBuffer
, SM_SIZE_T lSize
)
729 SME_SETUP("CSM_Buffer::cRead");
731 if ((pBuffer
== NULL
) || (lSize
<= 0))
732 SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
);
734 #if !defined(macintosh) && !defined(__APPLE__)
739 if (m_pMemFP
== NULL
)
740 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
742 SM_SIZE_T lReadSize
= lSize
;
743 SM_SIZE_T lLength
= Length();
744 // adjust the read size to what's possible
745 if ((m_pMemFP
+ lReadSize
) > (m_pMemory
+ lLength
))
746 lReadSize
= (m_pMemory
+ lLength
) - m_pMemFP
;
747 memcpy(pBuffer
, m_pMemFP
, lReadSize
);
748 // adjust the current pointer
751 m_pMemFP
+= lReadSize
;
757 #if !defined(macintosh) && !defined(__APPLE__)
762 SME_THROW(SM_FILEIO_ERROR
, "FP is NULL", NULL
);
764 lRet
= fread(pBuffer
, 1, lSize
, m_pFP
);
773 //////////////////////////////////////////////////////////////////////////
774 SM_RET_VAL
CSM_Buffer::Write(const char *pBuffer
, SM_SIZE_T lSize
)
778 SME_SETUP("CSM_Buffer::Write");
780 if ((pBuffer
== NULL
) || (lSize
<= 0))
781 SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
);
783 #if !defined(macintosh) && !defined(__APPLE__)
788 if (m_pMemFP
== NULL
)
790 if (m_pMemory
== NULL
)
792 // if we get here, we assume that the memory
793 // hasn't been allocated yet, allocate it...
794 if ((m_pMemFP
= m_pMemory
= (char *)calloc(1, lSize
)) == NULL
)
795 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
799 m_pMemFP
= m_pMemory
;
802 // do we have enough space to write to this buffer?
803 if ((SM_SIZE_T
)(((m_pMemory
+ Length()) - m_pMemFP
)) < lSize
)
804 // nope, get lSize more bytes
806 memcpy(m_pMemFP
, pBuffer
, lSize
);
810 #if !defined(macintosh) && !defined(__APPLE__)
815 SME_THROW(SM_FILEIO_ERROR
, "FP is NULL", NULL
);
817 if ((lRet
= fwrite(pBuffer
, 1, lSize
, m_pFP
)) > 0)
818 SetLength(m_lSize
+ lRet
);
827 //////////////////////////////////////////////////////////////////////////
828 char* CSM_Buffer::nRead(SM_SIZE_T lSize
, SM_SIZE_T
&lBytesRead
)
832 SME_SETUP("CSM_Buffer::nRead");
835 SME_THROW(SM_MISSING_PARAM
, NULL
, NULL
);
837 #if !defined(macintosh) && !defined(__APPLE__)
842 if (m_pMemFP
== NULL
)
843 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
845 SM_SIZE_T lReadSize
= lSize
;
846 SM_SIZE_T lLength
= Length();
847 // adjust the read size to what's possible
848 if ((m_pMemFP
+ lReadSize
) > (m_pMemory
+ lLength
))
849 lReadSize
= (m_pMemory
+ lLength
) - m_pMemFP
;
851 // adjust the current pointer
854 m_pMemFP
+= lReadSize
;
855 lBytesRead
= lReadSize
;
860 #if !defined(macintosh) && !defined(__APPLE__)
865 SME_THROW(SM_FILEIO_ERROR
, "FP is NULL", NULL
);
866 // if there's something already in the memory, free it
867 if (m_pMemory
!= NULL
)
869 // allocate memory to receive the read data
870 if ((m_pMemory
= (char *)calloc(1, lSize
+ 1)) == NULL
)
871 SME_THROW(SM_MEMORY_ERROR
, NULL
, NULL
);
872 // now, read into the memory cache
873 lBytesRead
= fread(m_pMemory
, 1, lSize
, m_pFP
);
874 // now set what we'll return
884 //////////////////////////////////////////////////////////////////////////
885 void CSM_Buffer::Flush()
887 if (m_pCache
!= NULL
)
889 Write(m_pCache
, m_lCacheSize
);