static bool _prop_array_externalize(struct _prop_object_externalize_context *ctx, void *v) { prop_array_t pa = v; struct _prop_object *po; prop_object_iterator_t pi; unsigned int i; bool rv = false; _PROP_RWLOCK_RDLOCK(pa->pa_rwlock); if (pa->pa_count == 0) { _PROP_RWLOCK_UNLOCK(pa->pa_rwlock); return (_prop_object_externalize_empty_tag(ctx, "array")); } /* XXXJRT Hint "count" for the internalize step? */ if (_prop_object_externalize_start_tag(ctx, "array") == false || _prop_object_externalize_append_char(ctx, '\n') == false) goto out; pi = _prop_array_iterator_locked(pa); if (pi == NULL) goto out; ctx->poec_depth++; _PROP_ASSERT(ctx->poec_depth != 0); while ((po = _prop_array_iterator_next_object_locked(pi)) != NULL) { if ((*po->po_type->pot_extern)(ctx, po) == false) { prop_object_iterator_release(pi); goto out; } } prop_object_iterator_release(pi); ctx->poec_depth--; for (i = 0; i < ctx->poec_depth; i++) { if (_prop_object_externalize_append_char(ctx, '\t') == false) goto out; } if (_prop_object_externalize_end_tag(ctx, "array") == false) goto out; rv = true; out: _PROP_RWLOCK_UNLOCK(pa->pa_rwlock); return (rv); }
/* * _prop_object_externalize_end_tag -- * Append an XML-style end tag to the externalize buffer. */ bool _prop_object_externalize_end_tag( struct _prop_object_externalize_context *ctx, const char *tag) { if (_prop_object_externalize_append_char(ctx, '<') == false || _prop_object_externalize_append_char(ctx, '/') == false || _prop_object_externalize_append_cstring(ctx, tag) == false || _prop_object_externalize_append_char(ctx, '>') == false || _prop_object_externalize_append_char(ctx, '\n') == false) return (false); return (true); }
/* * _prop_object_externalize_append_encoded_cstring -- * Append an encoded C string to the externalize buffer. */ bool _prop_object_externalize_append_encoded_cstring( struct _prop_object_externalize_context *ctx, const char *cp) { while (*cp != '\0') { switch (*cp) { case '<': if (_prop_object_externalize_append_cstring(ctx, "<") == false) return (false); break; case '>': if (_prop_object_externalize_append_cstring(ctx, ">") == false) return (false); break; case '&': if (_prop_object_externalize_append_cstring(ctx, "&") == false) return (false); break; default: if (_prop_object_externalize_append_char(ctx, (unsigned char) *cp) == false) return (false); break; } cp++; } return (true); }
/* * _prop_object_externalize_start_tag -- * Append an XML-style start tag to the externalize buffer. */ bool _prop_object_externalize_start_tag( struct _prop_object_externalize_context *ctx, const char *tag) { unsigned int i; for (i = 0; i < ctx->poec_depth; i++) { if (_prop_object_externalize_append_char(ctx, '\t') == false) return (false); } if (_prop_object_externalize_append_char(ctx, '<') == false || _prop_object_externalize_append_cstring(ctx, tag) == false || _prop_object_externalize_append_char(ctx, '>') == false) return (false); return (true); }
/* * _prop_object_externalize_footer -- * Append the standard XML footer to the externalize buffer. This * also NUL-terminates the buffer. */ bool _prop_object_externalize_footer(struct _prop_object_externalize_context *ctx) { if (_prop_object_externalize_end_tag(ctx, "plist") == false || _prop_object_externalize_append_char(ctx, '\0') == false) return (false); return (true); }
/* * _prop_object_externalize_append_cstring -- * Append a C string to the externalize buffer. */ bool _prop_object_externalize_append_cstring( struct _prop_object_externalize_context *ctx, const char *cp) { while (*cp != '\0') { if (_prop_object_externalize_append_char(ctx, (unsigned char) *cp) == false) return (false); cp++; } return (true); }
/* * _prop_object_externalize_header -- * Append the standard XML header to the externalize buffer. */ bool _prop_object_externalize_header(struct _prop_object_externalize_context *ctx) { static const char _plist_xml_header[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"; if (_prop_object_externalize_append_cstring(ctx, _plist_xml_header) == false || _prop_object_externalize_start_tag(ctx, "plist version=\"1.0\"") == false || _prop_object_externalize_append_char(ctx, '\n') == false) return (false); return (true); }