1. C++ / Говнокод #23170

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    int32 documentColorIndex(DocumentData *document, QString &ext) {
    	int32 colorIndex = 0;
    
    	QString name = document ? (document->name.isEmpty() ? (document->sticker() ? lang(lng_in_dlg_sticker) : qsl("Unknown File")) : document->name) : lang(lng_message_empty);
    	name = name.toLower();
    	int32 lastDot = name.lastIndexOf('.');
    	QString mime = document ? document->mime.toLower() : QString();
    	if (name.endsWith(qstr(".doc")) ||
    		name.endsWith(qstr(".txt")) ||
    		name.endsWith(qstr(".psd")) ||
    		mime.startsWith(qstr("text/"))
    		) {
    		colorIndex = 0;
    	} else if (
    		name.endsWith(qstr(".xls")) ||
    		name.endsWith(qstr(".csv"))
    		) {
    		colorIndex = 1;
    	} else if (
    		name.endsWith(qstr(".pdf")) ||
    		name.endsWith(qstr(".ppt")) ||
    		name.endsWith(qstr(".key"))
    		) {
    		colorIndex = 2;
    	} else if (
    		name.endsWith(qstr(".zip")) ||
    		name.endsWith(qstr(".rar")) ||
    		name.endsWith(qstr(".ai")) ||
    		name.endsWith(qstr(".mp3")) ||
    		name.endsWith(qstr(".mov")) ||
    		name.endsWith(qstr(".avi"))
    		) {
    		colorIndex = 3;
    	} else {
    		QChar ch = (lastDot >= 0 && lastDot + 1 < name.size()) ? name.at(lastDot + 1) : (name.isEmpty() ? (mime.isEmpty() ? '0' : mime.at(0)) : name.at(0));
    		colorIndex = (ch.unicode() % 4);
    	}
    
    	ext = document ? ((lastDot < 0 || lastDot + 2 > name.size()) ? name : name.mid(lastDot + 1)) : QString();
    
    	return colorIndex;
    }

    https://github.com/telegramdesktop/tdesktop/blob/5f5770dd46491133b135a71fc2d4f92d13107ade/Telegram/SourceFiles/layout.cpp#L170-L211

    херь из исходниктв Telegram Desktop

    Запостил: j123123, 10 Июля 2017

    Комментарии (20) RSS

    • Нет чтоб сделать
      switch (name.ends)
      {
          ".doc":
          ".txt":
          ".psd":
              colorIndex = 0;
          ".xls":
          ".csv":
              colorIndex = 1;
      .....
      }

      Но в плюсах такого нет, плюсы - говно!
      Ответить
      • > Но в плюсах такого нет
        Т.е. ты хочешь сказать, что в C++ недостаточно фич?!

        Надо просто головой подумать, не нужны тут эти свичи.
        using color_index = int;
        
        constexpr std::pair<std::string_view, color_index> color_index_by_extension[] = {
          {"txt", 0},
          {"psd", 0},
          {"xls", 1},
          // ...
          {"zip", 3},
          // ..
        };
        
        constexpr std::pair<std::string_view, color_index> color_index_by_mime_type[] = {
          {"text", 0},
          // ...
        };
        
        color_index pick_color_index(std::string_view filename, std::string_view mime) {
          auto mime_type = extract_mime_type(mime);
          for (auto&& entry : color_index_by_mime_type) {
            if (mime_type == entry.first) return entry.second;
          }
          auto extension = extract_extension(filename);
          for (auto&& entry : color_index_by_extension) {
            if (extension == entry.first) return entry.second;
          }
          return color_index_from_hash(filename, mime);
        }
        Если сильно хочется, можно отсортировать списки и искать бинарным поиском, но тут они настолько короткие, что профит вряд ли будет заметен.
        Ответить
        • блядь, какой ебаный пиздец!
          constexpr std::pair<std::string_view, color_index> color_index_by_extension[] = {
            {"txt", 0},
            {"psd", 0},
            {"xls", 1},
            // ...
            {"zip", 3},
            // ..
          };

          А если надо не
          colorIndex = 0;

          или
          colorIndex = 1;

          а например сделать что-то менее тривиальное, скажем
          switch (name.ends)
          {
              ".doc":
              ".txt":
              ".psd":
                  colorIndex = 0;
                  while (someshit)
                  {
                      //someshit...
                  }
                  if (someshit) {someshit; someshit; colorIndex = 0;}
                  else {colorindex = 666;}
                  break;
              ".xls":
              ".csv":
                  // еще какая-то ебучая хуйня, которую мне лень придумывать
                  break;
          .....
          }

          и чтоб эт не выглядело как ебучая мешанина из std::хуйня<std::параша, говно> а чтоб блядь выглядело как switch?
          Ответить
          • #define CASE(keys, code) {keys, [&]() code},
            
            CASE({".doc", ".txt", ".psd"}, {
                colorIndex = 0;
            })
            Ответить
    • > qstr(".txt")

      Это ведь выделяет память для создания временных строк?

      > QString name = document ? (document->name.isEmpty() ? (document->sticker() ? lang(lng_in_dlg_sticker) : qsl("Unknown File")) : document->name) : lang(lng_message_empty);

      Три тернарных оператора в одной строке, какая жесть. Нет бы написать простую функцию, которая вычисляет имя документа из DocumentData*
      Ответить
      • И не говори, этот телеграм какие-то говнокодеры олимпиадные писали, не иначе
        Ответить
        • > какие-то говнокодеры олимпиадные
          Емнип, Дуров на разработку телеграма как раз олимпиадников и набирал.
          Ответить
          • вроде на все клиенты конкурсы были. хотя про десктоп может и вру.
            Ответить
      • > Это ведь выделяет память для создания временных строк?
        Это самопальная функция

        > Три тернарных оператора в одной строке, какая жесть
        QString name = [](auto document) {
            if (!document)
                return lang(lng_message_empty);
            if (!document->name.isEmpty())
                return document.name;
            if (document->sticker())
                return lang(lng_in_dlg_sticker);
            return qsl("Unknown File");
        }(document);
        Ответить
      • > выделяет память для создания временных строк
        Мне по протобуфу показалось, что у вас там не экономят.
        Ответить
    • > colorIndex = (ch.unicode() % 4);
      Т.е. остальные файлы красим почти рандомно, тупо по первой букве расширения или mime типа?

      "Заебало эти типы перечислять... Пускай хоть как-то раскрасятся, чтобы нескучно выглядело."
      Ответить
      • адекватное решение, в принципе. Все расширения всё равно не перечислишь, а такой вариант хорошо справляется с поставленной задачей: раскрасить файлы в разные цвета чтобы одинаковые файлы окрашивались одинаково
        Ответить
    • вот вообще обратите внимание, что все расширения файлов укладываются в 4 байта
      ".doc" ".txt" ".psd" ".xls" ".csv" ".pdf" ".ppt" ".key" ".zip" ".rar" ".ai" ".mp3" ".mov" ".avi"
      Т.е. все это говно например можно закодировать в uint32_t и потом находить кусок с расширением, и делать switch по uint32_t переменной.
      И да, можно регистр всех символов сбросить в нижний регистр ASCII кодировки битовой маской тупо, ну чтоб у нас под ".doc" и ".dOc" не делать отдельный case
      Ответить
      • http://govnokod.ru/19842#comment322416 немного рассуждений об strcasecmp функции и регистре букв
        Ответить
      • А что делать с ".xlsx", ".docx" и, о боже, ".vcxproj".
        Ответить
        • uint64_t
          Но пока таких расширений там нет, об этом можно не думать.
          Ответить
        • ".blueprint"
          Ответить
          • Ну значит вначале проверяем, попадает ли наше расширение в 8 байт, если не попадает, применяем отдельный алгоритм.Можно просто все расширения сверх 8 байт обрабатывать так, что цвет выставляется по хэшу из этих байт расширения, а все байты расширения сверх 8 байт просто игнорим, ну как-то так наверное, типа берем расширение, и если например у нас расширение занимает 32 байт, то мы это все хэшируем в 3 байта (R, G, B) исключая возможно какие-то белые цвета или что-то типа того (чтоб с фоном не сливалось), и вот такой цвет выставляем, все очень просто. Надо только чтоб лавинный эффект, чтоб вот если хотя б один битик в байтике отличается между двумя расширениями, то чтоб цвет совсем другой
            Ответить
        • uint64_t?
          Ответить

    Добавить комментарий