Reading UDTs out of a byte array (CopyMemory vs Get on a disk file)
From: Beowulf (beowulf_is_not_here_at_hotmail.com)
Date: 06/18/04
- Next message: Eduardo A. Morcillo [MS MVP VB]: "Re: Convert BMP to JPG"
- Previous message: Ken Halter: "Re: Convert BMP to JPG"
- Next in thread: Gale Green: "Re: Reading UDTs out of a byte array (CopyMemory vs Get on a disk file)"
- Reply: Gale Green: "Re: Reading UDTs out of a byte array (CopyMemory vs Get on a disk file)"
- Reply: J French: "Re: Reading UDTs out of a byte array (CopyMemory vs Get on a disk file)"
- Messages sorted by: [ date ] [ thread ]
Date: Fri, 18 Jun 2004 14:26:17 -0400
Ok, I've been banging my head against the wall on this one for the
better part of a day, now and am hoping someone can point me in the
right direction.
I have an ActiveX DLL that converts data structures stored in a
proprietary binary file into COM objects. It's been working fine for
quite a while, but recently some users have complained about how long
it takes to load a file over the network (50 - 75 seconds), so I'm
looking into buffering the file to speed up access.
The file is a data dictionary for a proprietary database system
developed by my company. Anyway, it consists of a 64 byte header
followed by some number of 128 byte "variable records" laid out
contiguously on disk and then some number of 64 byte "segment records"
also laid out contiguously on disk.
Here is what I am doing to create a byte array in memory of the
contents of the data file:
Public Sub LoadBuffer(sFile As String)
Dim hFile As Integer
Dim lNumBytes As Long
' Open file
hFile = FreeFile
Open sFile For Binary Access Read As #hFile
' Dimension array
lNumBytes = LOF(hFile)
ReDim aryBuffer(lNumBytes - 1) As Byte
' Fill buffer
Get #hFile, , aryBuffer
' Close file
Close #hFile
End Sub
LoadBuffer() executes in about 1 second over the network, so it holds
promise. Using the current/slow method, I would just do sequential
Get #hfile calls on the file to fill in my UDTs. However, now that I
have the bytes in memory, I'm trying to use the Subs below to get the
data into the UDTs (declaration of UDTs below). I've used a hex
editor to inspect the bytes in the source file, and then gone through
my byte arrays and the bytes are all the same. For some reason,
though, CopyMemory doesn't store the bytes into the UDTs correctly.
This is what the data for a single "variable record" file looks like
using the slow method (which fills the UDT correctly) and what I'm
trying to get working using CopyMemory:
ReadFrom|Method|left_ptr_offset|right_ptr_offset|balancing_byte|unique_var|seg_var_name|offset_value|var_attrib|var_status|format_offset_h|format_offset_s|segment_offset|var_offset|lo_bound|hi_bound|var_length|var_new_length|redefine_begin|default_missing_values|order_number|var_label|Digits_only|response_require|question_number|available_byte|order_number_ptr|new_format_offset_h|new_format_offset_s|delivery_flag|redefine_end|next_var_num|dbsv_filler_1
File on disk|"Get #hfile,,udtVar"|25856|451072|43|U|BASE BASEID
|1|67|65|-1|-1|0|0|0|0|8|0|0| |1|SAMPLE PERSON ID NUMBER PLUS CHECK
DIGIT|32|32| |0|0|-1|-1|32|0|226|32
Byte array in memory|"CopyMemory udtVar, aryBuffer(jump - 1), 128
"|25856|451072|43|U|BASE BASEID |1|67|65|-1|65535|0|0|0|80|0|0|
|16723|MPLE PERSON ID NUMBER PLUS CHECK DIGIT |32|32|
|0|-1|-1|-503316448|0|8224|0|0|
Any help in figuring out what's going on, would be greatly
appreciated. Thanks.
Private Sub GetDDHeader(udtHeader As data_base_timestamp)
CopyMemory udtHeader, aryBuffer(0), VAX_TSTAMP_REC_SIZE
End Sub
Private Sub GetDDVarRecord(jump As Long, udtSegVar As
data_base_seg_vars)
CopyMemory udtSegVar, aryBuffer(jump - 1), VAX_DBSV_REC_SIZE
' The commented lines below document the final state of my attempts
' at shifting around the bytes in a temporary buffer before copying
' them into the UDT at a vain attempt to resolve word alignment
' issues. So far, even after various shifts, the data ends up
' getting out of alignment when read into the UDT
'
' Read bytes into temporary buffer
'CopyMemory aryTemp(0), aryBuffer(jump - 1), VAX_DBSV_REC_SIZE
'
' Right-shift the bits to account for word alignment issues
'
' right-shift format_offset_s by 2 bytes
'CopyMemory aryTemp(35), aryTemp(33), VAX_DBSV_REC_SIZE - 34
'
' right-shift hi_bound by 2 bytes
'CopyMemory aryTemp(47), aryTemp(45), VAX_DBSV_REC_SIZE + 2 - 46
'
' right-shift var_label by 40 bytes
'CopyMemory aryTemp(103), aryTemp(63), VAX_DBSV_REC_SIZE + 4 - 64
'
' Read the shifted bits into the structure
'CopyMemory udtSegVar, aryTemp(0), VAX_DBSV_REC_SIZE
End Sub
Public Type data_base_timestamp
' Various time stamps
db_date_created As String * 6 ' Database date created
db_time_created As String * 6 ' Database time created
db_date_modified As String * 6 ' Database date modified
db_time_modified As String * 6 ' Database time modified
db_date_reorg As String * 6 ' Database date
reorganized
db_time_reorg As String * 6 ' Database time
reorganized
' Offset information
dbsv_head_offset As Long ' Offset value of head
node in segment.variable tree
dbs_head_offset As Long ' Offset value of start
of segment structure
' Totals
total_seg_var_records As Integer ' Total number of
segment.variable records
total_seg_records As Integer ' Total number of
segment records
total_fmt_records As Integer ' Total number of
records needed to store ALL format info
total_formats As Integer ' Total number of
formats defined
' Miscellaneous vars
db_study_id As String * 8 ' Heading of dd list
db_privilege_byte As Byte ' "R" = pending reorg, "
" - no reorg outstanding
dbt_filler_1 As String * 3 ' A little extra room
for whatever
End Type
' The Data Dictionary segment structure (VAX_DBS_REC_SIZE bytes)
Public Type data_base_segments
dbs_current_address_ptr As Long ' Pointer to buffer
address of current segment
dbs_segment_name As String * 8 ' Name of the segment
dbs_replay_head As Long ' Pointer buffer to hold
random file access reference
dbs_segment_length As Integer ' Total segment size for
allocation
dbs_key_length As Integer ' Size of record key for
ISAM access. Set by file open routine.
dbs_list_head As Long ' Pointer to first
segment record in regular record list
dbs_record_ctr As Integer ' Count of the number of
records in the list
dbs_offset_value As Integer ' Equal to occurrence
number
dbs_file_status As Byte ' 0 = closed, 1 = open
dbs_fab_addr As Long ' Pointer to File Access
Block (FAB) of the segment
dbs_prototype_offset As Long ' Prototype offset from
beginning of seg vars (skip timestamp)
dbs_record_status As Byte ' =1 all records loaded
from disk, also known as dbs_load_status
dbs_bytes_read As Integer ' Contains the byte
count of the segment record for I/O
dbs_key_offset As Integer ' Offset of record key
for ISAM access. Set by file open routine.
dbs_preload_var_offset As Integer ' Offset of segment
preload flag
dbs_preload_var_length As Integer ' Length of segment
preload flag
dbs_delete_head As Long ' head of list of
deleted segments (7/31/85)
' actually, top of stack
of deleted segments, implemented as list
dbs_list_tail As Long ' -> Last segment record
in regular record list (9/23/85)
dbs_var_cnt As Integer ' Number of variables on
this segment
dbs_access As Byte ' "G" =Getseg access
only
dbs_first_var_num As Integer ' Variable number of var
with lowest order number on this seg
dbs_filler_1 As String * 2
End Type
-- What do you get when you multiply 6 by 9?
- Next message: Eduardo A. Morcillo [MS MVP VB]: "Re: Convert BMP to JPG"
- Previous message: Ken Halter: "Re: Convert BMP to JPG"
- Next in thread: Gale Green: "Re: Reading UDTs out of a byte array (CopyMemory vs Get on a disk file)"
- Reply: Gale Green: "Re: Reading UDTs out of a byte array (CopyMemory vs Get on a disk file)"
- Reply: J French: "Re: Reading UDTs out of a byte array (CopyMemory vs Get on a disk file)"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|