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