added amb618 - binary file i/o
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401802
This commit is contained in:
parent
cf023a0b7d
commit
abb763d1e1
@ -640,6 +640,197 @@ static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
FILE *pFile;
|
||||
size_t read = 0;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (params[4] != 1 && params[4] != 2 && params[4] != 4)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]);
|
||||
}
|
||||
|
||||
cell_t *data;
|
||||
pContext->LocalToPhysAddr(params[2], &data);
|
||||
|
||||
if (params[4] == 4)
|
||||
{
|
||||
read = fread(data, sizeof(cell_t), params[3], pFile);
|
||||
}
|
||||
else if (params[4] == 2)
|
||||
{
|
||||
int16_t val;
|
||||
for (cell_t i = 0; i < params[3]; i++)
|
||||
{
|
||||
if (fread(&val, sizeof(int16_t), 1, pFile) != 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
data[read++] = val;
|
||||
}
|
||||
}
|
||||
else if (params[4] == 1)
|
||||
{
|
||||
int8_t val;
|
||||
for (cell_t i = 0; i < params[3]; i++)
|
||||
{
|
||||
if (fread(&val, sizeof(int8_t), 1, pFile) != 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
data[read++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (read != (size_t)params[3] && ferror(pFile) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
FILE *pFile;
|
||||
cell_t num_read = 0;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *buffer;
|
||||
pContext->LocalToString(params[2], &buffer);
|
||||
|
||||
char val;
|
||||
while (1)
|
||||
{
|
||||
/* If we're in stop mode, break as soon as the buffer is full. */
|
||||
if (params[4] && (params[3] == 0 || num_read >= params[3] - 1))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (fread(&val, sizeof(val), 1, pFile) != 1)
|
||||
{
|
||||
if (ferror(pFile))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (val == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (params[3] > 0 && num_read < params[3] - 1)
|
||||
{
|
||||
buffer[num_read++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (params[3] > 0)
|
||||
{
|
||||
buffer[num_read] = '\0';
|
||||
}
|
||||
|
||||
return num_read;
|
||||
}
|
||||
|
||||
static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
FILE *pFile;
|
||||
size_t read = 0;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
cell_t *data;
|
||||
pContext->LocalToPhysAddr(params[2], &data);
|
||||
|
||||
if (params[4] != 1 && params[4] != 2 && params[4] != 4)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]);
|
||||
}
|
||||
|
||||
/* :NOTE: This really isn't compatible with big endian but we will never have to worry about that. */
|
||||
|
||||
if (params[4] == 4)
|
||||
{
|
||||
if (fwrite(data, sizeof(cell_t), params[3], pFile) != (size_t)params[3])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (params[4] == 2)
|
||||
{
|
||||
for (cell_t i = 0; i < params[3]; i++)
|
||||
{
|
||||
if (fwrite(&data[i], sizeof(int16_t), 1, pFile) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (params[4] == 1)
|
||||
{
|
||||
for (cell_t i = 0; i < params[3]; i++)
|
||||
{
|
||||
if (fwrite(&data[i], sizeof(int8_t), 1, pFile) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_WriteFileString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
FILE *pFile;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *buffer;
|
||||
pContext->LocalToString(params[2], &buffer);
|
||||
|
||||
size_t len = strlen(buffer);
|
||||
|
||||
if (params[3])
|
||||
{
|
||||
len++;
|
||||
}
|
||||
|
||||
return (fwrite(buffer, sizeof(char), len, pFile) == len) ? 1 : 0;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(filesystem)
|
||||
{
|
||||
{"OpenDirectory", sm_OpenDirectory},
|
||||
@ -664,5 +855,9 @@ REGISTER_NATIVES(filesystem)
|
||||
{"GetFileTime", sm_GetFileTime},
|
||||
{"LogToOpenFile", sm_LogToOpenFile},
|
||||
{"LogToOpenFileEx", sm_LogToOpenFileEx},
|
||||
{"ReadFile", sm_ReadFile},
|
||||
{"ReadFileString", sm_ReadFileString},
|
||||
{"WriteFile", sm_WriteFile},
|
||||
{"WriteFileString", sm_WriteFileString},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
@ -158,6 +158,112 @@ native bool:DeleteFile(const String:path[]);
|
||||
*/
|
||||
native bool:ReadFileLine(Handle:hndl, String:buffer[], maxlength);
|
||||
|
||||
/**
|
||||
* Reads binary data from a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param items Array to store each item read.
|
||||
* @param num_items Number of items to read into the array.
|
||||
* @param size Size of each element, in bytes, to be read.
|
||||
* Valid sizes are 1, 2, or 4.
|
||||
* @return Number of elements read, or -1 on error.
|
||||
*/
|
||||
native ReadFile(Handle:hndl, items[], num_items, size);
|
||||
|
||||
/**
|
||||
* Reads a UTF8 or ANSI string from a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param buffer Buffer to store the string.
|
||||
* @param max_size Maximum size of the string buffer.
|
||||
* @param stop If true, reading will stop once max_size-1 bytes have
|
||||
* been read. If false, reading will stop once a NUL
|
||||
* terminator is reached. The buffer will simply be
|
||||
* terminated in either case, the difference is in how
|
||||
* the far the file position is changed.
|
||||
* @return Number of characters written to the buffer, or -1
|
||||
* if an error was encountered.
|
||||
* @error Invalid Handle, or read_count > max_size.
|
||||
*/
|
||||
native ReadFileString(Handle:hndl, String:buffer[], max_size, read_count=-1);
|
||||
|
||||
/**
|
||||
* Writes binary data to a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param items Array of items to write. The data is read directly.
|
||||
* That is, in 1 or 2-byte mode, the lower byte(s) in
|
||||
* each cell are used directly, rather than performing
|
||||
* any casts from a 4-byte number to a smaller number.
|
||||
* @param num_items Number of items in the array.
|
||||
* @param size Size of each item in the array in bytes.
|
||||
* Valid sizes are 1, 2, or 4.
|
||||
* @return True on success, false on error.
|
||||
*/
|
||||
native bool:WriteFile(Handle:hndl, const items[], num_items, size);
|
||||
|
||||
/**
|
||||
* Writes a binary string to a file.
|
||||
*
|
||||
* @param hndl Handle to th efile.
|
||||
* @param buffer String to write.
|
||||
* @param term True to append NUL terminator, false otherwise.
|
||||
* @return True on success, false on error.
|
||||
*/
|
||||
native bool:WriteFileString(Handle:hndl, const String:buffer[], bool:term);
|
||||
|
||||
/**
|
||||
* Writes a line of text to a text file. A newline is automatically appended.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:WriteFileLine(Handle:hndl, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Reads a single binary cell from a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param data Variable to store the data read.
|
||||
* @param size Size of the data to read in bytes. Valid
|
||||
* sizes are 1, 2, or 4 bytes.
|
||||
* @return Number of elements read (max 1), or -1 on error.
|
||||
*/
|
||||
stock ReadFileCell(Handle:hndl, &data, size)
|
||||
{
|
||||
new array[1], ret;
|
||||
|
||||
if ((ret = ReadFile(hndl, array, 1, size)) == 1)
|
||||
{
|
||||
data = array[0];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a single binary cell to a file.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param data Cell to write to the file.
|
||||
* @param size Size of the data to read in bytes. Valid
|
||||
* sizes are 1, 2, or 4 bytes. If the size
|
||||
* is less than 4 bytes, the data is truncated
|
||||
* rather than casted. That is, only the lower
|
||||
* bits will be read.
|
||||
* @return True on success, false on error.
|
||||
*/
|
||||
stock bool:WriteFileCell(Handle:hndl, data, size)
|
||||
{
|
||||
new array[1];
|
||||
|
||||
array[0] = data;
|
||||
|
||||
return WriteFile(hndl, array, 1, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the end of file has been reached.
|
||||
*
|
||||
@ -171,10 +277,10 @@ native bool:IsEndOfFile(Handle:file);
|
||||
*
|
||||
* @param file Handle to the file.
|
||||
* @param position Position relative to what is specified in whence.
|
||||
* @param whence Look at the SEEK_* definitions.
|
||||
* @param where SEEK_ constant value of where to see from.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:FileSeek(Handle:file, position, whence);
|
||||
native bool:FileSeek(Handle:file, position, where);
|
||||
|
||||
/**
|
||||
* Get current position in the file.
|
||||
@ -235,17 +341,6 @@ native FlushFile(Handle:file);
|
||||
*/
|
||||
native bool:RemoveDir(const String:path[]);
|
||||
|
||||
/**
|
||||
* Writes a line of text in a file.
|
||||
* @note This native will append the newline character.
|
||||
*
|
||||
* @param hndl Handle to the file.
|
||||
* @param format Formatting rules.
|
||||
* @param ... Variable number of format parameters.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
native bool:WriteFileLine(Handle:hndl, const String:format[], any:...);
|
||||
|
||||
/**
|
||||
* Returns a file timestamp as a unix timestamp.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user