]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c++-lib/src/sm_buffer.cpp
68f9ae961d83fbfaea223ba440ef4b05490a9bdd
[apple/security.git] / SecuritySNACCRuntime / c++-lib / src / sm_buffer.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18 #ifndef __APPLE__
19 #ifndef NO_SCCS_ID
20 static char SccsId[ ] = "@(#) sm_buffer.cpp 1.17 5/7/98 16:36:20";
21 #endif
22 #endif
23
24 //////////////////////////////////////////////////////////////////////////
25 // sm_buffer.cpp
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 //////////////////////////////////////////////////////////////////////////
31
32 #include <stdio.h>
33 #if !defined(macintosh) && !defined(__APPLE__)
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #endif
37 #include <string.h>
38
39 #ifdef SUNOS
40 #include <unistd.h> // for SEEK_CUR and SEEK_END
41 #endif
42
43 #include "sm_vdasnacc.h"
44 #include <iomanip>
45
46 #if defined(macintosh) || defined(__APPLE__)
47
48 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
49
50 #define SME_SETUP(A) try {
51 #define SME_THROW(A, B, C) throw(static_cast<SM_RET_VAL>(A))
52 #define SME_FINISH }
53 #define SME_CATCH_SETUP catch(SM_RET_VAL) {
54 #define SME_CATCH_FINISH }
55 #define SM_RET_VAL long
56 #define SM_NO_ERROR 0
57 #define SME_FINISH_CATCH } catch(SM_RET_VAL) {}
58 #define SME(S) S
59
60 #define SM_MEMORY_ERROR memFullErr
61 #define SM_MISSING_PARAM paramErr
62 #define SM_FILEIO_ERROR ioErr
63
64 #else
65
66 #define SME_SETUP(A) do {} while (0)
67 #define SME_THROW(A, B, C) do {} while (0)
68 #define SME_FINISH
69 #define SME_CATCH_SETUP
70 #define SME_CATCH_FINISH
71 #define SM_RET_VAL long
72 #define SM_NO_ERROR 0
73 #define SME_FINISH_CATCH
74 #define SME(S) S
75
76 #endif
77
78 //////////////////////////////////////////////////////////////////////////
79 void CSM_Buffer::Clear()
80 {
81 m_lSize = 0;
82 m_pMemory = NULL;
83 #if !defined(macintosh) && !defined(__APPLE__)
84 m_pszFN = NULL;
85 m_pFP = NULL;
86 #endif
87 m_pMemFP = NULL;
88 m_pCache = NULL;
89 m_lCacheSize = 0;
90 }
91
92 //////////////////////////////////////////////////////////////////////////
93 CSM_Buffer::CSM_Buffer()
94 {
95 SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)");
96
97 Clear();
98
99 if ((m_pMemory = (char *)calloc(1, 1)) == NULL)
100 SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
101 SME(SetLength(0));
102
103 SME_FINISH_CATCH
104 }
105
106 //////////////////////////////////////////////////////////////////////////
107 CSM_Buffer::CSM_Buffer(size_t lSize)
108 {
109 SME_SETUP("CSM_Buffer::CSM_Buffer(size_t)");
110
111 Clear();
112
113 if ((m_pMemory = (char *)calloc(1, lSize + 1)) == NULL)
114 SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
115 SME(SetLength(lSize));
116
117 SME_FINISH_CATCH
118 }
119
120 //////////////////////////////////////////////////////////////////////////
121 #if !defined(macintosh) && !defined(__APPLE__)
122 CSM_Buffer::CSM_Buffer(char *pszFileName)
123 {
124 SME_SETUP("CSM_Buffer::CSM_Buffer(char*)");
125
126 Clear();
127
128 if (pszFileName == NULL)
129 SME_THROW(SM_MISSING_PARAM, NULL, NULL);
130
131 if ((m_pszFN = strdup(pszFileName)) == NULL)
132 SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
133
134 SME_FINISH_CATCH
135 }
136 #endif
137
138 //////////////////////////////////////////////////////////////////////////
139 CSM_Buffer::CSM_Buffer(const char *pBuf, SM_SIZE_T lSize)
140 {
141 SME_SETUP("CSM_Buffer::CSM_Buffer(char *, size_t)");
142
143 Clear();
144
145 if (pBuf == NULL)
146 SME_THROW(SM_MISSING_PARAM, NULL, NULL);
147
148 SME(Set(pBuf, lSize));
149
150 SME_FINISH_CATCH
151 }
152
153 //////////////////////////////////////////////////////////////////////////
154 CSM_Buffer::CSM_Buffer(const CSM_Buffer &b)
155 {
156 SME_SETUP("CSM_Buffer::CSM_Buffer(CSM_Buffer&)");
157
158 Clear();
159
160 SME(ReSet(b));
161
162 SME_FINISH_CATCH
163 }
164
165 //////////////////////////////////////////////////////////////////////////
166 CSM_Buffer::~CSM_Buffer()
167 {
168 if (m_pMemory)
169 free (m_pMemory);
170 #if !defined(macintosh) && !defined(__APPLE__)
171 if (m_pszFN)
172 free (m_pszFN);
173 if (m_pFP)
174 fclose(m_pFP);
175 #endif
176 if (m_pCache)
177 free (m_pCache);
178 }
179
180 //////////////////////////////////////////////////////////////////////////
181 SM_SIZE_T CSM_Buffer::Length() const
182 {
183 SM_SIZE_T lRet = 0;
184
185 SME_SETUP("CSM_Buffer::Length");
186
187 #if !defined(macintosh) && !defined(__APPLE__)
188 if (InFile())
189 {
190 // file version
191 struct stat statBuf;
192 // how big is data in file
193 if (stat(m_pszFN, &statBuf) == -1)
194 {
195 char szMsg[512];
196 sprintf(szMsg, "Couldn't stat file %s", m_pszFN);
197 SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
198 }
199 lRet = statBuf.st_size;
200 }
201 else
202 #endif
203 {
204 // memory version
205 lRet = m_lSize;
206 }
207
208 SME_FINISH_CATCH
209
210 return lRet;
211 }
212
213 //////////////////////////////////////////////////////////////////////////
214 void CSM_Buffer::Set(const char *psz)
215 {
216 SME_SETUP("CSM_Buffer::Set(char *)");
217 if (psz == NULL)
218 SME_THROW(SM_MISSING_PARAM, NULL, NULL);
219 if (m_pMemory)
220 free(m_pMemory);
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);
227 SME(SetLength(len));
228 #else
229 if ((m_pMemory = strdup(psz)) == NULL)
230 SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
231 SME(SetLength(strlen(psz)));
232 #endif
233 SME_FINISH_CATCH
234 }
235
236 //////////////////////////////////////////////////////////////////////////
237 void CSM_Buffer::Set(const char *p, SM_SIZE_T lSize)
238 {
239 SME_SETUP("CSM_Buffer::Set(char *, size_t)");
240 if (m_pMemory)
241 free(m_pMemory);
242
243 if (p == NULL)
244 {
245 m_pMemory = NULL;
246 SME(SetLength(0));
247 }
248 else
249 {
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));
255 }
256 SME_FINISH_CATCH
257 }
258
259 //////////////////////////////////////////////////////////////////////////
260 // allocate memory in the cache
261 char* CSM_Buffer::Alloc(SM_SIZE_T lSize)
262 {
263 SME_SETUP("CSM_Buffer::Alloc");
264
265 if (m_pCache)
266 free(m_pCache);
267 if ((m_pCache = (char *)calloc(1, lSize)) == NULL)
268 SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
269 m_lCacheSize = lSize;
270
271 SME_FINISH_CATCH
272
273 return m_pCache;
274 }
275
276 //////////////////////////////////////////////////////////////////////////
277 void CSM_Buffer::AllocMoreMem(SM_SIZE_T lSize)
278 {
279 char *pNew;
280 SM_SIZE_T lLength = Length();
281
282 SME_SETUP("CSM_Buffer::AllocMoreMem");
283
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);
289 free(m_pMemory);
290 m_pMemory = pNew;
291
292 SME_FINISH_CATCH
293 }
294
295 //////////////////////////////////////////////////////////////////////////
296 const char* CSM_Buffer::Access() const
297 {
298 SME_SETUP("CSM_Buffer::Access");
299 #if !defined(macintosh) && !defined(__APPLE__)
300 if (InFile())
301 {
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)
305 free (m_pMemory);
306 SME(m_pMemory = Get());
307 }
308 #endif
309 SME_FINISH_CATCH
310 return m_pMemory;
311 }
312
313 //////////////////////////////////////////////////////////////////////////
314 // return a copy of the actual data and return the size
315 char* CSM_Buffer::Get(SM_SIZE_T &l) const
316 {
317 char *pRet = NULL;
318 SME_SETUP("CSM_Buffer::Get");
319
320 SM_SIZE_T lSize = Length();
321
322 #if !defined(macintosh) && !defined(__APPLE__)
323 if (InFile()) // data in file
324 {
325 // allocate memory
326 if ((pRet = (char *)calloc(1, lSize + 1)) == NULL)
327 SME_THROW(SM_MEMORY_ERROR, "calloc failure", NULL);
328 // close file if present
329 if (m_pFP != NULL)
330 fclose(m_pFP);
331 // open the file
332 if ((m_pFP = fopen(m_pszFN, SM_FOPEN_READ)) == NULL)
333 {
334 char szMsg[512];
335 sprintf(szMsg, "Couldn't open file %s", m_pszFN);
336 SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
337 }
338 // read the data
339 long lRead = fread(pRet, 1, lSize, m_pFP);
340 if (ferror(m_pFP) != 0)
341 {
342 char szMsg[512];
343 sprintf(szMsg, "Couldn't read file %s", m_pszFN);
344 SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
345 }
346 // close and clear FP
347 fclose(m_pFP);
348 m_pFP = NULL;
349 l = lRead; // store the size that will be returned
350 }
351 else
352 #endif
353 {
354 // if there is data, duplicate it
355 if (m_pMemory)
356 {
357 pRet = (char *)calloc(1, lSize);
358 memcpy(pRet, m_pMemory, lSize);
359 l = lSize; // store the size that will be returned
360 }
361 }
362
363 SME_FINISH
364 SME_CATCH_SETUP
365 if (pRet != NULL)
366 {
367 free(pRet);
368 pRet = NULL;
369 }
370 #if !defined(macintosh) && !defined(__APPLE__)
371 if (m_pFP != NULL)
372 {
373 fclose(m_pFP);
374 m_pFP = NULL;
375 }
376 #endif
377 SME_CATCH_FINISH
378 return pRet;
379 }
380
381 //////////////////////////////////////////////////////////////////////////
382 // compare buffers regardless of memory/file status
383 long CSM_Buffer::Compare(const CSM_Buffer &b)
384 {
385 const char *p1 = NULL;
386 const char *p2 = NULL;
387 long lRet = -2;
388
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)
394 {
395 if ((p2 = b.Access()) != NULL)
396 {
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
402 }
403 #if !defined(macintosh) && !defined(__APPLE__)
404 else
405 if (InFile())
406 free (p1);
407 #endif
408 }
409 SME_FINISH_CATCH
410 return lRet;
411 }
412
413 //////////////////////////////////////////////////////////////////////////
414 // copy b into this
415 SM_RET_VAL CSM_Buffer::ReSet(const CSM_Buffer &b)
416 {
417 char *p;
418 SM_SIZE_T l;
419 SME_SETUP("CSM_Buffer::ReSet");
420
421 #if !defined(macintosh) && !defined(__APPLE__)
422 m_pszFNP = NULL;
423 m_pFP = NULL;
424 #endif
425 if (m_pMemory)
426 free(m_pMemory);
427
428 m_pMemory = m_pMemFP = NULL;
429 SME(SetLength(0));
430 m_pCache = NULL;
431 m_lCacheSize = 0;
432
433 SME(p = b.Get(l));
434
435 SME(Set(p, l));
436
437 free(p);
438
439 SME_FINISH_CATCH
440
441 return SM_NO_ERROR;
442 }
443
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()
449 {
450 SM_SIZE_T l;
451
452 SME_SETUP("CSM_Buffer::ConvertFileToMemory");
453
454 if (m_pszFN == NULL)
455 // we're already in memory
456 return SM_NO_ERROR;
457
458 // read everything into memory
459 SME(m_pMemory = Get(l));
460
461 // free the file name
462 free(m_pszFN);
463 m_pszFN = NULL;
464
465 // store the new size
466 SME(SetLength(l));
467
468 SME_FINISH_CATCH
469
470 return SM_NO_ERROR;
471 }
472
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)
477 {
478 SM_SIZE_T lRet = 0;
479
480 SME_SETUP("CSM_Buffer::ConvertMemoryToFile");
481
482 if (pszFN == NULL)
483 SME_THROW(SM_NO_FILENAME, NULL, NULL);
484
485 if (InFile())
486 {
487 if (strcmp(m_pszFN, pszFN) == 0) // we're already in file
488 return SM_NO_ERROR;
489 else
490 {
491 SM_SIZE_T lBytesRead;
492 SM_SIZE_T lSize=4096;
493 char *ptr;
494 FILE *fp=fopen(pszFN, "w");
495 this->Open(SM_FOPEN_READ);
496 while ((ptr=this->nRead(lSize, lBytesRead)) != NULL && lBytesRead > 0)
497 {
498 fwrite(ptr, 1, lBytesRead, fp);
499 }
500 this->Close();
501 fclose(fp);
502 return(SM_NO_ERROR);
503 }
504 }
505
506 // open the new file
507 if ((m_pFP = fopen(pszFN, SM_FOPEN_WRITE)) == NULL)
508 {
509 char szMsg[512];
510 sprintf(szMsg, "Couldn't stat file %s", pszFN);
511 SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
512 }
513
514 // write the data
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);
519
520 if ((lRet = fwrite(m_pMemory, 1, lLength, m_pFP)) != lLength)
521 {
522 char szMsg[512];
523 sprintf(szMsg, "Couldn't write file %s", m_pszFN);
524 SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
525 }
526
527 fclose(m_pFP);
528 m_pFP = NULL;
529
530 SME_FINISH
531 SME_CATCH_SETUP
532 // cleanup/catch code
533 if ((m_pszFN != NULL) && (pszFN != NULL))
534 {
535 free(m_pszFN);
536 m_pszFN = NULL;
537 }
538 SME_CATCH_FINISH
539
540 return SM_NO_ERROR;
541 }
542 #endif
543
544 //////////////////////////////////////////////////////////////////////////
545 SM_RET_VAL CSM_Buffer::Open(char *pszMode)
546 {
547 SME_SETUP("CSM_Buffer::Open");
548
549 if (pszMode == NULL)
550 SME_THROW(SM_MISSING_PARAM, NULL, NULL);
551
552 #if !defined(macintosh) && !defined(__APPLE__)
553 if (!InFile())
554 #endif
555 // memory version
556 m_pMemFP = m_pMemory; // set current pointer to start
557 #if !defined(macintosh) && !defined(__APPLE__)
558 else
559 // file version
560 if ((m_pFP = fopen(m_pszFN, pszMode)) == NULL)
561 {
562 char szMsg[512];
563 sprintf(szMsg, "Couldn't open file %s", m_pszFN);
564 SME_THROW(SM_FILEIO_ERROR, szMsg, NULL);
565 }
566 #endif
567
568 SME_FINISH_CATCH
569 return SM_NO_ERROR;
570 }
571
572 //////////////////////////////////////////////////////////////////////////
573 SM_RET_VAL CSM_Buffer::Seek(SM_SIZE_T lOffset, SM_SIZE_T lOrigin)
574 {
575 SM_RET_VAL lRet = SM_NO_ERROR;
576
577 SME_SETUP("CSM_Buffer::Seek");
578
579 #if !defined(macintosh) && !defined(__APPLE__)
580 if (!InFile())
581 #endif
582 {
583 // memory version
584 char *pSave = m_pMemFP;
585
586 if (m_pMemFP == NULL)
587 SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
588
589 SM_SIZE_T lLength = Length();
590
591 switch (lOrigin)
592 {
593 case SEEK_CUR:
594 m_pMemFP += lOffset;
595 break;
596 case SEEK_END:
597 m_pMemFP = (m_pMemory + lLength - 1) + lOffset;
598 break;
599 default: // SEEK_SET
600 m_pMemFP = m_pMemory + lOffset;
601 break;
602 }
603 if ((m_pMemFP > (m_pMemory + lLength - 1)) ||
604 (m_pMemFP < m_pMemory))
605 {
606 m_pMemFP = pSave;
607 lRet = -1;
608 }
609 }
610 #if !defined(macintosh) && !defined(__APPLE__)
611 else
612 {
613 // file version
614 if (m_pFP == NULL)
615 SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
616
617 lRet = fseek(m_pFP, lOffset, lOrigin);
618 }
619 #endif
620
621 SME_FINISH_CATCH
622
623 return lRet;
624 }
625
626 //////////////////////////////////////////////////////////////////////////
627 void CSM_Buffer::Close()
628 {
629 #if !defined(macintosh) && !defined(__APPLE__)
630 if (m_pFP != NULL)
631 {
632 fclose(m_pFP);
633 m_pFP = NULL;
634 if (m_pMemory)
635 {
636 free(m_pMemory);
637 m_pMemory = NULL;
638 }
639 }
640 else
641 #endif
642 m_pMemFP = NULL;
643 }
644
645 //////////////////////////////////////////////////////////////////////////
646 AsnType *CSM_Buffer::Clone() const
647 {
648 return new CSM_Buffer;
649 }
650
651 //////////////////////////////////////////////////////////////////////////
652 AsnType *CSM_Buffer::Copy() const
653 {
654 return new CSM_Buffer (*this);
655 }
656
657 //////////////////////////////////////////////////////////////////////////
658 AsnLen CSM_Buffer::BEnc(BUF_TYPE BBuf)
659 {
660 char *ptr;
661 unsigned int jj=0;
662 SM_SIZE_T lRead=1;
663 SM_SIZE_T lOffset;
664
665 this->Open(SM_FOPEN_READ);
666 for (jj = 0; jj < this->Length() && lRead > 0; jj += lRead)
667 {
668 if (jj == 0) // first time, only get last X bytes within 4096 block.
669 {
670 lOffset = this->Length() - (this->Length() % 4096);
671 }
672 else
673 lOffset -= 4096;
674 this->Seek(lOffset, 0);
675 ptr = this->nRead(4096, lRead);
676 BBuf.PutSegRvs(ptr, lRead);
677 }
678 this->Close();
679
680 return this->Length();
681 }
682
683 //////////////////////////////////////////////////////////////////////////
684 void CSM_Buffer::Print (ostream &os) const
685 {
686 #ifndef NDEBUG
687 int len = Length();
688 int i;
689
690 os << "{ -- ANY --" << endl;
691 indentG += stdIndentG;
692 Indent (os, indentG);
693
694 long oFlags = os.flags();
695 os << hex;
696 for (i = 0; i < len; i++)
697 {
698 os << setw(2) << setfill('0')
699 << static_cast<unsigned int>(static_cast<unsigned char>(m_pMemory[i])) << " ";
700
701 if (i == len - 1 || i % 16 == 15)
702 {
703 int j;
704 os << " ";
705 for (j = i > 15 ? i - 15 : 0; j <= i; j++)
706 {
707 if (m_pMemory[j] >= 0x20 && m_pMemory[j] < 0x80)
708 os << m_pMemory[j];
709 else
710 os << '.';
711 }
712 os << endl;
713 }
714 }
715
716 os.flags(oFlags);
717 os << endl;
718 indentG -= stdIndentG;
719 Indent (os, indentG);
720 os << "}";
721 #endif NDEBUG
722 }
723
724 //////////////////////////////////////////////////////////////////////////
725 SM_RET_VAL CSM_Buffer::cRead(char *pBuffer, SM_SIZE_T lSize)
726 {
727 SM_RET_VAL lRet = 0;
728
729 SME_SETUP("CSM_Buffer::cRead");
730
731 if ((pBuffer == NULL) || (lSize <= 0))
732 SME_THROW(SM_MISSING_PARAM, NULL, NULL);
733
734 #if !defined(macintosh) && !defined(__APPLE__)
735 if (!InFile())
736 #endif
737 {
738 // memory version
739 if (m_pMemFP == NULL)
740 SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
741
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
749 if (lReadSize > 0)
750 {
751 m_pMemFP += lReadSize;
752 lRet = lReadSize;
753 }
754 else
755 lRet = 0;
756 }
757 #if !defined(macintosh) && !defined(__APPLE__)
758 else
759 {
760 // file version
761 if (m_pFP == NULL)
762 SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
763
764 lRet = fread(pBuffer, 1, lSize, m_pFP);
765 }
766 #endif
767
768 SME_FINISH_CATCH
769
770 return lRet;
771 }
772
773 //////////////////////////////////////////////////////////////////////////
774 SM_RET_VAL CSM_Buffer::Write(const char *pBuffer, SM_SIZE_T lSize)
775 {
776 SM_RET_VAL lRet = 0;
777
778 SME_SETUP("CSM_Buffer::Write");
779
780 if ((pBuffer == NULL) || (lSize <= 0))
781 SME_THROW(SM_MISSING_PARAM, NULL, NULL);
782
783 #if !defined(macintosh) && !defined(__APPLE__)
784 if (!InFile())
785 #endif
786 {
787 // memory version
788 if (m_pMemFP == NULL)
789 {
790 if (m_pMemory == NULL)
791 {
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);
796 SetLength(lSize);
797 }
798 else
799 m_pMemFP = m_pMemory;
800 }
801
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
805 AllocMoreMem(lSize);
806 memcpy(m_pMemFP, pBuffer, lSize);
807 m_pMemFP += lSize;
808 lRet = lSize;
809 }
810 #if !defined(macintosh) && !defined(__APPLE__)
811 else
812 {
813 // file version
814 if (m_pFP == NULL)
815 SME_THROW(SM_FILEIO_ERROR, "FP is NULL", NULL);
816
817 if ((lRet = fwrite(pBuffer, 1, lSize, m_pFP)) > 0)
818 SetLength(m_lSize + lRet);
819 }
820 #endif
821
822 SME_FINISH_CATCH
823
824 return lRet;
825 }
826
827 //////////////////////////////////////////////////////////////////////////
828 char* CSM_Buffer::nRead(SM_SIZE_T lSize, SM_SIZE_T &lBytesRead)
829 {
830 char *pRet = NULL;
831
832 SME_SETUP("CSM_Buffer::nRead");
833
834 if (lSize <= 0)
835 SME_THROW(SM_MISSING_PARAM, NULL, NULL);
836
837 #if !defined(macintosh) && !defined(__APPLE__)
838 if (!InFile())
839 #endif
840 {
841 // memory version
842 if (m_pMemFP == NULL)
843 SME_THROW(SM_MEMORY_ERROR, NULL, NULL);
844
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;
850 pRet = m_pMemFP;
851 // adjust the current pointer
852 if (lReadSize > 0)
853 {
854 m_pMemFP += lReadSize;
855 lBytesRead = lReadSize;
856 }
857 else
858 lBytesRead = 0;
859 }
860 #if !defined(macintosh) && !defined(__APPLE__)
861 else
862 {
863 // file version
864 if (m_pFP == NULL)
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)
868 free (m_pMemory);
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
875 pRet = m_pMemory;
876 }
877 #endif
878
879 SME_FINISH_CATCH
880
881 return pRet;
882 }
883
884 //////////////////////////////////////////////////////////////////////////
885 void CSM_Buffer::Flush()
886 {
887 if (m_pCache != NULL)
888 {
889 Write(m_pCache, m_lCacheSize);
890 free(m_pCache);
891 m_pCache = NULL;
892 m_lCacheSize = 0;
893 }
894 }
895
896 // EOF sm_buffer.cpp