Instantly share code, notes, and snippets.

Embed
What would you like to do?
Binary template for reading strings of known or unknown length
//--------------------------------------
//--- 010 Editor v5.0.0 Binary Template
//
// File: prelen.bt
// Author: x1nixmzeng/WRS
// Revision: v1.03
// Purpose: Reading strings of known length
// History
// v1.03 Added optional STR_ENCODING macro to specify the charset
// used to format the template results
// Added optional PRELEN_REQUIRE macro for future versions
// v1.02 Added new alignment type for null-length strings
// v1.01 Added guards to avoid errors when included more than once
// v1.00 NOTE: The prelenType enum values have been updated
// NOTE: Unicode strings have been separately defined (wstr)
// Supports
// * 32/16/8 size descriptions
// * Null-terminated strings
// * Fixed length strings
// ------------------------------------
// v0.05 Now supports strings of known length
// v0.04 Added support for null-terminated strings
// v0.03 Added supported for wide strings (prepend 'w' to prelenType)
// v0.02 strRead function replaced with GetStrValue
// Cleaner GetStrValue method
// String displayed for empty values can now be defined outside script
//--------------------------------------
#ifndef PRELEN_BT_
#define PRELEN_BT_
#define PRELEN_VERSION 103
RequiresVersion(5);
#ifndef STR_EMPTY
// Default value used for empty values
#define STR_EMPTY ""
#endif
#ifndef STR_ENCODING
// Default source encoding
#define STR_ENCODING GetFileCharSet()
#endif
#ifdef PRELEN_REQUIRE
if(PRELEN_REQUIRE > PRELEN_VERSION)
{
Warning("Version %u of prelen.bt is required (have %u)", PRELEN_REQUIRE, PRELEN_VERSION);
Exit(-1);
}
#endif
//#define PRELEN_DISABLE_CHECKS
// Length flags
enum prelenType
{
pnt8 = -6, // null-terminated size descriptor, string padded to 8 bytes
pnt4 = -5, // null-terminated size descriptor, string padded to 4 bytes
plen32 = -4, // 32-bit size descriptor
plen16 = -3, // 16-bit size descriptor
plen8 = -2, // 8-bit size descriptor
pnt = -1, // null-terminated size descriptor
pblank = 0 // Empty string
};
//
// Helpers
//
int Align(int val, int align)
{
return ((val+(align-1)) & (~(align-1))) - val;
}
//
// Structures
//
// ASCII
struct prelenStr( prelenType t )
{
if( t == pblank )
{
// NOTE: This will give an empty structure warning
local uint len = 0;
}
else
{
if( t > pblank )
{
local uint len = t;
char val[len];
}
else
if( t == pnt || t == pnt4 || t == pnt8 )
{
string val;
local uint len = Strlen( val );
if( len > 0 && t != pnt )
{
local int pad = 0;
local uint size = len +1;
switch( t )
{
case pnt4 : pad = Align(size, 4); break;
case pnt8 : pad = Align(size, 8); break;
}
if( pad > 0 )
FSkip( pad );
}
}
else
{
switch( t )
{
case plen32 : uint len; break;
case plen16 : ushort len; break;
case plen8 : ubyte len; break;
default : Assert( false, "Unknown prelenType" );
}
#ifndef PRELEN_DISABLE_CHECKS
if( FTell() + len > FileSize() )
Warning("prelen.bt :: String out of bounds");
#endif
if( len > 0 )
char val[len];
}
}
};
// Unicode
struct prelenWStr( prelenType t )
{
if( t == pblank )
{
// NOTE: This will give an empty structure warning
local uint len = 0;
}
else
{
if( t > pblank )
{
local uint len = t;
wchar_t val[len];
}
else
if( t == pnt || t == pnt4 || t == pnt8 )
{
wstring val;
local uint len = WStrlen( val );
if( len > 0 && t != pnt )
{
local int pad = 0;
local uint size = (len +1) * sizeof(wchar_t);
switch( t )
{
case pnt4 : pad = Align(size, 4); break;
case pnt8 : pad = Align(size, 8); break;
}
if( pad > 0 )
FSkip( pad );
}
}
else
{
switch( t )
{
case plen32 : uint len; break;
case plen16 : ushort len; break;
case plen8 : ubyte len; break;
default : Assert( false, "Unknown prelenType" );
}
if( len > 0 )
wchar_t val[len];
}
}
};
//
// Type definitions
//
// ASCII
typedef prelenStr str <read=GetStrValue >;
// Unicode
typedef prelenWStr wstr <read=GetWStrValue>;
//
// Accessor functions
//
// ASCII
wstring GetStrValue(str &t)
{
// Return string or empty string
return( t.len ? StringToWString(t.val, STR_ENCODING) : STR_EMPTY );
}
// Unicode
wstring GetWStrValue(wstr &t)
{
// Return string or empty string
return( t.len ? t.val : STR_EMPTY );
}
#endif
// EOF
@x1nixmzeng

This comment has been minimized.

Owner

x1nixmzeng commented Sep 30, 2012

This template was adapted from the version posted on XeNTaX: http://forum.xentax.com/viewtopic.php?p=77375#p77375

From v0.03, it contains a few performance fixes and adds supported for fixed-length widestrings!

@x1nixmzeng

This comment has been minimized.

Owner

x1nixmzeng commented Feb 10, 2013

Updated to v1.00 which allows for fixed-length strings, with some minor changes to how Unicode strings are handled.

@x1nixmzeng

This comment has been minimized.

Owner

x1nixmzeng commented Nov 30, 2014

Updated to v1.02 which adds support for padding null-terminated strings to support 4 or 8 byte alignment

@x1nixmzeng

This comment has been minimized.

Owner

x1nixmzeng commented Feb 3, 2015

Updated to v1.03 which includes an optional macro for target character set (for display in the template results). Example usage:

#define STR_ENCODING CHARSET_CHINESE_S
#include "prelen.bt"

str ChineseString(plen32);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment