purebasic.info

PureBasic forum
Текущее время: Сб сен 22, 2018 10:42 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: Вс июн 19, 2016 2:58 am 
Не в сети
доцент

Зарегистрирован: Вс май 15, 2016 5:08 pm
Сообщений: 55
Благодарил (а): 1 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Всем привет.

Нужно прочитать бинарный файл, распарсить полученную вереницу байт в определенную структуру, произвести какие-то манипуляции с определенными полями этой структуры и так же бинарно записать все это дело назад. Проблема в том, что пока не соображу как это реализовать.

Структура файла проста:

1. Сигнатура (4 байта)
2. Длина 1 параметра (1 байт)
3. 1 параметр (длина из пункты выше)

... тут еще 10 таких же структур как п.2 и п.3

Х. CRC32 от конца сигнатуры и до самой контрольной суммы

Файл читается в заранее выделенную область памяти, равную его размеру. А вот как дальше эту область "нарезать кусками", чтоб запихнуть в структуру, произвести манипуляции с бинарными данными этой структуры (там же как-то иначе, нежели работа со строками, да ?) и главное - упаковать это все обратно в последовательность байт, чтобы записать назад.

Т.е. вот начальные наброски кода по классической схеме:

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
Enumeration
        #File
EndEnumeration
 
Structure bindata
        param1.b
        param2.b
        param3.b
        param4.b
        param5.b
        param6.b
        param7.b
        param8.b
        param9.b
        param10.b
EndStructure
 
file.s = OpenFileRequester("", "", "SDAConfig (bin)|*.bin", 0)
 
