Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как узнать его структуру файла

9.0K
06 сентября 2007 года
mr_smit
64 / / 03.12.2006
Если кто сможет дочитать до конца тот просто герой.

У меня старичок Siemens S65 так вот проблема такая: у меня на компьютере установлена программа Mobile Phone Manager которая шла вместе с телефоном. Данная программа позволяет выполнять с телефоном разные операции (запись картинок, музыки и т.д.) и среди них есть возможность отправлять SMS и MMS прямо с компьютера, набирая текст на клавиатуре. Только у меня почему то можно отправлять только SMS, а MMS нет (кнопка не активна). Читал инструкцию – должно быть, ан нет. Облазил все настройки – бесполезно. Т.е. MMS с компьютера отправить нельзя.
А в последнее время меня очень привлекает возможность отправлять по MMS много текста (до 1000 знаков как говорят), а не так что SMS разбивается на 3-4 sms-ки и ты платишь за каждую.
Когда отправляешь MMS с телефона, то текст можно «забить» вручную или вставить из предварительно созданного файла. Файл можно создать только в самом телефоне, телефон создает его с расширением .tmo. Я хочу сделать следующее: в программе где-нибудь в Memo печатаешь текст, нажимаешь кнопку и сохраняешь это всё в файл с расширением .tmo. Ведь большой обьем текста на клавиатуре набрать проще чем на телефоне. Затем закидываем файл в телефон и прикрепляем к MMS.
Проблема в том что я не знаю структуру tmo файла. Через Блокнот он не открывается. Т.е. текст хранится в каком то собственном формате. Можно ли имея только сам файл узнать его структуру. Или другими словами как его прочитать и как в него записать?

Посмотрел в «Энциклопедия расширений файлов» там сказано:
.TMO - ZTG global optimizer default output file ;Zortech C++
Т.е. типа файл не несет никакой смысловой нагрузки. И что? Как его прочесть? Телефон же как то читает.
Попробывал вот так:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  F1, F2: TextFile;
  Ch: Char;
begin
  if OpenDialog1.Execute then begin
    AssignFile(F1, OpenDialog1.Filename);
    Reset(F1);
    if SaveDialog1.Execute then begin
      AssignFile(F2, SaveDialog1.Filename);
      Rewrite(F2);
      while not Eof(F1) do
      begin
        Read(F1, Ch);
        Write(F2, Ch);
      end;
      CloseFile(F2);
    end;
    CloseFile(F1);
  end;
end;

Если сохранить в txt формат, то вроде как текст получается (с небольшими закорючками правда). Но этого мало. На форумах по siemens никто не знает и программы для конвертации txt в tmo нет, поэтому решил сам взяться.

Итак подводя итог: Есть файл. Как узнать его структуру, как его прочитать и как в него записать?
Прикрепляю сам файл. Я создал его в телефоне и написал в нем одно слово-«Dima». Хотя можно и по русски, но это не важно.

[color=red]Для оформления кода используй теги. Модератор.[/color]
268
07 сентября 2007 года
Михаил
587 / / 25.06.2005
текст там в Unicode

P.S. просматривать файлы удобнее будет не Блокнотом, а каким либо HEX редактором или просмотрщиком TotalComander`a
16K
08 сентября 2007 года
Zbyszek
118 / / 08.08.2007
Попробуй сделать несколько таких файлов - с разным текстом, разной длины. Потом можно будет поискать закономерность. Потому как мне пока не понятно, почему в конце вместо символа "а" стоит "0♦t♦". Возможно это окончание зависит от длины текста. Увы, под рукой нет Siemens`a.
9.0K
08 сентября 2007 года
mr_smit
64 / / 03.12.2006
Вот создал еще один файл в котором написал: В траве сидел кузнечик. Открыл в HEX редакторе (см. прикрепленные рисунки). Но что то не похоже что это чистый Unicode. Вот цитата из книги Ю. Ревича «Нестандартные приемы программирования на Delphi»:

