]>
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
);