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;
|
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)
|
REGISTER_NATIVES(filesystem)
|
||||||
{
|
{
|
||||||
{"OpenDirectory", sm_OpenDirectory},
|
{"OpenDirectory", sm_OpenDirectory},
|
||||||
@ -664,5 +855,9 @@ REGISTER_NATIVES(filesystem)
|
|||||||
{"GetFileTime", sm_GetFileTime},
|
{"GetFileTime", sm_GetFileTime},
|
||||||
{"LogToOpenFile", sm_LogToOpenFile},
|
{"LogToOpenFile", sm_LogToOpenFile},
|
||||||
{"LogToOpenFileEx", sm_LogToOpenFileEx},
|
{"LogToOpenFileEx", sm_LogToOpenFileEx},
|
||||||
|
{"ReadFile", sm_ReadFile},
|
||||||
|
{"ReadFileString", sm_ReadFileString},
|
||||||
|
{"WriteFile", sm_WriteFile},
|
||||||
|
{"WriteFileString", sm_WriteFileString},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
@ -158,6 +158,112 @@ native bool:DeleteFile(const String:path[]);
|
|||||||
*/
|
*/
|
||||||
native bool:ReadFileLine(Handle:hndl, String:buffer[], maxlength);
|
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.
|
* 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 file Handle to the file.
|
||||||
* @param position Position relative to what is specified in whence.
|
* @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.
|
* @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.
|
* Get current position in the file.
|
||||||
@ -235,17 +341,6 @@ native FlushFile(Handle:file);
|
|||||||
*/
|
*/
|
||||||
native bool:RemoveDir(const String:path[]);
|
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.
|
* Returns a file timestamp as a unix timestamp.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user