В Unicode все организовано элементарно просто и логично: если первый байт
равен нулю, то второй соответствует начертанию символа из таблицы ASCII
(или, что то же самое, английскому языку). Если же, к примеру, первый байт
равен 4, то это кириллица. Русские буквы в таблице располагаются подряд,
начиная со значения младшего байта, равного 16, "Ё" и "е", как всегда, от-
отдельно. Всякие фигурные кавычки и прочие длинные тире выбираются из отдельных таблиц со своим значением первого байта.
В принципе, если вы имеете некий Unicode-шрифт со всеми мыслимыми на-
начертаниями знаков, то можете писать многоязычный текст на всех языках
вперемешку. Правда, такой шрифт известен пока только один: это Arial
Unicode MS, который имеет объем более 13 Мбайт, и оттого может еще и за-
заработать не на всяком компьютере. Но на практике выше головы хватает и
десятка заполненных национальных страниц — что и наблюдается в ходовых
TTF-шрифтах.

В этой же книге есть пример как прочитать Unicode и переделать в txt (см. исходник).
Но он читает с небольшими «крякозяблами» т.е. получаем не чистый текст, хотя читать можно.
Все равно не пойму как записать такой файл если у меня есть txt (т.е. txt --> tmo). Как не пытался телефон твердит «Невозможно открыть файл». Чего то ему еще не хватает, но чего?
268
08 сентября 2007 года
Михаил
587 / / 25.06.2005
странно, а Lister (из TC который) при установке опций просмотра Unicode отображает чисто Dima с непечатаемым символом в начале слова и в конце
16K
08 сентября 2007 года
Zbyszek
118 / / 08.08.2007
2Михаил, странно, я смотрел Hiew'ом и наблюдал картину, почти идентичную второму скриншоту.
9.0K
08 сентября 2007 года
mr_smit
64 / / 03.12.2006
Вот ещё файлы:
Файл и что в нем написано:

Кузнец 1.tmo - В траве сидел
Unic.tmo - В Юникод всё организовано просто и логично: если
первый байт равен нулю, то второй соответствует
начертанию из таблицы
Unic 1.tmo - В Юникод всё организовано просто и логично: если
первый байт равен нулю
Unic 2.tmo - В Юникод всё организовано просто и логично

Точек в конце фраз нет.

Zbyszek похоже ты прав насчет длинны. Обрати внимание на Unic.tmo, Unic 1.tmo и Unic 2.tmo. Если открыть через блокнот, то сразу видно, что к фразе что то добавляется вначале и в конце. Я думаю это какой то идентификатор и если его нет телефон отказывается читать файл.
Может телефон считает длинну строки и добавляет к файлу, а потом при открытии проверяет длинну и очень длинные фразы не открывает (памяти мало). Ну это так предположение.
16K
08 сентября 2007 года
Zbyszek
118 / / 08.08.2007
Вот какой текст выдает Штирлиц:
[QUOTE="Штирлиц"]Кузнец 1.tmo - <новая строка>В траве сиделi
Unic.tmo - vВ Юникод всё организовано просто и логично: если первый байт равен нулю, то второй соответствует начертанию из таблицыС
Unic 1.tmo - GВ Юникод всё организовано просто и логично: если первый байт равен нулюю
Unic 2.tmo - *В Юникод всё организовано просто и логично<непечатный символ>
TmoFile.tmo - <непечатный символ>Dimаt[/QUOTE]
Видимо, первые и последние байты - что-то вроде контрольной суммы, и если она не сходится, то телефон отказывается открывать файл. Если для файлов со строками одинаковой длины но разного содержания эти байты будут разными, то, скорее всего, будет очень сложно понять, как написать конвертор txt->tmo.:(
9.0K
09 сентября 2007 года
mr_smit
64 / / 03.12.2006
Три файла одинаковой длинны:

Кузнец.tmo - В траве стоял
Кузнец 1.tmo - В траве сидел
Метро.tmo - Думал в метро

Байты в начале и в конце одинаковые у всех файлов. Контрольная сумма? Что с ней делать? По какому алгоритму посчитать?
268
09 сентября 2007 года
Михаил
587 / / 25.06.2005
Цитата: mr_smit
Три файла одинаковой длинны:

Кузнец.tmo - В траве стоял
Кузнец 1.tmo - В траве сидел
Метро.tmo - Думал в метро

Байты в начале и в конце одинаковые у всех файлов. Контрольная сумма? Что с ней делать? По какому алгоритму посчитать?


первый байт это длина сообщение, т.е. количество символов, про последний пока не знаю

16K
09 сентября 2007 года
Zbyszek
118 / / 08.08.2007
Попробуй открыть телефоном этот файл
Hullo.tmo - Hullo !!! )))
9.0K
09 сентября 2007 года
mr_smit
64 / / 03.12.2006
Я тут провел сравнительный анализ и вот мой вывод: помимо текста в кодировке Unicode в файл записываются ещё 4 байта, два в начале и два в конце.