If file.s <> ""
        If ReadFile(#File, file.s)
                size.i = Lof(#File)
                *memory = AllocateMemory(size)
                If *memory
                        ReadData(#File, *memory, size)
                        CloseFile(#File)
 
                        ; Вот в этом месте месте затык
 
                        FreeMemory(*memory)
                        Else
                                Debug "Memory allocation fail"
                                End
                        EndIf
                Else
                        Debug "Can't open file"
                End
        EndIf
EndIf
 


_________________
Чат по PureBasic в Telegram


Последний раз редактировалось damn Пн июн 20, 2016 6:04 pm, всего редактировалось 1 раз.

Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июн 19, 2016 6:40 am 
Не в сети
профессор

Зарегистрирован: Вс июн 10, 2012 8:18 am
Сообщений: 1294
Благодарил (а): 60 раз.
Поблагодарили: 49 раз.
Пункты репутации: 14
damn писал(а):
А вот как дальше эту область "нарезать кусками"

Можно читать данные при помощи PeekB, PeekL и т.д. Например PeekB(*memory + n)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июн 19, 2016 12:07 pm 
Не в сети
доцент

Зарегистрирован: Вс май 15, 2016 5:08 pm
Сообщений: 55
Благодарил (а): 1 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
А если понадобится прочесть целиком что-то большее, нежели 4 байта (PeekL) ? Как склеить несколько кусков, после чтения тем же PeekL, для вычисления контрольной суммы к примеру ?

_________________
Чат по PureBasic в Telegram


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июн 19, 2016 12:49 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
readdata? у меня например при чтении vgm файла, хотя точно уже не помню но там что-то типа такого: сначала маяк, что тут начинается блок данных, после размер этого блока, а потом уже данные. вот я по моему использовал readdata и читал столько, сколько было указано в графе размер :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июн 19, 2016 1:42 pm 
Не в сети
доцент

Зарегистрирован: Вс май 15, 2016 5:08 pm
Сообщений: 55
Благодарил (а): 1 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Тогда вопрос вдогонку - ReadData читает из файла, и если кусков на чтение будет сотня, то и читать файл будет сотню раз, так ? При этом, насколько я понимаю, придется еще и позицию выставлять через FileSeek (или она сохраняется с прошлого чтения) ? А ведь файл в моем "примере" уже считан в память целиком.

Аналога для памяти типа того же FileSeek нету ?

И вопрос по обратной сборке разрозненных кусков памяти в единый, для вычисления CRC, остается открытым.

Типа того:

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
*a = AllocateMemory(10)
*b = AllocateMemory(20)
*c = AllocateMemory(30)
*all = AllocateMemory(64) ; a+b+c+crc32(a+b+c)
 
;
; тут производим какие-то операции с *a, *b, *c
;
 
*all = *a + *b + *c ; УТРИРОВАНО написано, дабы было понятно что нужно
 
; Вычисляем из *all CRC32, добавляем его в конец *all и все это пишем в файл через WriteData
 


_________________
Чат по PureBasic в Telegram


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июн 19, 2016 4:01 pm 
Не в сети
профессор

Зарегистрирован: Вс июн 10, 2012 8:18 am
Сообщений: 1294
Благодарил (а): 60 раз.
Поблагодарили: 49 раз.
Пункты репутации: 14
Лучше один раз из файла прочитать, а потом при помощи CopyMemory делить. Собственно, собирать обратно можно им же.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июн 19, 2016 7:35 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
ааа... из памяти? :) ну тогда дополнительную переменную веди, куда вписывай индекс докуда уже дочитал.

ща попробую копирнуть из своего проекта:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
memsize = MemorySize(*FileMem) ; хотя тут не совсем верно, лучше по сайзу файла а не памяти
ot = *FileMem + 64  ; переставляем на 64 символа вперед индекс, у меня там был ненужный хедер
do = *FileMem + memsize ; вычисляем последнюю ячейку докуда дописано
 
Dim VGMARR(memsize) ; создаем массив в куда писать. хотя опять таки не совсем верно. массив будет больше, чем итоговая инфа.
 
For i = ot To do ; цикл от и до
 
  Number = PeekA(i) ; получаем значение "маяка"
 
  Select Number ; разбираем "маяки" и делаем соответствующие действия
 
    Case $67  ;  0x67 0x66 tt ss ss ss ss (data) - маска для разбора
      WavDataSize = PeekI(i + 3) ; вычисляем размер блока
      WavAddres = i + 7 ; получаем адрес откуда начинается сама инфа - вав сэмпл
      i + 6 + WavDataSize ; передвигаем индекс на конец вав блока
 
    Case $E0 ; 0xE0     dddddddd - маска для разбора
      samplecoordinates = PeekI(i + 1)
      samplecoordinates = WavAddres + samplecoordinates
      i + 4 ; прыжок дальше
 
и так далее по всем "маякам" расписано что делать и насколько символов передвигать наш маркер для последующего чтения
 



Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июн 19, 2016 8:26 pm 
Не в сети
доцент

Зарегистрирован: Вс май 15, 2016 5:08 pm
Сообщений: 55
Благодарил (а): 1 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Гранд мерси, уважаемый =)

_________________
Чат по PureBasic в Telegram


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт июл 01, 2016 9:48 pm 
Не в сети
док
Аватар пользователя

Зарегистрирован: Сб мар 28, 2015 11:06 pm
Сообщений: 147
Откуда: Україна
Благодарил (а): 10 раз.
Поблагодарили: 10 раз.
Пункты репутации: 4
Тоже было интересно, сварганил такой примерчик:

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#File = 0
 
Structure BinData
  Value1.l
  Value2.l
  Byte1.b
  fixedString1.s{30}
EndStructure
 
Index.l = 5
Dim mainArray.BinData(Index)
 
mainArray(0)\fixedString1 = "This example string, Index = 0"
 
mainArray(1)\Value1 = 234
mainArray(1)\Value2 = 45
mainArray(1)\Byte1 = 5
mainArray(1)\fixedString1 = "This example string #1"
 
mainArray(2)\Value1 = 553
mainArray(2)\Value2 = 113
mainArray(2)\Byte1 = 66
mainArray(2)\fixedString1 = "This example string #2"
 
mainArray(5)\fixedString1 = "This example last string"
 
; Write Array datas To file
If CreateFile(#File, "d:\test.bin")
  WriteInteger(#File,Index)
  For a = 0 To Index
    WriteData(#File, @mainArray(a), SizeOf(BinData))
  Next a
  CloseFile(#File)
  FreeArray(mainArray.BinData())
  Else
  Debug "Ошибка создания файла"
EndIf
 
 
;  Write array datas to file
If ReadFile(#File, "d:\test.bin")
  ReadIndex.l = ReadInteger(#File)
  Dim ReadArray.BinData(ReadIndex)
  For a = 0 To ReadIndex
    ReadData(#File, @ReadArray(a), SizeOf(BinData))
  Next a
  CloseFile(#File)
Else
  Debug "Ошибка чтения файла"
EndIf
 
;  See array data
If ReadIndex
  Debug Str(ReadIndex + 1) + " records read."
  Debug "Record 0's 'fixedString1' field = " + ReadArray(0)\fixedString1
  Debug "Record 2's 'fixedString1' field = " + ReadArray(1)\fixedString1
  Debug "Record 2's 'Value2' field = " + ReadArray(1)\Value2
  Debug "Record 5's 'fixedString1' field = " + ReadArray(5)\fixedString1
EndIf



Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Ср мар 07, 2018 8:21 am 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
зато теперь у меня затык :)

вобщем файл состоит из двух частей. в первом так сказать хедеры сэмплов. во второй части данные этих сэмплов.

45 5C 04 00 00 00 2E 0E 00 00 00 00 : 45 **** - второй пошел...

1 байт - флаг частоты
3 байта - смещение по которому находится данные сэмпла. не знаю точно относительно начала файла или относительно данной позиции - эксперементальным путем потом выясню.
2 байта какой-то там флаг
2 байта размер сэмпла
2 байта еще один флаг
2 байта еще один флаг
пошел второй сэмпл
1 байт флаг частоты
3 байта смещение *****

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

вот думаю так: получив смещение на первом сэмпле - это ведь я получаю и размер хедера всех сэмплов. значит я разделив это дело на 12 - получу количество сэмплов. дальше спокойно читаю все хедеры в массив, а как только Loc(#File) дошла до смещение - дальше уже читать сразу большими блоками и прыгать дальше по массиву. надо только это дело правильно обдумать :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт мар 09, 2018 3:17 am 
Не в сети
доцент

Зарегистрирован: Вс май 15, 2016 5:08 pm
Сообщений: 55
Благодарил (а): 1 раз.
Поблагодарили: 1 раз.
Пункты репутации: 0
Так в чем проблема то? Можешь пробежаться по всем хедерам и создать индекс-массив или индекс-файл, смотря что тебе удобнее. И потом уже по этому индексу дергать нужные семплы из общей цепочки. Все зависит от размера этой цепочки. Если это цепь на 1000 семплов - одно, если она же на гиг и десятки тысяч - другое. В первом можно индекс и не создавать, при необходимости пробежаться и выдернуть нужный семпл, а вот во втором случае лучше сразу сбросить индекс в файл и пусть рядом лежит. Мало ли ты читаешь с перфокарт и скорость - это самое слабое место во всей системе. Так ты до морковкиного зада будешь искать нужный тебе семпл. А по индексу быстренько оп - и ты в нужном месте.

_________________
Чат по PureBasic в Telegram


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт мар 09, 2018 10:57 am 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
выкрутился там уже :) другой затык... куда затычнее, чем тот :))

есть некий файл матрицы. скажем
Код:
1
2
3
4
5
00000000
00123400
00567800
009ABC00
00000000



понятно что это какая-то инфа на экране располагается. мне предположим надо её сдвинуть влево. какой тут может быть алгоритм? :) элементов на экране может быть несколько. сдвигать надо именно какой-то один, не трогая остальные. причем еще не факт, что система может знать что от 1 до C это относится к одному элементу... кароче я сам не знаю чо хочу :)))

вот думаю может можно будет избавится от матрицы и использовать спрайты. там то конфиг файл есть, а в нем и размеры и координаты и форм фактор - вся инфа. в матрице же тупо номер квадратика картинки - скажем 1 - и все. как из этого огрызка родить всю инфу, что на самом деле это изображение 4х4? никак :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июл 22, 2018 3:21 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1694
Откуда: Алматы
Благодарил (а): 15 раз.
Поблагодарили: 46 раз.
Пункты репутации: 5
и тут PB сотворил мега подставу :) проект уже раздулся по самый помидоры... скоро к 75 тысячам строк подкатится. и оказалось что индекс для файла не может быть больше 1000. поскольку гаджетов у меня миллион и энумерация идет вперемешку и гаджеты и индексы файлов и изображений - немудрено, что файл где-то там ближе к концу этой самой энумерации будет куда больше 1000 иметь значение. может чото можно переключить в PB?

подозреваю придется из всей этой энумерации передвигать вверх все метки для операций с файлами. подстава так подстава...


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июл 22, 2018 3:30 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11255
Благодарил (а): 4 раз.
Поблагодарили: 429 раз.
Не нужно было все константы добавлять в один блок перечисления.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс июл 22, 2018 11:25 pm 
Не в сети
док

Зарегистрирован: Вс июл 05, 2009 5:55 pm
Сообщений: 165
Благодарил (а): 1 раз.
Поблагодарили: 7 раз.
Пункты репутации: 0
SereZa писал(а):
поскольку гаджетов у меня миллион и
ты прикалываешся или так, только преувеличиваеш. У меня есть удобный древовидный блокнот, но у него заразы куча недостатков и когда в системе PID начинает зашкаливать за15-18 тысяч, новые гаджеты несоздаются, даже сраный проводник неоткрывается. Ну и через тормоз создания 1800 редакторов в таком блокноте меня поразила, на работе блокнот открывается 2 минуты, поэтому хчу когдато написать свой аналог. Лучше содержать списки на гаджеты и на часть открытых гаджетов проэцировать, ну чегото как в масиве строк есть адреса на строки. Как в редакторе отражают только часть файла и негрузять всё в память.


Цитата:
для вычисления контрольной суммы к примеру
в справке в разделе Cipher есть вычисление контрольной суммы CRC32 в памяти.
Может тебе просто запхать в память все даные, а в масиве указать ссылки на адреса начало этих блоков и делай с ними, что надо. потом ненужно
Цитата:
после чтения тем же PeekL...
ддостаточно использовать-
CRC32Fingerprint() -возвращает контрольную сумму CRC32 указанного буфера памяти. записываеш в нужное место в памяти и все это отправляеш в файл.
А Peek и poke используеш для манипуляции даными в блоках.

Цитата:
через FileSeek
указатель файла сам перемещается по мере чтения или записи файла, а если надо прочитать с определенного то указываеш новое место.

_________________
искатель истины


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB