diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Array.cpp | 49 | ||||
| -rw-r--r-- | src/Data.cpp | 21 | ||||
| -rw-r--r-- | src/Date.cpp | 22 | ||||
| -rw-r--r-- | src/Dictionary.cpp | 8 | ||||
| -rw-r--r-- | src/Integer.cpp | 3 | ||||
| -rw-r--r-- | src/Key.cpp | 2 | ||||
| -rw-r--r-- | src/Node.cpp | 2 | ||||
| -rw-r--r-- | src/String.cpp | 23 | ||||
| -rw-r--r-- | src/Structure.cpp | 27 | ||||
| -rw-r--r-- | src/bplist.c | 78 | ||||
| -rw-r--r-- | src/jplist.c | 10 | ||||
| -rw-r--r-- | src/oplist.c | 4 | ||||
| -rw-r--r-- | src/plist.c | 210 |
13 files changed, 304 insertions, 155 deletions
diff --git a/src/Array.cpp b/src/Array.cpp index bc448d3..49b8924 100644 --- a/src/Array.cpp +++ b/src/Array.cpp @@ -40,7 +40,9 @@ static void array_fill(Array *_this, std::vector<Node*> &array, plist_t node) do { subnode = NULL; plist_array_next_item(node, iter, &subnode); - array.push_back( Node::FromPlist(subnode, _this) ); + if (subnode) { + array.push_back( Node::FromPlist(subnode, _this) ); + } } while (subnode); free(iter); } @@ -51,7 +53,7 @@ Array::Array(plist_t node, Node* parent) : Structure(parent) array_fill(this, _array, _node); } -Array::Array(const PList::Array& a) +Array::Array(const PList::Array& a) : Structure(a.GetParent()) { _array.clear(); _node = plist_copy(a.GetPlist()); @@ -88,6 +90,26 @@ Node* Array::operator[](unsigned int array_index) return _array.at(array_index); } +Node* Array::Back() +{ + return _array.back(); +} + +Node* Array::back() +{ + return _array.back(); +} + +Node* Array::Front() +{ + return _array.front(); +} + +Node* Array::front() +{ + return _array.front(); +} + Array::iterator Array::Begin() { return _array.begin(); @@ -132,7 +154,7 @@ size_t Array::size() const { return _array.size(); } -void Array::Append(Node* node) +void Array::Append(const Node* node) { if (node) { @@ -143,7 +165,12 @@ void Array::Append(Node* node) } } -void Array::Insert(Node* node, unsigned int pos) +void Array::Append(const Node& node) +{ + Append(&node); +} + +void Array::Insert(const Node* node, unsigned int pos) { if (node) { @@ -156,6 +183,11 @@ void Array::Insert(Node* node, unsigned int pos) } } +void Array::Insert(const Node &node, unsigned int pos) +{ + Insert(&node, pos); +} + void Array::Remove(Node* node) { if (node) @@ -168,7 +200,7 @@ void Array::Remove(Node* node) std::vector<Node*>::iterator it = _array.begin(); it += pos; _array.erase(it); - delete node; + free(node); } } @@ -181,10 +213,15 @@ void Array::Remove(unsigned int pos) _array.erase(it); } -unsigned int Array::GetNodeIndex(Node* node) const +unsigned int Array::GetNodeIndex(const Node* node) const { std::vector<Node*>::const_iterator it = std::find(_array.begin(), _array.end(), node); return std::distance (_array.begin(), it); } +unsigned int Array::GetNodeIndex(const Node& node) const +{ + return GetNodeIndex(&node); +} + } // namespace PList diff --git a/src/Data.cpp b/src/Data.cpp index c4709f7..56b2d6b 100644 --- a/src/Data.cpp +++ b/src/Data.cpp @@ -34,7 +34,7 @@ Data::Data(plist_t node, Node* parent) : Node(node, parent) Data::Data(const PList::Data& d) : Node(PLIST_DATA) { - std::vector<uint8_t> b = d.GetValue(); + std::vector<char> b = d.GetValue(); plist_set_data_val(_node, &b[0], b.size()); } @@ -45,11 +45,16 @@ Data& Data::operator=(const PList::Data& b) return *this; } -Data::Data(const std::vector<uint8_t>& buff) : Node(PLIST_DATA) +Data::Data(const std::vector<char>& buff) : Node(PLIST_DATA) { plist_set_data_val(_node, &buff[0], buff.size()); } +Data::Data(const char* buff, uint64_t size) : Node(PLIST_DATA) +{ + plist_set_data_val(_node, buff, size); +} + Data::~Data() { } @@ -59,21 +64,17 @@ Node* Data::Clone() const return new Data(*this); } -void Data::SetValue(const std::vector<uint8_t>& buff) +void Data::SetValue(const std::vector<char>& buff) { plist_set_data_val(_node, &buff[0], buff.size()); } -std::vector<uint8_t> Data::GetValue() const +std::vector<char> Data::GetValue() const { - uint8_t* buff = NULL; uint64_t length = 0; - plist_get_data_val(_node, &buff, &length); - std::vector<uint8_t> ret(buff, buff + length); - delete buff; + const char* buff = plist_get_data_ptr(_node, &length); + std::vector<char> ret(buff, buff + length); return ret; } - - } // namespace PList diff --git a/src/Date.cpp b/src/Date.cpp index 8b8e650..cbfa123 100644 --- a/src/Date.cpp +++ b/src/Date.cpp @@ -34,8 +34,8 @@ Date::Date(plist_t node, Node* parent) : Node(node, parent) Date::Date(const PList::Date& d) : Node(PLIST_DATE) { - timeval t = d.GetValue(); - plist_set_date_val(_node, t.tv_sec, t.tv_usec); + int64_t t = d.GetValue(); + plist_set_unix_date_val(_node, t); } Date& Date::operator=(const PList::Date& d) @@ -45,9 +45,9 @@ Date& Date::operator=(const PList::Date& d) return *this; } -Date::Date(timeval t) : Node(PLIST_DATE) +Date::Date(int64_t t) : Node(PLIST_DATE) { - plist_set_date_val(_node, t.tv_sec, t.tv_usec); + plist_set_unix_date_val(_node, t); } Date::~Date() @@ -59,18 +59,16 @@ Node* Date::Clone() const return new Date(*this); } -void Date::SetValue(timeval t) +void Date::SetValue(int64_t t) { - plist_set_date_val(_node, t.tv_sec, t.tv_usec); + plist_set_unix_date_val(_node, t); } -timeval Date::GetValue() const +int64_t Date::GetValue() const { - int32_t tv_sec = 0; - int32_t tv_usec = 0; - plist_get_date_val(_node, &tv_sec, &tv_usec); - timeval t = {tv_sec, tv_usec}; - return t; + int64_t sec = 0; + plist_get_unix_date_val(_node, &sec); + return sec; } } // namespace PList diff --git a/src/Dictionary.cpp b/src/Dictionary.cpp index 30c20b6..0a909e5 100644 --- a/src/Dictionary.cpp +++ b/src/Dictionary.cpp @@ -40,7 +40,7 @@ static void dictionary_fill(Dictionary *_this, std::map<std::string,Node*> &map, plist_dict_next_item(node, it, &key, &subnode); if (key && subnode) map[std::string(key)] = Node::FromPlist(subnode, _this); - delete key; + free(key); } while (subnode); free(it); } @@ -51,7 +51,7 @@ Dictionary::Dictionary(plist_t node, Node* parent) : Structure(parent) dictionary_fill(this, _map, _node); } -Dictionary::Dictionary(const PList::Dictionary& d) +Dictionary::Dictionary(const PList::Dictionary& d) : Structure(d.GetParent()) { for (Dictionary::iterator it = _map.begin(); it != _map.end(); it++) { @@ -176,9 +176,9 @@ void Dictionary::Remove(Node* node) plist_dict_get_item_key(node->GetPlist(), &key); plist_dict_remove_item(_node, key); std::string skey = key; - delete key; + free(key); _map.erase(skey); - delete node; + free(node); } } diff --git a/src/Integer.cpp b/src/Integer.cpp index 30a5405..653455d 100644 --- a/src/Integer.cpp +++ b/src/Integer.cpp @@ -35,7 +35,8 @@ Integer::Integer(plist_t node, Node* parent) : Node(node, parent) Integer::Integer(const PList::Integer& i) : Node(PLIST_INT) { - plist_set_uint_val(_node, i.GetValue()); + plist_free(_node); + _node = plist_copy(i.GetPlist()); } Integer& Integer::operator=(const PList::Integer& i) diff --git a/src/Key.cpp b/src/Key.cpp index 79265d5..86a0bf8 100644 --- a/src/Key.cpp +++ b/src/Key.cpp @@ -69,7 +69,7 @@ std::string Key::GetValue() const char* s = NULL; plist_get_key_val(_node, &s); std::string ret = s ? s : ""; - delete s; + free(s); return ret; } diff --git a/src/Node.cpp b/src/Node.cpp index 0bd428a..1043b31 100644 --- a/src/Node.cpp +++ b/src/Node.cpp @@ -73,7 +73,7 @@ Node::Node(plist_type type, Node* parent) : _parent(parent) _node = plist_new_data(NULL,0); break; case PLIST_DATE: - _node = plist_new_date(0,0); + _node = plist_new_unix_date(0); break; case PLIST_ARRAY: _node = plist_new_array(); diff --git a/src/String.cpp b/src/String.cpp index 2ddc28b..8daec0f 100644 --- a/src/String.cpp +++ b/src/String.cpp @@ -45,11 +45,30 @@ String& String::operator=(const PList::String& s) return *this; } +String& String::operator=(const std::string& s) +{ + plist_free(_node); + _node = plist_new_string(s.c_str()); + return *this; +} + +String& String::operator=(const char* s) +{ + plist_free(_node); + _node = plist_new_string(s); + return *this; +} + String::String(const std::string& s) : Node(PLIST_STRING) { plist_set_string_val(_node, s.c_str()); } +String::String(const char *s) : Node(PLIST_STRING) +{ + plist_set_string_val(_node, s); +} + String::~String() { } @@ -66,10 +85,8 @@ void String::SetValue(const std::string& s) std::string String::GetValue() const { - char* s = NULL; - plist_get_string_val(_node, &s); + const char* s = plist_get_string_ptr(_node, NULL); std::string ret = s ? s : ""; - delete s; return ret; } diff --git a/src/Structure.cpp b/src/Structure.cpp index 670cce6..65e5ca8 100644 --- a/src/Structure.cpp +++ b/src/Structure.cpp @@ -57,7 +57,7 @@ std::string Structure::ToXml() const uint32_t length = 0; plist_to_xml(_node, &xml, &length); std::string ret(xml, xml+length); - delete xml; + free(xml); return ret; } @@ -67,7 +67,7 @@ std::vector<char> Structure::ToBin() const uint32_t length = 0; plist_to_bin(_node, &bin, &length); std::vector<char> ret(bin, bin+length); - delete bin; + free(bin); return ret; } @@ -77,7 +77,7 @@ void Structure::UpdateNodeParent(Node* node) if ( NULL != node->_parent ) { plist_type type = plist_get_node_type(node->_parent); - if (PLIST_ARRAY ==type || PLIST_DICT == type ) + if (PLIST_ARRAY == type || PLIST_DICT == type) { Structure* s = static_cast<Structure*>(node->_parent); s->Remove(node); @@ -117,8 +117,27 @@ Structure* Structure::FromBin(const std::vector<char>& bin) plist_from_bin(&bin[0], bin.size(), &root); return ImportStruct(root); +} + +Structure* Structure::FromBin(const char* bin, uint64_t size) +{ + plist_t root = NULL; + plist_from_bin(bin, size, &root); + return ImportStruct(root); } -} // namespace PList +Structure* Structure::FromMemory(const std::vector<char>& buf, plist_format_t *format) +{ + return Structure::FromMemory(&buf[0], buf.size(), format); +} +Structure* Structure::FromMemory(const char* buf, uint64_t size, plist_format_t *format) +{ + plist_t root = NULL; + plist_from_memory(buf, size, &root, format); + return ImportStruct(root); +} + + +} // namespace PList diff --git a/src/bplist.c b/src/bplist.c index 93f0bc6..85e55e2 100644 --- a/src/bplist.c +++ b/src/bplist.c @@ -87,6 +87,28 @@ union plist_uint_ptr uint64_t *u64ptr; }; +#ifdef _MSC_VER +uint64_t get_unaligned_64(uint64_t *ptr) +{ + uint64_t temp; + memcpy(&temp, ptr, sizeof(temp)); + return temp; +} + +uint32_t get_unaligned_32(uint32_t *ptr) +{ + uint32_t temp; + memcpy(&temp, ptr, sizeof(temp)); + return temp; +} + +uint16_t get_unaligned_16(uint16_t *ptr) +{ + uint16_t temp; + memcpy(&temp, ptr, sizeof(temp)); + return temp; +} +#else #define get_unaligned(ptr) \ ({ \ struct __attribute__((packed)) { \ @@ -94,6 +116,7 @@ union plist_uint_ptr } *__p = (void *) (ptr); \ __p->__v; \ }) +#endif #ifndef bswap16 @@ -148,17 +171,31 @@ union plist_uint_ptr #define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3)) #endif +#ifdef _MSC_VER +static uint64_t UINT_TO_HOST(const void* x, uint8_t n) +{ + union plist_uint_ptr __up; + __up.src = (n > 8) ? (const char*)x + (n - 8) : (const char*)x; + return (n >= 8 ? be64toh( get_unaligned_64(__up.u64ptr) ) : + (n == 4 ? be32toh( get_unaligned_32(__up.u32ptr) ) : + (n == 2 ? be16toh( get_unaligned_16(__up.u16ptr) ) : + (n == 1 ? *__up.u8ptr : + beNtoh( get_unaligned_64(__up.u64ptr), n) + )))); +} +#else #define UINT_TO_HOST(x, n) \ ({ \ union plist_uint_ptr __up; \ - __up.src = ((n) > 8) ? (x) + ((n) - 8) : (x); \ + __up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \ ((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \ ((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \ ((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \ - ((n) == 1 ? *__up.u8ptr : \ + ((n) == 1 ? *__up.u8ptr : \ beNtoh( get_unaligned(__up.u64ptr), n) \ )))); \ }) +#endif #define get_needed_bytes(x) \ ( ((uint64_t)(x)) < (1ULL << 8) ? 1 : \ @@ -168,15 +205,13 @@ union plist_uint_ptr #define get_real_bytes(x) ((x) == (float) (x) ? sizeof(float) : sizeof(double)) -#if (defined(__LITTLE_ENDIAN__) \ - && !defined(__FLOAT_WORD_ORDER__)) \ - || (defined(__FLOAT_WORD_ORDER__) \ - && __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define float_bswap64(x) bswap64(x) -#define float_bswap32(x) bswap32(x) -#else +#if (defined(__BIG_ENDIAN__) && !defined(__FLOAT_WORD_ORDER__)) \ + || (defined(__FLOAT_WORD_ORDER__) && __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) #define float_bswap64(x) (x) #define float_bswap32(x) (x) +#else +#define float_bswap64(x) bswap64(x) +#define float_bswap32(x) bswap32(x) #endif #ifndef __has_builtin @@ -271,19 +306,30 @@ static plist_t parse_int_node(const char **bnode, uint8_t size) static plist_t parse_real_node(const char **bnode, uint8_t size) { plist_data_t data = plist_new_plist_data(); - uint8_t buf[8]; size = 1 << size; // make length less misleading switch (size) { case sizeof(uint32_t): - *(uint32_t*)buf = float_bswap32(get_unaligned((uint32_t*)*bnode)); - data->realval = *(float *) buf; - break; + { + uint32_t ival; + memcpy(&ival, *bnode, sizeof(uint32_t)); + ival = float_bswap32(ival); + float fval; + memcpy(&fval, &ival, sizeof(float)); + data->realval = fval; + } + break; + case sizeof(uint64_t): - *(uint64_t*)buf = float_bswap64(get_unaligned((uint64_t*)*bnode)); - data->realval = *(double *) buf; + { + uint64_t ival; + memcpy(&ival, *bnode, sizeof(uint64_t)); + ival = float_bswap64(ival); + memcpy(&data->realval, &ival, sizeof(double)); break; + } + default: free(data); PLIST_BIN_ERR("%s: Invalid byte size for real node\n", __func__); @@ -343,7 +389,7 @@ static char *plist_utf16be_to_utf8(uint16_t *unistr, long len, long *items_read, } while (i < len) { - wc = be16toh(get_unaligned(unistr + i)); + wc = UINT_TO_HOST(unistr + i, sizeof(wc)); i++; if (wc >= 0xD800 && wc <= 0xDBFF) { if (!read_lead_surrogate) { diff --git a/src/jplist.c b/src/jplist.c index 782d2b3..1c7a932 100644 --- a/src/jplist.c +++ b/src/jplist.c @@ -72,8 +72,10 @@ void plist_json_set_debug(int debug) } #ifndef HAVE_STRNDUP +#ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" +#endif static char* strndup(const char* str, size_t len) { char *newstr = (char *)malloc(len+1); @@ -83,8 +85,10 @@ static char* strndup(const char* str, size_t len) } return newstr; } +#ifndef _MSC_VER #pragma GCC diagnostic pop #endif +#endif static size_t dtostr(char *buf, size_t bufsize, double realval) { @@ -460,6 +464,8 @@ static int64_t parse_decimal(const char* str, const char* str_end, char** endp) if (str[0] == '-') { is_neg = 1; (*endp)++; + } else if (str[0] == '+') { + (*endp)++; } if (is_neg) { MAX++; @@ -522,7 +528,7 @@ static plist_t parse_primitive(const char* js, jsmntok_info_t* ti, int* index) } else { val = plist_new_uint((uint64_t)intpart); } - } else if ((*endp == '.' && endp+1 < str_end && isdigit(*(endp+1))) || ((*endp == 'e' || *endp == 'E') && endp+1 < str_end && (isdigit(*(endp+1)) || ((*(endp+1) == '-') && endp+2 < str_end && isdigit(*(endp+2)))))) { + } else if ((*endp == '.' && endp+1 < str_end && isdigit(*(endp+1))) || ((*endp == 'e' || *endp == 'E') && endp+1 < str_end && (isdigit(*(endp+1)) || (((*(endp+1) == '-') || (*(endp+1) == '+')) && endp+2 < str_end && isdigit(*(endp+2)))))) { /* floating point */ double dval = (double)intpart; char* fendp = endp; @@ -546,7 +552,7 @@ static plist_t parse_primitive(const char* js, jsmntok_info_t* ti, int* index) if (fendp >= str_end) { break; } - if (fendp+1 < str_end && (*fendp == 'e' || *fendp == 'E') && (isdigit(*(fendp+1)) || ((*(fendp+1) == '-') && fendp+2 < str_end && isdigit(*(fendp+2))))) { + if (fendp+1 < str_end && (*fendp == 'e' || *fendp == 'E') && (isdigit(*(fendp+1)) || (((*(fendp+1) == '-') || (*(fendp+1) == '+')) && fendp+2 < str_end && isdigit(*(fendp+2))))) { int64_t exp = parse_decimal(fendp+1, str_end, &fendp); dval = dval * pow(10, (double)exp); } else { diff --git a/src/oplist.c b/src/oplist.c index 6ab6603..33896f9 100644 --- a/src/oplist.c +++ b/src/oplist.c @@ -71,8 +71,10 @@ void plist_ostep_set_debug(int debug) } #ifndef HAVE_STRNDUP +#ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" +#endif static char* strndup(const char* str, size_t len) { char *newstr = (char *)malloc(len+1); @@ -82,8 +84,10 @@ static char* strndup(const char* str, size_t len) } return newstr; } +#ifndef _MSC_VER #pragma GCC diagnostic pop #endif +#endif static size_t dtostr(char *buf, size_t bufsize, double realval) { diff --git a/src/plist.c b/src/plist.c index d1b0b5a..fe98f34 100644 --- a/src/plist.c +++ b/src/plist.c @@ -39,8 +39,6 @@ #ifdef WIN32 #include <windows.h> -#else -#include <pthread.h> #endif #include <node.h> @@ -48,6 +46,8 @@ #include <hashtable.h> #include <ptrarray.h> +#define MAC_EPOCH 978307200 + #ifdef _MSC_VER typedef SSIZE_T ssize_t; #endif @@ -59,15 +59,6 @@ static int plist_debug = 0; #define PLIST_ERR(...) #endif -extern void plist_xml_init(void); -extern void plist_xml_deinit(void); -extern void plist_bin_init(void); -extern void plist_bin_deinit(void); -extern void plist_json_init(void); -extern void plist_json_deinit(void); -extern void plist_ostep_init(void); -extern void plist_ostep_deinit(void); - #ifndef bswap16 #define bswap16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) #endif @@ -91,36 +82,64 @@ extern void plist_ostep_deinit(void); #endif #ifndef le16toh -#ifdef __LITTLE_ENDIAN__ -#define le16toh(x) (x) -#else +#ifdef __BIG_ENDIAN__ #define le16toh(x) bswap16(x) +#else +#define le16toh(x) (x) #endif #endif #ifndef le32toh -#ifdef __LITTLE_ENDIAN__ -#define le32toh(x) (x) -#else +#ifdef __BIG_ENDIAN__ #define le32toh(x) bswap32(x) +#else +#define le32toh(x) (x) #endif #endif #ifndef le64toh -#ifdef __LITTLE_ENDIAN__ -#define le64toh(x) (x) -#else +#ifdef __BIG_ENDIAN__ #define le64toh(x) bswap64(x) +#else +#define le64toh(x) (x) #endif #endif -static void internal_plist_init(void) -{ - plist_bin_init(); - plist_xml_init(); - plist_json_init(); - plist_ostep_init(); -} +// Reference: https://stackoverflow.com/a/2390626/1806760 +// Initializer/finalizer sample for MSVC and GCC/Clang. +// 2010-2016 Joe Lowe. Released into the public domain. + +#ifdef __cplusplus + #define INITIALIZER(f) \ + static void f(void); \ + struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \ + static void f(void) +#elif defined(_MSC_VER) + #pragma section(".CRT$XCU",read) + #define INITIALIZER2_(f,p) \ + static void f(void); \ + __declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \ + __pragma(comment(linker,"/include:" p #f "_")) \ + static void f(void) + #ifdef _WIN64 + #define INITIALIZER(f) INITIALIZER2_(f,"") + #else + #define INITIALIZER(f) INITIALIZER2_(f,"_") + #endif +#else + #define INITIALIZER(f) \ + static void f(void) __attribute__((__constructor__)); \ + static void f(void) +#endif + +extern void plist_xml_init(void); +extern void plist_xml_deinit(void); +extern void plist_bin_init(void); +extern void plist_bin_deinit(void); +extern void plist_json_init(void); +extern void plist_json_deinit(void); +extern void plist_ostep_init(void); +extern void plist_ostep_deinit(void); static void internal_plist_deinit(void) { @@ -130,66 +149,14 @@ static void internal_plist_deinit(void) plist_ostep_deinit(); } -#ifdef WIN32 -typedef volatile struct { - LONG lock; - int state; -} thread_once_t; - -static thread_once_t init_once = {0, 0}; -static thread_once_t deinit_once = {0, 0}; - -static void thread_once(thread_once_t *once_control, void (*init_routine)(void)) -{ - while (InterlockedExchange(&(once_control->lock), 1) != 0) { - Sleep(1); - } - if (!once_control->state) { - once_control->state = 1; - init_routine(); - } - InterlockedExchange(&(once_control->lock), 0); -} -#else -static pthread_once_t init_once = PTHREAD_ONCE_INIT; -static pthread_once_t deinit_once = PTHREAD_ONCE_INIT; -#define thread_once pthread_once -#endif - -#ifndef HAVE_ATTRIBUTE_CONSTRUCTOR - #if defined(__llvm__) || defined(__GNUC__) - #define HAVE_ATTRIBUTE_CONSTRUCTOR - #endif -#endif - -#ifdef HAVE_ATTRIBUTE_CONSTRUCTOR -static void __attribute__((constructor)) libplist_initialize(void) -{ - thread_once(&init_once, internal_plist_init); -} - -static void __attribute__((destructor)) libplist_deinitialize(void) -{ - thread_once(&deinit_once, internal_plist_deinit); -} -#elif defined(WIN32) -BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) +INITIALIZER(internal_plist_init) { - switch (dwReason) { - case DLL_PROCESS_ATTACH: - thread_once(&init_once, internal_plist_init); - break; - case DLL_PROCESS_DETACH: - thread_once(&deinit_once, internal_plist_deinit); - break; - default: - break; - } - return 1; + plist_bin_init(); + plist_xml_init(); + plist_json_init(); + plist_ostep_init(); + atexit(internal_plist_deinit); } -#else -#warning No compiler support for constructor/destructor attributes, some features might not be available. -#endif #ifndef HAVE_MEMMEM // see https://sourceware.org/legacy-ml/libc-alpha/2007-12/msg00000.html @@ -391,7 +358,7 @@ plist_data_t plist_get_data(plist_t node) plist_data_t plist_new_plist_data(void) { - plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1); + plist_data_t data = (plist_data_t) calloc(1, sizeof(struct plist_data_s)); return data; } @@ -544,7 +511,7 @@ plist_t plist_new_real(double val) return plist_new_node(data); } -plist_t plist_new_data(const uint8_t *val, uint64_t length) +plist_t plist_new_data(const char *val, uint64_t length) { plist_data_t data = plist_new_plist_data(); data->type = PLIST_DATA; @@ -563,6 +530,15 @@ plist_t plist_new_date(int32_t sec, int32_t usec) return plist_new_node(data); } +plist_t plist_new_unix_date(int64_t sec) +{ + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_DATE; + data->realval = (double)sec - MAC_EPOCH; + data->length = sizeof(double); + return plist_new_node(data); +} + plist_t plist_new_null(void) { plist_data_t data = plist_new_plist_data(); @@ -1385,7 +1361,7 @@ void plist_get_real_val(plist_t node, double *val) assert(length == sizeof(double)); } -void plist_get_data_val(plist_t node, uint8_t **val, uint64_t * length) +void plist_get_data_val(plist_t node, char **val, uint64_t * length) { if (!node || !val || !length) return; @@ -1395,7 +1371,7 @@ void plist_get_data_val(plist_t node, uint8_t **val, uint64_t * length) plist_get_type_and_value(node, &type, (void *) val, length); } -const uint8_t* plist_get_data_ptr(plist_t node, uint64_t* length) +const char* plist_get_data_ptr(plist_t node, uint64_t* length) { if (!node || !length) return NULL; @@ -1404,7 +1380,7 @@ const uint8_t* plist_get_data_ptr(plist_t node, uint64_t* length) return NULL; plist_data_t data = plist_get_data(node); *length = data->length; - return data->buff; + return (const char*)data->buff; } void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec) @@ -1427,6 +1403,20 @@ void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec) } } +void plist_get_unix_date_val(plist_t node, int64_t *sec) +{ + if (!node || !sec) + return; + plist_type type = plist_get_node_type(node); + uint64_t length = 0; + double val = 0; + if (PLIST_DATE != type) + return; + plist_get_type_and_value(node, &type, (void *) &val, &length); + assert(length == sizeof(double)); + *sec = (int64_t)val + MAC_EPOCH; +} + int plist_data_compare(const void *a, const void *b) { plist_data_t val_a = NULL; @@ -1575,7 +1565,7 @@ void plist_set_real_val(plist_t node, double val) plist_set_element_val(node, PLIST_REAL, &val, sizeof(double)); } -void plist_set_data_val(plist_t node, const uint8_t *val, uint64_t length) +void plist_set_data_val(plist_t node, const char *val, uint64_t length) { plist_set_element_val(node, PLIST_DATA, val, length); } @@ -1583,7 +1573,13 @@ void plist_set_data_val(plist_t node, const uint8_t *val, uint64_t length) void plist_set_date_val(plist_t node, int32_t sec, int32_t usec) { double val = (double)sec + (double)usec / 1000000; - plist_set_element_val(node, PLIST_DATE, &val, sizeof(struct timeval)); + plist_set_element_val(node, PLIST_DATE, &val, sizeof(double)); +} + +void plist_set_unix_date_val(plist_t node, int64_t sec) +{ + double val = (double)(sec - MAC_EPOCH); + plist_set_element_val(node, PLIST_DATE, &val, sizeof(double)); } int plist_bool_val_is_true(plist_t boolnode) @@ -1705,9 +1701,12 @@ int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec) if (!PLIST_IS_DATE(datenode)) { return -1; } - int32_t sec = 0; - int32_t usec = 0; - plist_get_date_val(datenode, &sec, &usec); + plist_data_t data = plist_get_data(datenode); + assert(data->length == sizeof(double)); + double val = data->realval; + int32_t sec = (int32_t)val; + val = fabs((val - (int64_t)val) * 1000000); + int32_t usec = (int32_t)val; uint64_t dateval = ((int64_t)sec << 32) | usec; uint64_t cmpval = ((int64_t)cmpsec << 32) | cmpusec; if (dateval == cmpval) { @@ -1721,6 +1720,24 @@ int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec) return 1; } +int plist_unix_date_val_compare(plist_t datenode, int64_t cmpval) +{ + if (!PLIST_IS_DATE(datenode)) { + return -1; + } + int64_t dateval = 0; + plist_get_unix_date_val(datenode, &dateval); + if (dateval == cmpval) { + return 0; + } + + if (dateval < cmpval) { + return -1; + } + + return 1; +} + int plist_string_val_compare(plist_t strnode, const char* cmpval) { if (!PLIST_IS_STRING(strnode)) { @@ -1843,6 +1860,9 @@ void plist_sort(plist_t plist) } else if (PLIST_IS_DICT(plist)) { node_t node = (node_t)plist; node_t ch; + if (!node_first_child(node)) { + return; + } for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { ch = node_next_sibling(ch); plist_sort((plist_t)ch); |