Первый – длина строки
Второй – нулевой байт
Предпоследний - ???? не пойму как считается
Последний – при нечетной длинне строки 4, при четной длинне строки 0.

На картинке представлены некоторые мои эксперименты, всё более наглядно (см. прикрепл. изображение). Предпоследний байт каким то образом связан с регистром букв (большая или маленькая). Но каким образом известно одному Сименсу. Может у кого есть соображения на этот счет.
9.0K
09 сентября 2007 года
mr_smit
64 / / 03.12.2006
Не открывает. "Невозможно открыть файл".
268
09 сентября 2007 года
Михаил
587 / / 25.06.2005
mr_smit, а у тебя в самом первом присланном файле на одном языке все слово написано? там вроде последняя буква на русском

первые 2 байта это длина сообщения, далее идет текст в формате UTF-16LE, затем наверное контрольная сумма, ты попробуй создать сообщение из одного символа, затем из 2 таких же и так далее и проследи за изменением последних байт
9.0K
09 сентября 2007 года
mr_smit
64 / / 03.12.2006
Интересная закономерность, правда она мне пока ни о чем не говорит:
10 файлов. В первом одна буква ‘н’, во втором две, в третьем три и т. д. Предпоследний байт (контрольная сумма) в десятичной системе (‘н’ в десятичной системе 61):
1. 60
2. 2
3. 62
4. 4
5. 56
6. 6
7. 58
8. 8
9. 52
10. 10

Ещё 10 файлов. В первом одна буква ‘а’, во втором две, в третьем три и т. д. Предпоследний байт (контрольная сумма) в десятичной системе (‘а’ в десятичной системе 48):
1. 49
2. 2
3. 51
4. 4
5. 53
6. 6
7. 55
8. 8
9. 57
10. 10

Ну если ‘а’ ещё хоть на что то похоже, то ‘н’, особенно нечетное количество, вообще не понятно.

Да кстати я напортачил в самом первом файле. Там последняя 'а' русская. Исправленный файл в архиве.
268
10 сентября 2007 года
Михаил
587 / / 25.06.2005
mr_smit в приведенном тобой примере учтен только один байт, но в реальности их два и в в символе сообщения и в контрольной сумме, это нужно помнить и не отбрасывать их.

вот так:
Код:
var fs:TFileStream;
    l,crc,i,t:word;
begin
  fs:=TFileStream.Create('tmofile.htm',fmOpenRead);
  try
    fs.Read(l,2);
    if l<>0 then
      begin
        fs.Read(crc,2);
        crc:=crc xor l;
        for i:=1 to l-1 do
          begin
            fs.Read(t,2);
            crc:=crc xor t;
          end;
        ShowMessage(IntToHex(crc,4));
      end;
  finally
    fs.Free;
  end;
