bstring.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /**
  2. * @file bstring.h
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * This file is part of BadVPN.
  8. *
  9. * BadVPN is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * BadVPN is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. */
  22. #ifndef BADVPN_BSTRING_H
  23. #define BADVPN_BSTRING_H
  24. #include <misc/debug.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #define BSTRING_TYPE_STATIC 5
  28. #define BSTRING_TYPE_DYNAMIC 7
  29. #define BSTRING_TYPE_EXTERNAL 11
  30. #define BSTRING_STATIC_SIZE 23
  31. #define BSTRING_STATIC_MAX (BSTRING_STATIC_SIZE - 1)
  32. typedef struct {
  33. union {
  34. struct {
  35. char type;
  36. char static_string[BSTRING_STATIC_SIZE];
  37. } us;
  38. struct {
  39. char type;
  40. char *dynamic_string;
  41. } ud;
  42. struct {
  43. char type;
  44. const char *external_string;
  45. } ue;
  46. } u;
  47. } BString;
  48. static void BString__assert (BString *o)
  49. {
  50. switch (o->u.us.type) {
  51. case BSTRING_TYPE_STATIC:
  52. case BSTRING_TYPE_DYNAMIC:
  53. case BSTRING_TYPE_EXTERNAL:
  54. return;
  55. }
  56. ASSERT(0);
  57. }
  58. static int BString_Init (BString *o, const char *str)
  59. {
  60. if (strlen(str) <= BSTRING_STATIC_MAX) {
  61. strcpy(o->u.us.static_string, str);
  62. o->u.us.type = BSTRING_TYPE_STATIC;
  63. } else {
  64. if (!(o->u.ud.dynamic_string = malloc(strlen(str) + 1))) {
  65. return 0;
  66. }
  67. strcpy(o->u.ud.dynamic_string, str);
  68. o->u.ud.type = BSTRING_TYPE_DYNAMIC;
  69. }
  70. BString__assert(o);
  71. return 1;
  72. }
  73. static void BString_InitStatic (BString *o, const char *str)
  74. {
  75. ASSERT(strlen(str) <= BSTRING_STATIC_MAX)
  76. strcpy(o->u.us.static_string, str);
  77. o->u.us.type = BSTRING_TYPE_STATIC;
  78. BString__assert(o);
  79. }
  80. static void BString_InitExternal (BString *o, const char *str)
  81. {
  82. o->u.ue.external_string = str;
  83. o->u.ue.type = BSTRING_TYPE_EXTERNAL;
  84. BString__assert(o);
  85. }
  86. static void BString_InitAllocated (BString *o, char *str)
  87. {
  88. o->u.ud.dynamic_string = str;
  89. o->u.ud.type = BSTRING_TYPE_DYNAMIC;
  90. BString__assert(o);
  91. }
  92. static void BString_Free (BString *o)
  93. {
  94. BString__assert(o);
  95. if (o->u.ud.type == BSTRING_TYPE_DYNAMIC) {
  96. free(o->u.ud.dynamic_string);
  97. }
  98. }
  99. static const char * BString_Get (BString *o)
  100. {
  101. BString__assert(o);
  102. switch (o->u.us.type) {
  103. case BSTRING_TYPE_STATIC: return o->u.us.static_string;
  104. case BSTRING_TYPE_DYNAMIC: return o->u.ud.dynamic_string;
  105. case BSTRING_TYPE_EXTERNAL: return o->u.ue.external_string;
  106. }
  107. ASSERT(0);
  108. return NULL;
  109. }
  110. #endif