Advertisement
Guest User

coolstory

a guest
Nov 22nd, 2015
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.74 KB | None | 0 0
  1. /*
  2.  * Dynamic strings implementation
  3.  * Smagin Maksim 2015
  4.  */
  5.  
  6. #include <stdint.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <memory.h>
  13.  
  14. // #include "dstring.h" //Я ламерок и не умею в хеадеронли - моё место на помойке
  15. // я посто спрятал структуру в dstring.c чтобы не дать туда явный доступ
  16. ////в 2015, если у тебя нет хеадеронли - твоё и твоей либе место на помойке. Особенно, если у тебя доступ к полям через методы. В крестах это делается подефолту - подефолту инлайн в методах с телом.
  17.  
  18.  
  19. #define dstr_malloc malloc //я ламерок и не умею в функции - моё место на помойке
  20. #define dstr_realloc realloc//я ламерок и не умею в функции - моё место на помойке
  21. #define dstr_free free//я ламерок и не умею в функции - моё место на помойке
  22. // *** я думал о том что бы сделать их функциями и я знал, что не буду писать аллокаторы и точно буду буду использовать malloc и компанию.
  23. // *** по этому для меня сейчас актуален и стандартный алокатор
  24.  
  25. //.. тут дело не в написании аллокатора, а в:
  26. // void * dstr_malloc(size_t n) {return malloc(n);}
  27. // ну и да - тебе не надо писать маллок - тебе надо написать примитивную обёртку над mmap()
  28.  
  29. struct dstring {
  30.   char * data;//терминальная лс"ная нулина.
  31.   // *** а вчем разниза если написать data[0] ?
  32.   //.. В том, что будет 1 маллок, а не 2.
  33.   size_t length;
  34.   size_t capacity;//я у мамы ламерок - увидел что-то у крестов и своими 3-мя извилинами попытался повторить.
  35.   // *** по моему это логично знать сколько памяти занято и сколько есть свободной.
  36.   // *** еще раз скажу что я ничего у кестов не смотрел)
  37.   //.. в чём смысл? Попытка оптимизировать кол-во реаллокаций?  mreamap() в realloc() это сделает за тебя. Тут нет никаких копирований и прочего.
  38.   //.. Тем более юзать убогий malloc() тебе ничего не мешало, значит к оптимизации твой код не имеет никакого отношения. А уж про днище в toupper я и молчу.
  39. };//я ламерок и не умею в тайпдеф и структуры - моё место на помойке
  40.  // *** ну это ты уже засунул хедер сюда. они были в разных файлах, так что верхний комент - это бред.
  41. //.. Нет, всё в моём коммента правильно - нахрен вообще нужно struct dstring, если у тебя оно неиспользуется?
  42.  
  43. typedef struct dstring dstring_t;
  44.  
  45.  
  46. typedef struct {
  47.   uint64_t len, capacity;
  48.   char data[0];
  49. } string_t;
  50.  
  51. typedef string_t * string_ptr_t;
  52. string_ptr_t string_alloc(uint64_t capacity) {
  53.   return memcpy(malloc(capacity + sizeof(string_t)), &(string_t){0, capacity}, sizeof(string_t));
  54. }
  55.  
  56. char * get_data(string_ptr_t str) {
  57.   return str->data;
  58. }
  59.  
  60. string_ptr_t string_realloc(string_ptr_t str, uint64_t new_capacity) {
  61.   return memcpy(realloc(str, new_capacity), &(string_t){str->len, new_capacity}, sizeof(string_t));
  62. }
  63. //а теперь сравни со своей куллстори с десятью маллоками.
  64.  
  65.  
  66. dstring_t * dstr_new(const char * init);
  67. void dstr_delete(dstring_t * str);
  68. dstring_t * dstr_set(dstring_t * str, const char * val);
  69. dstring_t * dstr_truncate(dstring_t * str, size_t len);
  70. size_t dstr_len(const dstring_t * str);
  71. void dstr_swap(dstring_t * str1, dstring_t * str2);
  72. dstring_t * dstr_insert(dstring_t * str, const char * val, size_t n);
  73. dstring_t * dstr_append(dstring_t * str, const char * val);
  74. dstring_t * dstr_appendc(dstring_t * str, char c);
  75. dstring_t * dstr_prepend(dstring_t * str, const char * val);
  76. int dstr_equal(const dstring_t * str1, const dstring_t * str2);
  77. dstring_t * dstr_toupper(dstring_t * str);
  78. dstring_t * dstr_tolower(dstring_t * str);
  79. void dstr_fprint(const dstring_t * str, FILE * file);
  80.  
  81. // *** о enum { ... }  я знаю. почему не использовал его? Ну признаю что просто хоетл написать define) согласен что надо заменить на enum
  82. #define DSTRING_CAPMARGIN 48//я ламерок и не умею в переменные - моё место на помойке
  83. #define DSTRING_DEFAULT_CAPACITY 16//я ламерок и не умею в переменные - моё место на помойке
  84.  
  85. #define DSTRING_ERR_RESIZE 0//я ламерок и не умею в переменные - моё место на помойке
  86. #define DSTRING_SUCC_RESIZE 1//я ламерок и не умею в переменные - моё место на помойке
  87.  
  88. /* Resize dstring capacity */
  89. static int dstr_capacity_resize(dstring_t * str, size_t capacity) {//статик инты и прочий мусор - я не умею писать код
  90.   char * temp_data_ptr = (char *)dstr_realloc(str->data, capacity);//очередной С/С++ ламерок.
  91.  
  92.   if(temp_data_ptr == NULL) return DSTRING_ERR_RESIZE;//Очередная ламерюга, не умеющая в Си.
  93.  
  94.   str->data = temp_data_ptr;//Ламерюга не умеющая в Си.
  95.   str->capacity = capacity;//То же самое.
  96.   return DSTRING_SUCC_RESIZE;//Ламерюга не умеет в !succ - надо же заваять тонну дерьма, но !succ не осилилось
  97.  
  98. }
  99.  
  100. /*
  101.  * Base function implementation
  102.  */
  103.  
  104. /* Create new dynamic string and init that string $init.
  105.    Return pointer into created dynamic string, or NULL if can't allocate memory for that.
  106.  */
  107. dstring_t * dstr_new(const char * init) {
  108.   dstring_t * str = (dstring_t *)dstr_malloc(sizeof(dstring_t));//ламерок не может в Си. Зачем юзать маллок один раз, если можно заюзать его 2 раза. А что не три?
  109.   // *** понятно что можно сделать один маллок и туда и стрктуру воткнуть и данные. но если надо их ресайзить то
  110.  
  111.   if(str == NULL) return NULL;//просто ахриненная история - ламерок опять не умеет в си.
  112.  
  113.   size_t data_capacity = DSTRING_DEFAULT_CAPACITY;//ламерок не умеет в си.
  114.   size_t init_len = 0;//ламерок не умеет в си.
  115.  
  116.   if(init != NULL) {//логика убогих мне не ясная
  117.     init_len = strlen(init);//Я не умею в Си.
  118.     data_capacity += init_len;//facepalm
  119.   }
  120.  
  121.   str->data = (char *)dstr_malloc(data_capacity);//я умамы ламерок
  122.  
  123.   if(str->data == NULL) {//я не умею в си.
  124.     free(str);
  125.     return NULL;
  126.   }
  127.  
  128.   str->length = init_len;//я не умею в си.
  129.   str->capacity = data_capacity;//я не умею в си.
  130.   memcpy(str->data, init, init_len);//я не умею в си.
  131.  
  132.   return str;//я не умею в си.
  133. }
  134.  
  135. /* Free memory which takes dynamic string. */
  136. void dstr_delete(dstring_t * str) {
  137.   if(str != NULL) {//я не умею в си.
  138.     dstr_free(str->data);//я не умею в си.
  139.     dstr_free(str);//я не умею в си.
  140.   }
  141.  
  142.   // *** на ноль проверяю что бы не освобождать память по NULL указателю - это бессмысленно
  143.   // (хотя тут следовало бы говорить что в функцию суют указатель на NULL)
  144.   //..free() сам проверяет и ничего не освобожает.
  145. }
  146.  
  147. /* Truncate dynamic string $str to fixed length $len from the beginning $str. */
  148. dstring_t * dstr_truncate(dstring_t * str, size_t len) {//дерьмо.
  149.   if(str != NULL && str->length > len) {
  150.     if(dstr_capacity_resize(str, DSTRING_DEFAULT_CAPACITY + len))
  151.       str->length = len;
  152.   }
  153.  
  154.   return str;
  155. }
  156.  
  157. /* Set value of dynamic string $str equal $val.
  158. dstring_t * dstr_set(dstring_t * str, const char * val) {//дерьмо
  159.  
  160.   if(val == NULL && dstr_capacity_resize(str, DSTRING_DEFAULT_CAPACITY))
  161.     str->length = 0;
  162.   else {
  163.     size_t val_len = strlen(val);
  164.  
  165.     if(dstr_capacity_resize(str, DSTRING_DEFAULT_CAPACITY + val_len)) {
  166.       str->length = val_len;
  167.       memcpy(str->data, val, val_len);
  168.     }
  169.   }
  170.  
  171.   return str;
  172. }
  173. */
  174.  
  175. /* Output dstring value into stream */
  176. void dstr_fprint(const dstring_t * str, FILE * file) {//дерьмо
  177.   if(file == NULL || str == NULL) return;
  178.   fwrite(str->data, 1, str->length, file);
  179.  
  180.   // *** я не могу получитиь доступ к структуре ибо она спрятана. По этому я пишу в файл через функцию
  181.   //.. тут дело в моей жопаболи от fwrite() и в том, что эта операция просто не имеет смысла. Сделай get_length().
  182.   //а если я хочу записать половину твоей строки? Что я буду делать?
  183. }
  184.  
  185. /* Return length of dynamic string $str. */
  186. size_t dstr_len(const dstring_t * str) {
  187.   return str->length;
  188. }
  189.  
  190. /* Swaps values of two dynamic strings.
  191. void dstr_swap(dstring_t * str1, dstring_t * str2) {//зачем это надо? Опять школьник вчера увидивший кресты стал у мамки сишником?
  192.   if(str1 == NULL || str2 == NULL) return;
  193.  
  194.   char * temp_data_ptr = str1->data;
  195.   size_t temp_length = str1->length;
  196.   size_t temp_capacity = str1->capacity;
  197.  
  198.   str1->capacity = str2->capacity;
  199.   str1->length = str2->length;
  200.   str1->data = str2->data;
  201.  
  202.   str2->data = temp_data_ptr;
  203.   str2->capacity = temp_capacity;
  204.   str2->length = temp_length;
  205. }
  206. */
  207.  
  208. /* Append string into dsting.
  209. dstring_t * dstr_append(dstring_t * str, const char * val) {//просто дерьмо, зачем нужно dstr_set(), если это то же самое?
  210.   if(str == NULL || val == NULL) return str;
  211.  
  212.   size_t val_len = strlen(val);
  213.  
  214.   if(val_len > (str->capacity - str->length)) {
  215.     size_t new_capacity = str->capacity + val_len + DSTRING_CAPMARGIN;
  216.  
  217.     if(!dstr_capacity_resize(str, new_capacity))
  218.       return str;
  219.  
  220.     str->capacity = new_capacity;
  221.   }
  222.  
  223.   memcpy(str->data + str->length, val, val_len);
  224.   str->length += val_len;
  225.   return str;
  226. }
  227.  
  228. /* Append single char into dsting. */
  229. dstring_t * dstr_appendc(dstring_t * str, char c) {//просто нахрен дерьмо
  230.   if(str == NULL) return str;
  231.  
  232.   if((str->capacity - str->length) < 1) {
  233.     if(!dstr_capacity_resize(str, str->capacity + DSTRING_CAPMARGIN)) return str;
  234.  
  235.     str->capacity += DSTRING_CAPMARGIN;
  236.   }
  237.  
  238.   str->data[str->length] = c;
  239.   str->length++;
  240.   return str;
  241.  
  242.   // *** нет не дерьмо. ради вставки одного симвла мне нужно дергать memcpy ? зачем?
  243.   // *** плюс надо будет передавать в двойных кавычках строку в одним смволом. зачем?
  244.   // *** ( хотя проверку на длинну можно вставить в append )
  245.   // само добавление символа не имеет смысла.
  246. }
  247.  
  248. //
  249. dstring_t * dstr_coolreasize(dstring_t * str, uint64_t len) {
  250.   //логика работы такая - после вызова этой функции гарантируется, что append() на len байт влезет по capacity.
  251. }
  252.  
  253. //теперь твоё днище превращается в
  254. dstring_t * dstr_appendc(dstring_t * str, char c) {//просто нахрен дерьмо
  255.   if(str == NULL) return str;
  256.   dstr_coolreasize(str, 1);//как-то так и тебе не надо писать одно и тоже в каждой функции на 10строк
  257.   *(str->data + (++str->length)) = c;//как-то так
  258. }
  259.  
  260. /* Prepend string into dsting. */
  261. dstring_t * dstr_prepend(dstring_t * str, const char * val) {//Л - логика.
  262.  
  263.   // а в чем проблема? вставка в начало строки)
  264.  
  265.   if(str == NULL || val == NULL) return str;
  266.  
  267.   if(str->length == 0) return str = dstr_set(str, val);
  268.  
  269.   size_t val_len = strlen(val);
  270.  
  271.   if(val_len == 0) return str;
  272.  
  273.   size_t new_capacity = str->capacity + val_len;
  274.  
  275.   if(!dstr_capacity_resize(str, new_capacity))
  276.     return str;
  277.  
  278.   str->capacity = new_capacity;
  279.  
  280.   // move the $str value on $val_len characters to rigth
  281.   memmove(str->data + val_len, str->data, str->length);
  282.   memcpy(str->data, val, val_len);
  283.   str->length += val_len;
  284.   return str;
  285. }
  286.  
  287. /* Compare two dynamic strings and return 1 if they are equals or 0 - if don't. */
  288. int dstr_equal(const dstring_t * str1, const dstring_t * str2) {
  289.   if(str1->length != str2->length) return 0;//я у мамы ламерок. Это типа куллоптимизация?
  290.   return strncmp(str1->data, str2->data, str1->length) == 0;//а если str2 меньше str1?
  291.  
  292.   // *** функция называется equal - это либо равно либо нет.
  293.   // *** так что больше или меньше и какая из строк не интересует.
  294.   // *** проверка на равенство длинн - логична в этом контексте,
  295.   // *** ибо нафига сравнивать две строки с разной длинной - он и так не равны.
  296.   // *** (я не учитываю строки забитые с конца пробелами одинаковой длинны и тд)
  297.  
  298.   //.. Я про другое. Она не логична - это куллоптимизация, которая итак должна быть в strcmp().
  299.   //Далее ты заюзал strncmp(), а не strcmp() из-за куллоптимизация, при этом это абсолютно(в50%+) не имеет смысла, ибо всё равно каждый символ проверяет на терминатор.
  300.   //если ты хотел куллоптимизацию, чтобы как бэ у строк без терминатора, то memcmp(a, a, min(alen, blen));
  301. }
  302.  
  303. // Converts dynamic string characters to uppercase.
  304. /*
  305. dstring_t * dstr_toupper(dstring_t * str) {//таким дерьмом можешь только подтереться
  306.   for(size_t i = 0; i < str->length; i++)
  307.     str->data[i] = toupper(str->data[i]);
  308.  
  309.   return str;
  310. }
  311.  
  312. // Converts dynamic string characters to lowercase.
  313. dstring_t * dstr_tolower(dstring_t * str) {//и этим тоже.
  314.   for(size_t i = 0; i < str->length; i++)
  315.     str->data[i] = tolower(str->data[i]);
  316.  
  317.   return str;
  318. }
  319. */
  320.  
  321. //..Давай поясню почему это мусор - это в 10+раз тормазнее нормальной реализации не через таблицу.
  322. //тебе надо поднять диапазон a-z до a-A - это всё идеально векторизуется в if(c >= 'a' && c <= 'z') c += diffAa;
  323.  
  324.  
  325. /* Insert value of string $val after $n character $str. */
  326. dstring_t * dstr_insert(dstring_t * str, const char * val, size_t n) { //т.е. твоя вставка в начало не вставка? Просто логика
  327.  
  328.   // *** тут я не понял что ты умеешь ввиду
  329.   // *** это вставка после  n-ного символа в строке
  330.   //// я имею ввиду то, что у тебя есть вставка в начало, которая эквивалентна dstr_insert(x, y, 0); Зачем писать ещё одну куллфункцию раздувая код?
  331.   if(val == NULL || n > str->length) return str;
  332.  
  333.   size_t val_len = strlen(val);
  334.  
  335.   if(val_len == 0) return str;
  336.  
  337.   size_t new_capacity = str->capacity + val_len;
  338.  
  339.   if(dstr_capacity_resize(str, new_capacity))
  340.     str->capacity = new_capacity;
  341.  
  342.   // move the $str value on $val_len characters to rigth
  343.   memmove(str->data + val_len + n, str->data + n, str->length - n);
  344.   memcpy(str->data + n, val, val_len);
  345.   str->length += val_len;
  346.   return str;
  347. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement