Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
4.0 KiB
126 lines
4.0 KiB
|
|
#undef NDEBUG /* ensure tests always assert. */ |
|
#include "upb_string.h" |
|
|
|
char static_str[] = "Static string."; |
|
upb_string static_upbstr = UPB_STATIC_STRING(static_str); |
|
|
|
static void test_static() { |
|
// Static string is initialized appropriately. |
|
assert(upb_streql(&static_upbstr, UPB_STRLIT("Static string."))); |
|
|
|
// Taking a ref on a static string returns the same string, and repeated |
|
// refs don't get the string in a confused state. |
|
assert(upb_string_getref(&static_upbstr) == &static_upbstr); |
|
assert(upb_string_getref(&static_upbstr) == &static_upbstr); |
|
assert(upb_string_getref(&static_upbstr) == &static_upbstr); |
|
|
|
// Unreffing a static string does nothing (is not harmful). |
|
upb_string_unref(&static_upbstr); |
|
upb_string_unref(&static_upbstr); |
|
upb_string_unref(&static_upbstr); |
|
upb_string_unref(&static_upbstr); |
|
upb_string_unref(&static_upbstr); |
|
|
|
// Recycling a static string returns a new string (that can be modified). |
|
upb_string *str = &static_upbstr; |
|
upb_string_recycle(&str); |
|
assert(str != &static_upbstr); |
|
|
|
upb_string_unref(str); |
|
} |
|
|
|
static void test_dynamic() { |
|
upb_string *str = upb_string_new(); |
|
assert(str != NULL); |
|
upb_string_unref(str); |
|
|
|
// Can also create a string by recycle(NULL). |
|
str = NULL; |
|
upb_string_recycle(&str); |
|
assert(str != NULL); |
|
|
|
// Take a ref and recycle; should create a new string and release a ref |
|
// on the old one. |
|
upb_string *strcp = upb_string_getref(str); |
|
assert(strcp == str); |
|
assert(upb_atomic_read(&str->refcount) == 2); |
|
upb_string_recycle(&str); |
|
assert(strcp != str); |
|
assert(upb_atomic_read(&str->refcount) == 1); |
|
assert(upb_atomic_read(&strcp->refcount) == 1); |
|
upb_string_unref(strcp); |
|
|
|
upb_strcpyc(str, static_str); |
|
assert(upb_string_len(str) == (sizeof(static_str) - 1)); |
|
const char *robuf = upb_string_getrobuf(str); |
|
assert(robuf != NULL); |
|
assert(upb_streqlc(str, static_str)); |
|
upb_string_endread(str); |
|
|
|
upb_string *str2 = str; |
|
upb_string_recycle(&str2); |
|
// No other referents, so should return the same string. |
|
assert(str2 == str); |
|
|
|
// Write a shorter string, the same memory should be reused. |
|
upb_strcpyc(str, "XX"); |
|
const char *robuf2 = upb_string_getrobuf(str); |
|
assert(robuf2 == robuf); |
|
assert(upb_streqlc(str, "XX")); |
|
assert(upb_streql(str, UPB_STRLIT("XX"))); |
|
|
|
// Make string alias part of another string. |
|
str2 = upb_strdupc("WXYZ"); |
|
upb_string_recycle(&str); |
|
upb_string_substr(str, str2, 1, 2); |
|
assert(upb_string_len(str) == 2); |
|
assert(upb_string_len(str2) == 4); |
|
// The two string should be aliasing the same data. |
|
const char *robuf3 = upb_string_getrobuf(str); |
|
const char *robuf4 = upb_string_getrobuf(str2); |
|
assert(robuf3 == robuf4 + 1); |
|
// The aliased string should have an extra ref. |
|
assert(upb_atomic_read(&str2->refcount) == 2); |
|
|
|
// Recycling str should eliminate the extra ref. |
|
upb_string_recycle(&str); |
|
assert(upb_atomic_read(&str2->refcount) == 1); |
|
|
|
// Resetting str should reuse its old data. |
|
upb_strcpyc(str, "XX"); |
|
const char *robuf5 = upb_string_getrobuf(str); |
|
assert(robuf5 == robuf); |
|
|
|
// Resetting str to something very long should require new data to be |
|
// allocated. |
|
upb_string_recycle(&str); |
|
const char longstring[] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; |
|
upb_strcpyc(str, longstring); |
|
const char *robuf6 = upb_string_getrobuf(str); |
|
assert(robuf6 != robuf); |
|
assert(upb_streqlc(str, longstring)); |
|
|
|
// Test printf. |
|
upb_string_recycle(&str); |
|
upb_string_printf(str, "Number: %d, String: %s", 5, "YO!"); |
|
assert(upb_streqlc(str, "Number: 5, String: YO!")); |
|
|
|
// Test asprintf |
|
upb_string *str3 = upb_string_asprintf("Yo %s: " UPB_STRFMT "\n", |
|
"Josh", UPB_STRARG(str)); |
|
const char expected[] = "Yo Josh: Number: 5, String: YO!\n"; |
|
assert(upb_streqlc(str3, expected)); |
|
|
|
upb_string_unref(str); |
|
upb_string_unref(str2); |
|
upb_string_unref(str3); |
|
|
|
// Unref of NULL is harmless. |
|
upb_string_unref(NULL); |
|
} |
|
|
|
int main() { |
|
test_static(); |
|
test_dynamic(); |
|
}
|
|
|