00001
00002 #include <microfeed/microfeedmisc.h>
00003
00004 #include <stdio.h>
00005 #include <string.h>
00006 #include <stdarg.h>
00007 #include <stdlib.h>
00008
00009 struct _MicrofeedWeakReference {
00010 void* referenced;
00011 unsigned int reference_count;
00012 };
00013
00014 void* microfeed_memory_allocate_bytes(size_t size) {
00015 void* pointer;
00016
00017 if (!(pointer = malloc(size))) {
00018 fprintf(stderr, "ERROR: Failed to allocate memory.\n");
00019
00020 exit(126);
00021 }
00022 memset(pointer, 0, size);
00023
00024 return pointer;
00025 }
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 void microfeed_memory_free(void* pointer) {
00068 free(pointer);
00069 }
00070
00071 char* microfeed_util_string_concatenate(const char* s, ...) {
00072 char* result;
00073 size_t size;
00074 size_t length;
00075 va_list argp;
00076
00077 size = strlen(s);
00078 length = size + 1;
00079 result = (char*)malloc(length);
00080 memcpy(result, s, length);
00081 va_start(argp, s);
00082 while ((s = va_arg(argp, const char*))) {
00083 length = strlen(s);
00084 result = realloc(result, size + length + 1);
00085 memcpy(result + size, s, length + 1);
00086 size += length;
00087 }
00088 va_end(argp);
00089
00090 return result;
00091 }
00092
00093 static int hexadecimal_char_to_int(char c) {
00094 int retvalue = -1;
00095
00096 if (c >= '0' && c <= '9') {
00097 retvalue = c - '0';
00098 } else if (c >= 'a' && c <= 'f') {
00099 retvalue = c - 'a' + 10;
00100 } else if (c >= 'A' && c <= 'F') {
00101 retvalue = c - 'A' + 10;
00102 }
00103
00104 return retvalue;
00105 }
00106
00107 char* microfeed_util_string_unescape_percent_encoding(const char* s) {
00108 char* result;
00109 const char* from;
00110 char* to;
00111 int tempvalue;
00112 int value;
00113
00114 result = (char*)malloc(strlen(s) + 1);
00115 for (to = result, from = s; *from; from++, to++) {
00116 if (*from == '%') {
00117 if ((tempvalue = hexadecimal_char_to_int(from[1])) == -1) {
00118 free(result);
00119 result = NULL;
00120 break;
00121 }
00122 if ((value = hexadecimal_char_to_int(from[2])) == -1) {
00123 free(result);
00124 result = NULL;
00125 break;
00126 }
00127 value |= tempvalue << 4;
00128 if ((value >= 'a' && value <= 'z') || (value >= 'A' && value <= 'Z') || (value >= '0' && value <= '9') ||
00129 value == '-' || value == '_' || value == '.' || value == '~') {
00130 *to = value;
00131 } else {
00132 *to++ = *from++;
00133 *to++ = *from++;
00134 *to = *from;
00135 }
00136 } else {
00137 *to = *from;
00138 }
00139 }
00140 if (result) {
00141 *to++ = 0;
00142 result = (char*)realloc(result, result - to);
00143 }
00144
00145 return result;
00146 }
00147
00148 MicrofeedWeakReference* microfeed_weak_reference_new(void* referenced, MicrofeedWeakReference* existing_weak_reference) {
00149 if (existing_weak_reference) {
00150 existing_weak_reference->reference_count++;
00151 } else {
00152 existing_weak_reference = microfeed_memory_allocate(MicrofeedWeakReference);
00153 existing_weak_reference->referenced = referenced;
00154 existing_weak_reference->reference_count = 1;
00155 }
00156
00157 return existing_weak_reference;
00158 }
00159
00160 void microfeed_weak_reference_free(MicrofeedWeakReference* weak_reference) {
00161 weak_reference->reference_count--;
00162 if (weak_reference->reference_count == 0) {
00163 weak_reference->referenced = NULL;
00164 microfeed_memory_free(weak_reference);
00165 }
00166 }
00167
00168 void* microfeed_weak_reference_get_impl(MicrofeedWeakReference* weak_reference) {
00169
00170 return weak_reference->referenced;
00171 }
00172
00173 void microfeed_weak_reference_invalidate(MicrofeedWeakReference* weak_reference) {
00174 if (weak_reference) {
00175 weak_reference->referenced = NULL;
00176 }
00177 }
00178