9.0K
12 сентября 2007 года
mr_smit
64 / / 03.12.2006
Додумался я до следующего: ищем в ‘таблице’ наш знак и пишем соответствующий байт в файл.

Код:
...

const
  Byte04: Byte = $04;
  Byte00: Byte = $00;
var
  Form1: TForm1;
  ff:file;

implementation

{$R *.dfm}

procedure TForm1.N1Click(Sender: TObject);
var  i:integer;
     s:string;
     t: byte;
begin
 if SaveDialog1.Execute then
  begin
  assignfile(ff,SaveDialog1.FileName+'.tmo');
  rewrite(ff,1);
  s:=Memo1.Text;
  for i:=1 to length(s) do
  begin
  case s of
        'а': t:=$30;
        'б': t:=$31;
        'в': t:=$32;
        'г': t:=$33;
        'д': t:=$34;
        'е': t:=$35;
        'ё': t:=$51;
        'ж': t:=$36;
        'з': t:=$37;
        'и': t:=$38;
        'й': t:=$39;
        'к': t:=$3A;
        ',': t:=$2C;
        '.': t:=$2E;
        ' ': t:=$20;
        '?': t:=$3F; // и т.д.
      else t:=$3F; // если что то другое - знак вопроса ?
      end;
    blockwrite(ff, t,1);
    if (t=$2C) or (t=$2E) or (t=$20) or (t=$3F) then  begin
     blockwrite(ff,Byte00,1);
    end
    else begin
     blockwrite(ff,Byte04,1);
    end;
  end;
  closefile(ff);
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
memo1.Text:='ёж, газ, бак.';
end;

...


Но не понимаю как записать в начало файла длинну строки. Если использовать

IntToHex(Length(Memo1.Text))

то получаем строку (string) и записать в файл её нельзя, компилятор ругается. А по твоему алгоритму, Михаил, контрольная сумма считается правильно, только когда в начале файла указана длинна строки.

Мой исходник в архиве.
268
12 сентября 2007 года
Михаил
587 / / 25.06.2005
длину записать можно при помощи BlockWrite
9.0K
12 сентября 2007 года
mr_smit
64 / / 03.12.2006
Всё, сделал. Код конечно не претендует на идеальный. Но главное работает. Телефон открывает без проблем. Единственное ограничение это то что можно набрать не более 400 символов, свыше 400 телефон отказывается читать. Но и в редакторе телефона тоже больше 400 не набирается. Видно это как то связано с памятью, незнаю.

Михаил тебе огромное спасибо за код, без него я конечно ничего бы не сделал.

Ну и собственно исходник для тех кому интересно. (Правда его нужно немного доработать, добавить поддержку заглавных букв, но это уже мелочи).
268
12 сентября 2007 года
Михаил
587 / / 25.06.2005
Цитата: mr_smit
Всё, сделал. Код конечно не претендует на идеальный. Но главное работает. Телефон открывает без проблем. Единственное ограничение это то что можно набрать не более 400 символов, свыше 400 телефон отказывается читать. Но и в редакторе телефона тоже больше 400 не набирается. Видно это как то связано с памятью, незнаю.

Михаил тебе огромное спасибо за код, без него я конечно ничего бы не сделал.

Ну и собственно исходник для тех кому интересно. (Правда его нужно немного доработать, добавить поддержку заглавных букв, но это уже мелочи).



гораздо проще использовать StringToWideChar, чем переводить в Unicode самому

10
12 сентября 2007 года
Freeman
3.2K / / 06.03.2004
Цитата: Михаил
гораздо проще использовать StringToWideChar, чем переводить в Unicode самому


Достаточно

 
Код:
var
  S: string;
  W: WideString;
begin
  S := 'мама';
  W := S; // тут компилятор вставляет вызов MultiByteToWideChar
// работаем с W
end;
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог