Artöm
факт в том что я даже не знаю как
В таком случае готовое решение тебе ничего не даст. Нужно понимать каждую строчку и почему она именно такая, в асинхронном контексте особенно
Dan
мы с @xvitaly работаем над этим. Github.com/procxx/faq
Давайте, нам всем есть что добавить
Vitaliy ◀️TriΔng3l▶️
хотя, тут может быть во втором случае что-нибудь типа mov r2, r1, rsl 5
ed
Ребят, а что выбрать С++ или javascript?
Это 2 крайности.. Слишком много контроля над кодом и полное его отсутствие.. ЗЫ люблю и то и другое..
Artöm
А потом нужно будет написать то же самое с незначительными изменениями, а ты не сможешь, потому что не понимаешь принципов
Artöm
Ребят, а что выбрать С++ или javascript?
А если серьезно - эти языки на разных уровнях по применению находятся. Скажи, где, над чем работать хочешь
Constantine
Как лучше писать: (byte & 0xe0) == 0xc0 или (byte » 5) == 6?
если byte типа unsigned char то вообще пофиг
Vitaliy ◀️TriΔng3l▶️
Artöm
Для себя можно и плюсы, чтобы потом холиварить
Aidar
Да, unsigned char
ты спрашиваешь что дольше сдвиг или and? вроде одинаково
Aidar
по логике
Constantine
Да, unsigned char
писать так чтобы твой сосед с маниакальным психозом тебе голову не снес ледорубом
Vladislav
Artöm
Если нужно проверить один бит, то логичней сдвигом
Aidar
лучше наверн 0b юзать тут
Vitaliy ◀️TriΔng3l▶️
Vitaliy ◀️TriΔng3l▶️
Vitaliy ◀️TriΔng3l▶️
но там не один бит проверяется, а три, четыре или пять для первого байта, а для остальных — два
Constantine
да там очевидно всё, я просто для UTF-8 код пишу
скопипасть перекодировщик с фолли лол
Vitaliy ◀️TriΔng3l▶️
так что, там явно не test, а cmp
Constantine
да там очевидно всё, я просто для UTF-8 код пишу
https://github.com/facebook/folly/blob/master/folly/Unicode.cpp
Vitaliy ◀️TriΔng3l▶️
о, кстати
Vitaliy ◀️TriΔng3l▶️
if (!(fst & 0x80))
Vitaliy ◀️TriΔng3l▶️
shr же ZF ставит?
Vitaliy ◀️TriΔng3l▶️
хотя, без разницы, что shr, что test, оба с 8-битным immediate
Constantine
ты на асме что ли пишешь
Vitaliy ◀️TriΔng3l▶️
Vitaliy ◀️TriΔng3l▶️
или даже cmp с immediate, та же хрень
Constantine
я полагаю, компилер поймет и оптимизирует тебе
Constantine
хоть как ты напишешь
Vitaliy ◀️TriΔng3l▶️
блин, я тот самый сосед
Constantine
вычислить функцию unsigned char -> unsigned char на всех отсчетах не так сложно
Constantine
и потом подставить табличку
Constantine
какую из них как оптимально в асме делать
Vitaliy ◀️TriΔng3l▶️
abTextU32 abTextU8_NextCP(abTextU8 const * * textCursor) { abTextU8 const * text = *textCursor, first = *text; if (first == '\0') { return 0u; } if (first <= 127u) { ++(*textCursor); return first; } // Doing || sequences in order is safe due to early exit. if ((first >> 5u) == 6u) { if ((text[1u] >> 6u) != 2u) { ++(*textCursor); return abText_InvalidSubstitute; } *textCursor += 2u; return ((abTextU32) (first & 31u) << 6u) | (text[1u] & 63u); } if ((first >> 4u) == 14u) { if ((text[1u] >> 6u) != 2u || (text[2u] >> 6u) != 2u) { ++(*textCursor); return abText_InvalidSubstitute; } *textCursor += 3u; abTextU32 cp = ((abTextU32) (first & 15u) << 12u) | ((abTextU32) (text[1u] & 63u) << 6u) | (text[2u] & 63u); return ((cp & ~((abTextU32) 0x7ffu)) != 0xd800u) ? cp : abText_InvalidSubstitute; } if ((first >> 3u) == 30u) { if ((text[1u] >> 6u) != 2u || (text[2u] >> 6u) != 2u || (text[3u] >> 6u) != 2u) { ++(*textCursor); return abText_InvalidSubstitute; } *textCursor += 4u; abTextU32 cp = ((abTextU32) (first & 7u) << 18u) | ((abTextU32) (text[1u] & 63u) << 12u) | ((abTextU32) (text[2u] & 63u) << 6u) | (text[3u] & 63u); return (cp <= 0x10ffff) ? cp : abText_InvalidSubstitute; } ++(*textCursor); return abText_InvalidSubstitute; } как-то так :D
Aidar
а на функции разбить никак?
Vladislav
Глаза вытекают
Stanislav
Aidar
Глаза вытекают
так это же си
Nik
а на си разве нельзя писать более...красиво?
Vladislav
так это же си
Да это даже в студии выглядит просто pizdec
Igor
по-моему битоёбство просто по своей природе такое, его можно улучшить разве что раздробив на однострочные функции с максимально понятными именами
Igor
и каждому индексу и константе, да
ttldtor
сколько комментариев не пиши, всё равно сегфолтнется
Vladislav
и поехали страдать херней по памяти
Vitaliy ◀️TriΔng3l▶️
Да это даже в студии выглядит просто pizdec
ну u лишнее, конечно, но это я просто для себя такое правило сделал, как с f
Vitaliy ◀️TriΔng3l▶️
чтобы уж наверняка, если там что-нибудь типа 0x80000000
Vitaliy ◀️TriΔng3l▶️
а на функции разбить никак?
А зачем? Назначение у этой функции неделимое
Vitaliy ◀️TriΔng3l▶️
Разве что валидация тут захардкодена
Aidar
А зачем? Назначение у этой функции неделимое
Уверен? Что тогда значит тыща ифов?
Aidar
И коммент в середине
Vitaliy ◀️TriΔng3l▶️
И коммент в середине
Чтоб если вдруг когда-нибудь позже взгляну на этот код, не захотелось наделать вложенных ифов
Vitaliy ◀️TriΔng3l▶️
Уверен? Что тогда значит тыща ифов?
Разбор записи самой базовой сущности в UTF-8
Aidar
Ты разбор не можешь на подэтапы разбить?
Vitaliy ◀️TriΔng3l▶️
Ты разбор не можешь на подэтапы разбить?
Так эти подэтапы коротенькие совсем
Vitaliy ◀️TriΔng3l▶️
Да и сама функция коротенькая
Aidar
И что
Vitaliy ◀️TriΔng3l▶️
И фундаментальная
Aidar
Охуеть коротенькая
Aidar
Упоролся чтоль
Vitaliy ◀️TriΔng3l▶️
Зачем по всему файлу разбрасывать мелкие кусочки?
Aidar
Затем что они имеют название и могут быть переиспользованы
Vitaliy ◀️TriΔng3l▶️
И потом путаться в том, что для чего предназначено и кому что можно использовать
Kirill
я долго хотел что то написать по делу, но в общем. нужно ли давать функциям читаемые имена и делить ужасный пипец на более мелкие читаемые части это вроде вопрос для supapro
Vitaliy ◀️TriΔng3l▶️
Aidar
Придумай нормальные названия
Vitaliy ◀️TriΔng3l▶️
Придумай нормальные названия
Какие названия? Тут название одно — последовательность в UTF-8
Pavel
abTextU32 abTextU8_NextCP(abTextU8 const * * textCursor) { abTextU8 const * text = *textCursor, first = *text; if (first == '\0') { return 0u; } if (first <= 127u) { ++(*textCursor); return first; } // Doing || sequences in order is safe due to early exit. if ((first >> 5u) == 6u) { if ((text[1u] >> 6u) != 2u) { ++(*textCursor); return abText_InvalidSubstitute; } *textCursor += 2u; return ((abTextU32) (first & 31u) << 6u) | (text[1u] & 63u); } if ((first >> 4u) == 14u) { if ((text[1u] >> 6u) != 2u || (text[2u] >> 6u) != 2u) { ++(*textCursor); return abText_InvalidSubstitute; } *textCursor += 3u; abTextU32 cp = ((abTextU32) (first & 15u) << 12u) | ((abTextU32) (text[1u] & 63u) << 6u) | (text[2u] & 63u); return ((cp & ~((abTextU32) 0x7ffu)) != 0xd800u) ? cp : abText_InvalidSubstitute; } if ((first >> 3u) == 30u) { if ((text[1u] >> 6u) != 2u || (text[2u] >> 6u) != 2u || (text[3u] >> 6u) != 2u) { ++(*textCursor); return abText_InvalidSubstitute; } *textCursor += 4u; abTextU32 cp = ((abTextU32) (first & 7u) << 18u) | ((abTextU32) (text[1u] & 63u) << 12u) | ((abTextU32) (text[2u] & 63u) << 6u) | (text[3u] & 63u); return (cp <= 0x10ffff) ? cp : abText_InvalidSubstitute; } ++(*textCursor); return abText_InvalidSubstitute; } как-то так :D
uint32_t GetUtf8Char(uint32_t* i, const std::string &m_text){ static const char trailingBytesForUTF8[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; static const uint32_t offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; uint32_t first = (uint8_t)m_text[*i]; uint32_t ch = 0; int count = *i; unsigned short extraBytesToRead = trailingBytesForUTF8[first]; switch (extraBytesToRead) { case 5: ch += (uint8_t)m_text[count++]; ch <<= 6; case 4: ch += (uint8_t)m_text[count++]; ch <<= 6; case 3: ch += (uint8_t)m_text[count++]; ch <<= 6; case 2: ch += (uint8_t)m_text[count++]; ch <<= 6; case 1: ch += (uint8_t)m_text[count++]; ch <<= 6; case 0: ch += (uint8_t)m_text[count++]; } *i = count - 1; ch -= offsetsFromUTF8[extraBytesToRead]; return ch; }
Kirill