1. Pascal / Говнокод #6865

    +96

    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
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    Assign(F, FileName);
      IOResult;
      Reset(F);
      if IOResult = 0 then begin
        for i := 0 to MaxModelNamesCount-1 do ModelKind[i] := mkVagon;
        Result := True;
        BlockRead(F, W, 2);
        if W = OldWDim then begin // старый формат
          // 20 строк пропущено
        end else if W = WDim then begin // новый формат
          BlockRead(F, FormatVersion, 4); // версия нового формата
          if FormatVersion <= 4 then begin
            BlockRead(F, EditorDate, 4);
            BlockRead(F, C, 4);
            LCount := C;
            for i := 0 to LCount - 1 do begin
              BlockReadLine(F, Lines[i], 16);
              if (FormatVersion <= 2) and (Lines[i].Attr[3] and $0F = 5) then Lines[i].Attr[0] := 0
              else if (Lines[i].Attr[3] and $0F = k3DObject) then ModelKind[Lines[i].IntAttr[1]] := mkStatic;
            end;
            if FormatVersion <= 1 then begin
              ModelNamesCount := 8;  // для 1й версии список жёстко задан
              ModelNames[0] := 'ГЗРВ-10';
              ModelNames[1] := 'ГЗРВ-10М';
              ModelNames[2] := 'КТМ-5М3';
              ModelNames[3] := 'ЛМ-68';
              ModelNames[4] := 'ЛМ-68М';
              ModelNames[5] := 'ЛМ-68ММ';
              ModelNames[6] := 'ЛВС-86';
              ModelNames[7] := 'ЛВС-97';
              for i := 8 to MaxModelNamesCount-1 do ModelNames[i] := '';
            end else if FormatVersion <= 3 then begin
              ModelNamesCount := 0;
              for i := 0 to 255 do begin
                j := 0;
                BlockRead(F, j, 1);
                SetLength(ModelNames[i], j);
                for j := 1 to Length(ModelNames[i]) do Read(F, byte(ModelNames[i, j]));
                if ModelNames[i] <> '' then Inc(ModelNamesCount);
              end;
            end else begin
              BlockRead(F, ModelNamesCount, 4); // кол-во моделей
              for i := 0 to MaxModelNamesCount - 1 do ModelNames[i] := '';
              for i := 0 to ModelNamesCount-1 do begin
                BlockRead(F, k, 4); // номер считываемой модели
                j := 0;
                BlockRead(F, j, 1); // длина имени, не более 255
                SetLength(ModelNames[k], j);
                for j := 1 to Length(ModelNames[k]) do Read(F, byte(ModelNames[k, j]));
              end;
            end;
    
            for i := 0 to 8 do
              for j := 0 to 12 + Byte(FormatVersion >= 2) do with Routes[i, j] do begin
                BlockRead(F, PCount, 2);
                SetAllowedModels(Routes[i,j], 0, -1);
                if FormatVersion <= 1 then begin      
                  BS := [];
                  BlockRead(F, BS, 4);
                  AllowedModelsCount := 0;
                  for k := 0 to 255 do if k in BS then begin
                    Inc(AllowedModelsCount);
                    AllowedModels[k] := True;
                  end;
                end else if FormatVersion <= 3 then begin
                  BlockRead(F, BS, 32);
                  AllowedModelsCount := 0;
                  for k := 0 to 255 do if k in BS then begin
                    Inc(AllowedModelsCount);
                    AllowedModels[k] := True;
                  end;
                end else begin
                  BlockRead(F, AllowedModelsCount, 4);
                  for k := 0 to AllowedModelsCount-1 do begin
                    BlockRead(F, n, 4);           // номер модели
                    AllowedModels[n] := True;
                  end;
                end;
    
                for k := 0 to PCount - 1 do begin
                  if FormatVersion >= 3 then BlockRead(F, c, 4)
                  else begin
                    c := 0;
                    BlockRead(F, c, 2);
                  end;
                  Points[k] := c;
                end;
                BlockRead(F, DefVagons, 1);
                SpeedRoute := boolean(DefVagons shr 4);
                DefVagons := DefVagons and $0F;
                BlockRead(F, Interval, 1);
              end;
          end else Result := False;
        end else Result := False;
        Close(F);

    Короче, лапша из if FormatVesion такой-то...
    Обратная совместимость формата файла.
    Формату уже 4 года.

    Запостил: TarasB, 05 Июня 2011

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

    • Это какая-то хитрая магия.
      Где смеяться-то?
      Ответить
    • Такой большой код вряд ли будет смешным.
      Ответить
    • yeah TL;DR
      немного доставил руглиш с вагоном
      Ответить
    • Уходи, НЕХ! Уходи!
      Ответить
    • Смеяться на кол-ве условий, связанных с версией формата.
      Ответить
      • Забыли указать номера строк.
        Ответить
        • Да похрен на номера.
          Ну короче я просто хотел сказать, в какое говнище и портянку из непонятных условий превращается поддержка (даже в одну сторону) всей файловых форматов, когда-либо связанных с данной программой.
          Ответить
      • ну и что плохого в поддержке бородатых форматов - может это жизненно важно для системы?
        Возможно, стоило бы отдельно реализовать чтение данных для каждой версии файлов. тот еще высер, конечно, но для поддержки и модификации кода намного проще.
        Ответить
        • Это скорее всего значит, что формата, как такового никогда не было, его не проектировали, и не задумывались над расшираемостью, дополнениями в будущем, удобством чтения и т.п. просто, как пришло в голову, так и записали. Оскар, конечно не формат файлов, но в своем роде классика жанра. Не сильно заглядывая в код, тут, похоже, что какие-то данные, которые можно было заложить в структуру формата определяются по его версии. Т.е. допустим, у нас есть Х записей, и мы наивно верим, что записей всегда будет именно Х и они все фиксированой длины Y. Мы пишем процедуру, которая читает по Y элементов X раз. В следующей версии оказывается, что записей может быть X+1. Тут уже стоит задуматься, а может лучше было бы записать сколько записей всего есть в файл, и таким образом сделать процедуру чтения более универсальной, чтобы прочитав сначала N, в котором описывается количество записей, мы бы потом прочитали N записей из Y элементов.
          Судя по всему, даже в четвертой версии эта идея не пришла в голову автора формата, и даже если в пятой версии он исправится, остальные четыре прийдется читать вот так вот.
          Ответить
          • скорее всего это так. что сделано - то сделано, говорить поздно.
            а сейчас все-таки стоит рефакторить с учетом всего выше сказанного, а поддержку ранних версий вынести в depricated-функцию (функции).
            Ответить
            • То есть использование ранних версий нежелательно? :D
              Ответить
              • типа того. нежелательно, но допустимо, т.к. сохранение, как я понимаю, позволено только в последнем формате.
                плюс еще в том, что при внесении изменений не придется проверять работоспособность всех старых версий.
                есть идеи получше?
                Ответить
                • Не совсем понял про:
                  >плюс еще в том, что при внесении изменений не придется проверять работоспособность всех старых версий.
                  Ответить
                  • судя по отсутствию проектирования до реализации этого кода, с большой вероятностью изменения еще будут. При этом старые форматы надо поддерживать - видимо, отказаться от этого нельзя. для очередной версии предлагаю написать код с нуля, а для старых версий оставить этот и не трогать его.
                    Ответить
          • кто такой оскар?
            Ответить
          • Автор формата - я.
            Про нормальный формат я знаю. Например, можно в начале каждой записи записывать её размер. И если при чтении из файла размер больше того, что знает программа, то проигнорировать лишнее, если меньше, то добить недостающее нулями. Это позволило бы очень долго дополнять формат новыми полями, не меняя код загрузки и сохранения вообще.
            Идея изменить формат на нормальный висит уже давно. Вместе с идеей обновить движок полностью, не ковыряясь в наследстве времён 3 курса. Уже год, как я каждый месяц вклиниваю какое-нибудь изменение, делая это в лоб, не думая об архитектуре (уже не до неё потому что), обещая больше это не трогать и вскоре переписать нафиг.
            Ответить
            • Ну вы вклинивайте так, чтобы было максимально близко к предполагаемой архитектуре.Ну, чтобы мусора не создавать.
              Ответить
            • > переписать нафиг
              именно это я вам и предлагаю
              Ответить
              • Ага, а для этого надо будет думать, как впихнуть более глобальные фичи, которые давно назревали, но я не делал, потому что в движок не вписывались ваще.
                Короче, полгода жизни я угроблю точно.
                Ответить
                • не мне вас учить конечно, но разве нельзя сделать несколько функций-оберток?
                  ну и понятно, что ничего не делать - проще сейчас. а что потом - ну вам виднее.
                  Ответить
          • И лучше всего формат разрабатывать текстовым. Хотя бы XML или JSON, а если по уму (где ж его взять?), то хватит и попроще. Часть проблем вообще отпадает — битность целых, длина строк, формат дат и вещественных, длина массивов, дополнительные атрибуты. И перенести данные в программу на другом языке проще.
            Ответить
            • Вот с картами я боюсь, что эта текстовость слишком много лишнего объёма может создать.
              А модели там и так текстовые, кстати. Размер при этом поражает. Довольно хорошо выглядящая модель вагона в архиве занимает максимум 10КИЛОбайт, и это нормально.
              Ответить
              • gzip

                В итоге выйдет меньше.
                Ответить
                • бинарник тоже можно архивировать.
                  в любом случае вопрос в критичности размера данных.
                  Ответить
                  • В текстовом формате сжимается намного лучше.
                    Ответить
                    • И разжимается намного шире.
                      Я вчера то же самое хотел написать из-под гостя (под хромом не логинился), не пустило, зато капча была 9999, не вру!
                      Ответить
                      • А какая разница, какого оно будет виртуального размера между декомпрессором и парсером? Потом всё равно во внутреннее представление переведётся, которое может быт как компактнее, так обширнее текстового (и может меняться независимо от внешнего).
                        Ответить
                        • да кто его знает? может в его проекте это критично, и стандартные решения по тем или иным причинам не устраивают?
                          Никуда не денешься - и изобретай тут велосипеды:(
                          я наступил на такие же грабли лет 7-8 назад - описал свои действия - как позже оказалось, все делал не зря.
                          Ответить
                          • Для проекта типа приведённого выше — совершенно некритично. А если человек хорошо понимает, что делает, то сможет сам выбрать подходящее средство.
                            Ответить
            • если размер не критичен, то какой-ньть JSON будет удачным выбором.
              у себя подобную проблему решил написанием довольно простого контейнера данных - древовидная структура нодов с доступом по строковому ключу, в каждом из них хранится массив элементов (у меня был 2д массив, но это частности). элемент может быть int, double, string, data (бинарные данные). формат файла после этого больше не менялся, менялась только спецификация, в плюсе имеем стандарт, контроль за ошибками (был случай по почте файл пересылали килобайт 50 размера, а он испоганился), удобство работы (если нормально классы сделать), маленький размер данных (можно zlib поюзать). в минусе - день потраченного времени.
              Ответить
            • Ну такая техника не прокатит для видео, или аудио, например. Или, например, когда критично, чтобы можно было максимально разбить на части, и легко читать с произвольного места (иерархические структуры типа XML к этому плохо подходят). А так - да, если есть такая возможность.
              Ответить
              • Для видео и аудио есть готовые форматы и специальные библиотеки. Для специальных требований тоже можно найти стандартные специальные средства. Например, для быстрого произвольного доступа — разбивка на отдельные файлы, отдельный файл-индекс (как почтовики для mbox создают), dictzip, Berkeley DB, SQLite, другие БД. А внутри — на усмотрение программы.
                Ответить
                • Ну так а они что трансцедентальные и существовали всегда и всегда будут и аналоги (лучшие) не нужны? К слову, я почему про Оскара вспомнил, например, на сегодняшний день нет ни одного формата передачи сообщений, который бы соответсвовал всем требованиям, которые потенциально предъявляются к "мессенджерам" разных видов. Т.е. какие-то способны передавать только текст, какие-то могут не только текст, но структура сообщения не позволяет использовать для мультикаста и т.п. Тот же формат e-mail - такой анахронизм, да и не просто анахронизм, а дико неудобный, небезопасный и т.п. Форматы видео пишутся и регистрируются новые по нескольку штук в год.
                  Как бы я не вижу никаких причин не создавать свои форматы, если этого требует ситуация. Это все равно что не делать новые редакторы кода потому что есть emacs. :) (скоро 24-я верся, релиз, кстати).
                  Ответить
                  • > Форматы видео пишутся и регистрируются новые по нескольку штук в год.

                    А кто это делает, кстати? Я бы с удовольствием затащил их в свой подвал для вивисекторских экспериментов.
                    После того, как я два дня убил на то, чтобы найти все кодеки и конвертёры для одного видео (я хотел его склеить из 2 файлов в 1 и перевести в другой формат), я ненавижу тех, кто плодит эти форматы.
                    Ответить
                    • Ну тут как бы есть несколько нюансов... иногда кодеками называют конкретную реализацию алгоритма, а иногда сам алгоритм. Например MPEG (какой-то из) реализован в Xvid. С другой стороны, если последовательность из BMP картинок зазиповать - это тоже будет кодеком?
                      А так, Википедия говорит, что знает вот такие: http://en.wikipedia.org/wiki/List_of_codecs :)
                      Ответить
                    • >я ненавижу тех, кто плодит эти форматы.
                      А ещё и тех, кто из года в год меняет ГОСТы оформления документов просто от того, что-бы его не выгнали с работы за бездействие, заменяя жирные буквы большими, меняя отступ от края страницы на миллиметр и тд - без причин.
                      Ответить
                  • Специализированные распространённые форматы обычно разрабатываются людьми, очень хорошо разбирающимися в этой сфере, поэтому они намного эффективнее доморощеных велосипедов. А главный плюс в том, что они распространённые — существует множество библиотек для работы с ними в разных языках программирования (иногда даже в стандартной библиотеке). Это, с одной стороны, прячет сложность формата под капот, за простой интерфейс, с другой — позволяет работать с ним уже написанными сторонними программами. Если архив сообщений хранить в формате сообщений email, то его можно импортировать в почтовый клиент (тысячи их!) и использовать его возможности для просмотра/фильтрации/поиска. Если картинки внедрять в формате jpeg/png/gif (а не каком-то самописном), то их можно извлечь и просмотреть любым вьювером. Если использовать стандартный компрессор, то данные можно извлечь не реализуя свой декомпрессор для каждого случая. Это не просто экономит время и деньги при разработке, это ещё и удобнее и расширяемее.

                    Разумеется, на самом верхнем уровне мы принимаем стратегические решения, какие из стандартных форматов использовать, как их комбинировать. это уже зависит от нашего приложения и полностью наше.
                    Ответить
                    • Стыдно говорить, но много раз был свидетелем, того, когда нужно, чтобы сторонний софт не мог работать с вашими данными. политика. решение управленцев, посадить на наше ПО, чтобы другие не залезли. Что делать - кушать-то хочется.
                      Ответить
                    • В моей практике очень часто оказывалось так, что стандартные решения либо убоги, либо не подходяв в принципе.
                      Типичный пример: нужно как-то передавать данные из флеша на сервер и обратно. Казалось бы банально, но когда это вырастает до десятковы тысячь запросов в час, то начинают чесать репу о том, что в мемкешед не влезает, мемкешед не успевает и т.п. XML - долго генерится и долго парсится. Вот так вот. JSON - чуть лучше, но это нестандартная хрень, особенно в том, как оно работает с алиасами в строках (типа \r например). AMF - формат построен с поддержкой дурацкой фичи, которая не нужна никому - кроме того, что хранятся описания классов, в таблицах символов хранятся не хеши строк, а строки, как есть. Пробовал переписывать таблицы символов, долго. Protobuf - никому не нужные во флеше long / ulong. Изза которых нужно тянуть левую библиотеку для длинной математики + реализация формата в рекоммендуемом Гуглом проекте ниже плинтуса. Писатель не в курсе был про ByteArray.endian свойство, поэтому разворачивал все 4-байтовые последовательности вручную. В итоге пришлось писать самим. Это даже не гордость никакая, просто ничто другое нормально не работало. Kонечно, можно было и даже тем же XML воспользоваться, но по деньгам, это 2К долларов в месяц убытков на ровном месте (аренда доп. серверов у Амазона).
                      Ответить
                      • Это уже типизация людских ресурсов.
                        Ответить
                      • \r и прочее стандартизировано. После парсинга в динамически типизированных языках получаем сразу готовое внутренне представление (в статически — без оверхеда в 2-3 раза не обойтись, но всё равно перевод проще, чем из XML). Во многих языках поддержка есть «из коробки» или лёгкой сторонней библиотекой. Если нет — тогда лучше не связываться, проще изобретать что-то простое, чем велосипедить кривую реализацию.

                        В любом случае у текстового представления будут преимущества (если это не большой блоб, упакованный специальным алгоритмом, вроде картинок, музыки, видео).
                        Ответить
                        • Нет, JSON не является стандартом. Почитайте RFC. Там прямо в первой строчке / строчках так и написано. Проблема с ним в том, что алиасы он не будет запоминать как алиасы, и всегда при туда-обратно переводе он будет представлять их в том виде, в котором ему удобно, а не так, как это было записано. Врезультате, например, если вы хотели хешировать строку, или проверять чексумы может случится облом. При чем, облом будет только в каких-то очень редких случаях, которые, как правило, на тестах не всплывут.
                          Что до стандартизации алиасов, то, например ECMAScript считает, что \v (вертикальная табуляция) существует, а JSON так не считает. И, собственно поэтому утверждение о том, что JSON и ECMAScript совместимы не верно. Хотя авторы колотят себя пяткой в грудь :)
                          Ответить
                          • Любой правильный генератор JSON создаёт представление, которое однозначно и правильно интерпретируется любым правильным парсером JSON и результат не зависит от внешнего представления. Какие там пробелы, эскейпинг (кстати, \r гарантируется RFC) и нормализация чисел — никого не волнует, это незначащие детали. Не нужно сравнивать внешнее представление, это неправильно. То, что ECMAScript (и некоторые парсеры JSON) понимает больше, чем допускает JSON, — это естественно, в ECMAScript и [2+3] валидно. JSON совместим с ECMAScript снизу вверх.
                            Ответить
                            • Ну вы в упор смотрите на белое и беззастенчиво называете его черным.
                              Нет, RFC - это не стандарт. ECMA - тоже не стандарт, стандарты это ISO / ANSI и им подобные. ECMA свои произведения утверждает в качестве стандартов. JSON - это пока что на уровне инициативы, но никак не стандартизирован. Кроме того, заявление его авторов о полном соответсвии синтаксиса с ECMAScript какой бы то ни было версии - это всего лишь выдумка его авторов. Валидное выражение ECMAScript "foo\vbar" вызывает ошибку в любом JSON парсере правильно реализующем формат. Кроме того, этот формат не гарантирует полного соответсвия полученной и отправленной информации - поэтому, использовать его там, где это критически необходимо (например места, где нужно оперировать контрольными сумами) не возможно.
                              Ответить
                              • Вам шашечки или ехать? JSON — вполне себе стандарт, хоть и не официальный (и ГОСТа на него нет). Это стандарт де-факто, отклонения от него если и существуют, то следует считать ошибочными. Он совместим с ECMAScript, то, что произвольное выражение ECMAScript не принимается парсером JSON этому не противоречит — ведь это не выражение JSON. И информация в нём кодируется вполне однозначно, входные и выходные данные полностью соответствуют — в том смысле, в котором вообще можно говорить о соответствии (представление данных в разных языках может в деталях отличаться, и адреса памяти, по которым размещены данные, будут различаться).
                                Ответить
    • Кeтчуп в студию, официaнт!
      Ответить
    • показать все, что скрытоvanished
      Ответить

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