Mercurial > pidgin
comparison src/util.c @ 6982:083d1e4a9c78
[gaim-migrate @ 7538]
This is Mr. Holland's Opus. And by Mr. Holland I mean Robot101. He
rewrote the coreish IM image support so that the binary data gets
ripped out in the prpl and put in an imgstore instead of just being
passed in the same huge as char string as the actual message. This
is good because it's prpl agnostic, or something. It also means
we don't have a silly length of "-1" with pretty much every send or
receive IM function.
It should be crash free, bug free, and memleak free, but additional
testing is always a good thing.
If you like good stuff then you'll love this patch. But don't take
my word for it--ba dun dunt!
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sat, 27 Sep 2003 19:17:21 +0000 |
parents | dd0eecfbe413 |
children | 9d038cc7e825 |
comparison
equal
deleted
inserted
replaced
6981:abd3c684da31 | 6982:083d1e4a9c78 |
---|---|
938 g_strfreev(split); | 938 g_strfreev(split); |
939 | 939 |
940 return ret; | 940 return ret; |
941 } | 941 } |
942 | 942 |
943 const char *gaim_strcasestr(const char *haystack, const char *needle) { | |
944 size_t hlen, nlen; | |
945 const char *tmp, *ret; | |
946 | |
947 g_return_val_if_fail(haystack != NULL, NULL); | |
948 g_return_val_if_fail(needle != NULL, NULL); | |
949 | |
950 hlen = strlen(haystack); | |
951 nlen = strlen(needle); | |
952 tmp = haystack, | |
953 ret = NULL; | |
954 | |
955 g_return_val_if_fail(hlen > 0, NULL); | |
956 g_return_val_if_fail(nlen > 0, NULL); | |
957 | |
958 while (*tmp && !ret) { | |
959 if (!g_ascii_strncasecmp(needle, tmp, nlen)) | |
960 ret = tmp; | |
961 else | |
962 tmp++; | |
963 } | |
964 | |
965 return ret; | |
966 } | |
967 | |
943 char *gaim_get_size_string(size_t size) | 968 char *gaim_get_size_string(size_t size) |
944 { | 969 { |
945 static const char *size_str[4] = { "bytes", "KB", "MB", "GB" }; | 970 static const char *size_str[4] = { "bytes", "KB", "MB", "GB" }; |
946 float size_mag; | 971 float size_mag; |
947 int size_index = 0; | 972 int size_index = 0; |
961 } | 986 } |
962 | 987 |
963 return g_strdup_printf("%.2f %s", size_mag, size_str[size_index]); | 988 return g_strdup_printf("%.2f %s", size_mag, size_str[size_index]); |
964 } | 989 } |
965 } | 990 } |
991 | |
992 gboolean gaim_markup_find_tag(const char *needle, const char *haystack, const char **start, const char **end, GData **attributes) { | |
993 GData *attribs; | |
994 const char *cur = haystack; | |
995 char *name = NULL; | |
996 gboolean found = FALSE; | |
997 gboolean in_tag = FALSE; | |
998 gboolean in_attr = FALSE; | |
999 gboolean in_quotes = FALSE; | |
1000 size_t needlelen = strlen(needle); | |
1001 | |
1002 g_datalist_init(&attribs); | |
1003 | |
1004 while (*cur && !found) { | |
1005 if (in_tag) { | |
1006 if (in_quotes) { | |
1007 const char *close = cur; | |
1008 | |
1009 while (*close && *close != '"') | |
1010 close++; | |
1011 | |
1012 /* if we got the close quote, store the value and carry on from * | |
1013 * after it. if we ran to the end of the string, point to the NULL * | |
1014 * and we're outta here */ | |
1015 if (*close) { | |
1016 /* only store a value if we have an attribute name */ | |
1017 if (name) { | |
1018 size_t len = close - cur; | |
1019 char *val = g_strndup(cur, len); | |
1020 | |
1021 g_datalist_set_data_full(&attribs, name, val, g_free); | |
1022 g_free(name); | |
1023 name = NULL; | |
1024 } | |
1025 | |
1026 in_quotes = FALSE; | |
1027 cur = close + 1; | |
1028 } else { | |
1029 cur = close; | |
1030 } | |
1031 } else if (in_attr) { | |
1032 const char *close = cur; | |
1033 | |
1034 while (*close && *close != '>' && *close != '"' && *close != ' ' && *close != '=') | |
1035 close++; | |
1036 | |
1037 /* if we got the equals, store the name of the attribute. if we got | |
1038 * the quote, save the attribute and go straight to quote mode. | |
1039 * otherwise the tag closed or we reached the end of the string, | |
1040 * so we can get outta here */ | |
1041 switch (*close) { | |
1042 case '"': | |
1043 in_quotes = TRUE; | |
1044 case '=': | |
1045 { | |
1046 size_t len = close - cur; | |
1047 | |
1048 /* don't store a blank attribute name */ | |
1049 if (len) { | |
1050 if (name) | |
1051 g_free(name); | |
1052 name = g_ascii_strdown(cur, len); | |
1053 } | |
1054 | |
1055 in_attr = FALSE; | |
1056 cur = close + 1; | |
1057 break; | |
1058 } | |
1059 case ' ': | |
1060 case '>': | |
1061 in_attr = FALSE; | |
1062 default: | |
1063 cur = close; | |
1064 break; | |
1065 } | |
1066 } else { | |
1067 switch (*cur) { | |
1068 case ' ': | |
1069 /* swallow extra spaces inside tag */ | |
1070 while (*cur && *cur == ' ') cur++; | |
1071 in_attr = TRUE; | |
1072 break; | |
1073 case '>': | |
1074 found = TRUE; | |
1075 *end = cur; | |
1076 break; | |
1077 case '"': | |
1078 in_quotes = TRUE; | |
1079 default: | |
1080 cur++; | |
1081 break; | |
1082 } | |
1083 } | |
1084 } else { | |
1085 /* if we hit a < followed by the name of our tag... */ | |
1086 if (*cur == '<' && !g_ascii_strncasecmp(cur + 1, needle, needlelen)) { | |
1087 *start = cur; | |
1088 cur = cur + needlelen + 1; | |
1089 | |
1090 /* if we're pointing at a space or a >, we found the right tag. if * | |
1091 * we're not, we've found a longer tag, so we need to skip to the * | |
1092 * >, but not being distracted by >s inside quotes. */ | |
1093 if (*cur == ' ' || *cur == '>') { | |
1094 in_tag = TRUE; | |
1095 } else { | |
1096 while (*cur && *cur != '"' && *cur != '>') { | |
1097 if (*cur == '"') { | |
1098 cur++; | |
1099 while (*cur && *cur != '"') | |
1100 cur++; | |
1101 } else { | |
1102 cur++; | |
1103 } | |
1104 } | |
1105 } | |
1106 } else { | |
1107 cur++; | |
1108 } | |
1109 } | |
1110 } | |
1111 | |
1112 /* clean up any attribute name from a premature termination */ | |
1113 if (name) | |
1114 g_free(name); | |
1115 | |
1116 if (found) { | |
1117 *attributes = attribs; | |
1118 } else { | |
1119 *start = NULL; | |
1120 *end = NULL; | |
1121 *attributes = NULL; | |
1122 } | |
1123 | |
1124 return found; | |
1125 } |