version 1.2, 2015/04/20 18:10:09
|
version 1.3, 2015/04/20 18:19:50
|
|
|
#include <stdlib.h> | #include <stdlib.h> |
#include <string.h> | #include <string.h> |
#include "strarr.h" | #include "strarr.h" |
#include "strings.h" |
#include <pal/strings.h> |
|
#include "alloc.h" |
| |
char** StrArr() | char** StrArr() |
{ | { |
return (char**)calloc(1, sizeof(char*)); |
return (char**)PAL_Calloc(1, sizeof(char*)); |
} | } |
| |
void StrArrCat(char*** self_, const char* str) |
_Use_decl_annotations_ |
|
void StrArrCat(CharPtrPtr * self_, ConstCharPtr str) |
{ | { |
size_t len; | size_t len; |
char** self = *self_; |
CharPtrPtr self = *self_; |
| |
len = StrArrLen(self); | len = StrArrLen(self); |
self = (char**)realloc(self, sizeof(char*) * (len + 2)); |
self = (CharPtrPtr)PAL_Realloc(self, sizeof(char*) * (len + 2)); |
| |
if (self) | if (self) |
{ | { |
char* s = Strdup(str); |
CharPtr s = PAL_Strdup(str); |
self[len] = s; | self[len] = s; |
self[len+1] = NULL; | self[len+1] = NULL; |
} | } |
| |
|
#ifdef _PREFAST_ |
|
#pragma prefast (push) |
|
#pragma prefast (disable: 26036) |
|
#endif |
|
/* |
|
OACR does not like NULL-ing buffers by using length above, instead it wants us to walk the entire array manually. |
|
This isn't necessary here. The logic is correct. |
|
*/ |
*self_ = self; | *self_ = self; |
|
#ifdef _PREFAST_ |
|
#pragma prefast (pop) |
|
#endif |
} | } |
| |
size_t StrArrLen(char** self) |
_Use_decl_annotations_ |
|
size_t StrArrLen(CharPtrPtr self) |
{ | { |
char** p = self; |
CharPtrPtr p = self; |
| |
while (*p) | while (*p) |
p++; | p++; |
|
|
return p - self; | return p - self; |
} | } |
| |
void StrArrFree(char** self) |
_Use_decl_annotations_ |
|
void StrArrFree(CharPtrPtr self) |
{ | { |
char** p = self; |
CharPtrPtr p = self; |
while (*p) | while (*p) |
free(*p++); |
PAL_Free(*p++); |
| |
free(self); |
PAL_Free(self); |
} | } |
|
|
|
wchar_t** WcsArr() |
|
{ |
|
return (wchar_t**)PAL_Calloc(1, sizeof(wchar_t*)); |
|
} |
|
|
|
_Use_decl_annotations_ |
|
void WcsArrCat(WcharPtrPtr * self_, ConstWcharPtr str) |
|
{ |
|
size_t len; |
|
WcharPtrPtr self = *self_; |
|
|
|
len = WcsArrLen(self); |
|
self = (WcharPtrPtr)PAL_Realloc(self, sizeof(wchar_t*) * (len + 2)); |
|
|
|
if (self) |
|
{ |
|
wchar_t* s = PAL_Wcsdup(str); |
|
self[len] = s; |
|
self[len+1] = NULL; |
|
} |
|
|
|
#ifdef _PREFAST_ |
|
#pragma prefast (push) |
|
#pragma prefast (disable: 26036) |
|
#endif |
|
/* |
|
OACR does not like NULL-ing buffers by using length above, instead it wants us to walk the entire array manually. |
|
This isn't necessary here. The logic is correct. |
|
*/ |
|
*self_ = self; |
|
#ifdef _PREFAST_ |
|
#pragma prefast (pop) |
|
#endif |
|
} |
|
|
|
_Use_decl_annotations_ |
|
size_t WcsArrLen(WcharPtrPtr self) |
|
{ |
|
WcharPtrPtr p = self; |
|
|
|
while (*p) |
|
p++; |
|
|
|
return p - self; |
|
} |
|
|
|
_Use_decl_annotations_ |
|
void WcsArrFree(WcharPtrPtr self) |
|
{ |
|
WcharPtrPtr p = self; |
|
while (*p) |
|
PAL_Free(*p++); |
|
|
|
PAL_Free(self); |
|
} |
|
|
|
_Use_decl_annotations_ |
|
ZChar** CloneStringArray( |
|
const ZChar** data, |
|
MI_Uint32 size, |
|
Batch* batch) |
|
{ |
|
size_t n; |
|
MI_Uint32 i; |
|
ZChar* ptr; |
|
ZChar** array; |
|
|
|
/* Empty arrays are represented by NULL */ |
|
if (!data || size == 0) |
|
return NULL; |
|
|
|
/* Calculate space for pointer array */ |
|
n = size * sizeof(ZChar*); |
|
|
|
/* Calculate space for strings (add space for zero terminators) */ |
|
for (i = 0; i < size; i++) |
|
{ |
|
if (!data[i]) |
|
{ |
|
/* Null elements are illegal */ |
|
return NULL; |
|
} |
|
|
|
n += (Tcslen(data[i]) + 1) * sizeof(ZChar); |
|
} |
|
|
|
/* Allocate memory */ |
|
array = (ZChar**)BAlloc(batch, n, CALLSITE); |
|
|
|
if (!array) |
|
return NULL; |
|
|
|
ptr = (ZChar*)&array[size]; |
|
|
|
/* Copy the strings */ |
|
for (i = 0; i < size; i++) |
|
{ |
|
size_t count = Tcslen(data[i]) + 1; |
|
memcpy(ptr, data[i], count * sizeof(ZChar)); |
|
array[i] = ptr; |
|
ptr += count; |
|
} |
|
|
|
return array; |
|
} |
|
|