1// 2// CommonBuffering.c 3// CommonCrypto 4// 5 6#include <stdio.h> 7#include "ccMemory.h" 8#include "CommonBufferingPriv.h" 9#include <AssertMacros.h> 10 11 12CNBufferRef 13CNBufferCreate(size_t chunksize) 14{ 15 CNBufferRef retval = CC_XMALLOC(sizeof(CNBuffer)); 16 __Require_Quiet(NULL != retval, errOut); 17 retval->chunksize = chunksize; 18 retval->bufferPos = 0; 19 retval->buf = CC_XMALLOC(chunksize); 20 __Require_Quiet(NULL != retval->buf, errOut); 21 return retval; 22 23errOut: 24 if(retval) { 25 if(retval->buf) CC_XFREE(retval->buf, chunksize); 26 CC_XFREE(retval, sizeof(CNBuffer)); 27 } 28 return NULL; 29} 30 31CNStatus 32CNBufferRelease(CNBufferRef *bufRef) 33{ 34 CNBufferRef ref; 35 36 __Require_Quiet(NULL != bufRef, out); 37 ref = *bufRef; 38 if(ref->buf) CC_XFREE(ref->buf, chunksize); 39 if(ref) CC_XFREE(ref, sizeof(CNBuffer)); 40out: 41 return kCNSuccess; 42} 43 44 45 46CNStatus 47CNBufferProcessData(CNBufferRef bufRef, 48 void *ctx, const void *in, const size_t inLen, void *out, size_t *outLen, 49 cnProcessFunction pFunc, cnSizeFunction sizeFunc) 50{ 51 size_t blocksize = bufRef->chunksize; 52 uint8_t *input = (uint8_t *) in, *output = out; 53 size_t inputLen = inLen, outputLen, inputUsing, outputAvailable; 54 55 outputAvailable = outputLen = *outLen; 56 57 if(sizeFunc(ctx, bufRef->bufferPos + inLen) > outputAvailable) return kCNBufferTooSmall; 58 *outLen = 0; 59 if(bufRef->bufferPos > 0) { 60 inputUsing = CC_XMIN(blocksize - bufRef->bufferPos, inputLen); 61 CC_XMEMCPY(&bufRef->buf[bufRef->bufferPos], in, inputUsing); 62 bufRef->bufferPos += inputUsing; 63 if(bufRef->bufferPos < blocksize) { 64 return kCNSuccess; 65 } 66 pFunc(ctx, bufRef->buf, blocksize, output, &outputLen); 67 inputLen -= inputUsing; input += inputUsing; 68 output += outputLen; *outLen = outputLen; outputAvailable -= outputLen; 69 bufRef->bufferPos = 0; 70 } 71 72 inputUsing = inputLen - inputLen % blocksize; 73 if(inputUsing > 0) { 74 outputLen = outputAvailable; 75 pFunc(ctx, input, inputUsing, output, &outputLen); 76 inputLen -= inputUsing; input += inputUsing; 77 *outLen += outputLen; 78 } 79 80 if(inputLen > blocksize) { 81 return kCNAlignmentError; 82 } else if(inputLen > 0) { 83 CC_XMEMCPY(bufRef->buf, input, inputLen); 84 bufRef->bufferPos = inputLen; 85 } 86 return kCNSuccess; 87 88} 89 90CNStatus 91CNBufferFlushData(CNBufferRef bufRef, 92 void *ctx, void *out, size_t *outLen, 93 cnProcessFunction pFunc, cnSizeFunction sizeFunc) 94{ 95// size_t outputLen, outputAvailable; 96// outputAvailable = outputLen = *outLen; 97 98 if(bufRef->bufferPos > 0) { 99 if(bufRef->bufferPos > bufRef->chunksize) return kCNAlignmentError; 100 if(sizeFunc(ctx, bufRef->bufferPos) > *outLen) return kCNBufferTooSmall; 101 pFunc(ctx, bufRef->buf, bufRef->bufferPos, out, outLen); 102 } else { 103 *outLen = 0; 104 } 105 return kCNSuccess; 106} 107 108 109 110bool 111CNBufferEmpty(CNBufferRef bufRef) 112{ 113 return bufRef->bufferPos == 0; 114} 115