mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Merge pull request #1130 from disarray2077/fix_ide_textwrites
Fix issues with the methods for writing files
This commit is contained in:
commit
3cd94cbc8e
11 changed files with 142 additions and 63 deletions
|
@ -295,11 +295,13 @@ namespace Beefy
|
|||
|
||||
public static Result<void> WriteTextFile(StringView path, StringView text)
|
||||
{
|
||||
var stream = scope FileStream();
|
||||
if (stream.Create(path) case .Err)
|
||||
{
|
||||
var stream = scope UnbufferedFileStream();
|
||||
if (stream.Open(path, .OpenOrCreate, .Write) case .Err)
|
||||
return .Err;
|
||||
}
|
||||
|
||||
if (stream.SetLength(text.Length) case .Err)
|
||||
return .Err;
|
||||
|
||||
if (stream.WriteStrUnsized(text) case .Err)
|
||||
return .Err;
|
||||
|
||||
|
|
|
@ -88,14 +88,12 @@ namespace System.IO
|
|||
data.RemoveFromStart((.)spaceLeft);
|
||||
}
|
||||
|
||||
if (mWriteDirtyPos >= 0)
|
||||
Try!(Flush());
|
||||
Try!(Flush());
|
||||
|
||||
if ((mBuffer == null) || (data.Length > mBuffer.Count))
|
||||
{
|
||||
var result = TryReadUnderlying(mPos, data);
|
||||
if (result case .Ok(let len))
|
||||
mPos += len;
|
||||
let len = Try!(TryReadUnderlying(mPos, data));
|
||||
mPos += len;
|
||||
return (.)(mPos - readStart);
|
||||
}
|
||||
|
||||
|
@ -148,10 +146,9 @@ namespace System.IO
|
|||
|
||||
if ((mBuffer == null) || (data.Length > mBuffer.Count))
|
||||
{
|
||||
var result = TryWriteUnderlying(mPos, data);
|
||||
if (result case .Ok(let len))
|
||||
mPos += len;
|
||||
writeCount += result;
|
||||
let len = Try!(TryWriteUnderlying(mPos, data));
|
||||
mPos += len;
|
||||
writeCount += len;
|
||||
return writeCount;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace System.IO
|
|||
|
||||
public static Result<void> WriteAll(StringView path, Span<uint8> data, bool doAppend = false)
|
||||
{
|
||||
FileStream fs = scope FileStream();
|
||||
UnbufferedFileStream fs = scope UnbufferedFileStream();
|
||||
var result = fs.Open(path, doAppend ? .Append : .Create, .Write);
|
||||
if (result case .Err)
|
||||
return .Err;
|
||||
|
@ -76,7 +76,7 @@ namespace System.IO
|
|||
|
||||
public static Result<void> WriteAllText(StringView path, StringView text, bool doAppend = false)
|
||||
{
|
||||
FileStream fs = scope FileStream();
|
||||
UnbufferedFileStream fs = scope UnbufferedFileStream();
|
||||
var result = fs.Open(path, doAppend ? .Append : .Create, .Write);
|
||||
if (result case .Err)
|
||||
return .Err;
|
||||
|
@ -87,7 +87,7 @@ namespace System.IO
|
|||
|
||||
public static Result<void> WriteAllText(StringView path, StringView text, Encoding encoding)
|
||||
{
|
||||
FileStream fs = scope FileStream();
|
||||
UnbufferedFileStream fs = scope UnbufferedFileStream();
|
||||
|
||||
int len = encoding.GetEncodedSize(text);
|
||||
uint8* data = new uint8[len]*;
|
||||
|
|
|
@ -178,7 +178,7 @@ namespace System.IO
|
|||
case .Open:
|
||||
createKind = .OpenExisting;
|
||||
case .OpenOrCreate:
|
||||
createKind = .CreateAlways;
|
||||
createKind = .OpenAlways;
|
||||
case .Truncate:
|
||||
createKind = .CreateAlways;
|
||||
createFlags |= .Truncate;
|
||||
|
@ -235,6 +235,32 @@ namespace System.IO
|
|||
return .Err;
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
public override Result<void> SetLength(int64 length)
|
||||
{
|
||||
int64 pos = Position;
|
||||
|
||||
if (pos != length)
|
||||
Seek(length);
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
Platform.BfpFile_Truncate(mBfpFile, &result);
|
||||
if (result != .Ok)
|
||||
{
|
||||
Seek(pos);
|
||||
return .Err;
|
||||
}
|
||||
|
||||
if (pos != length)
|
||||
{
|
||||
if (pos < length)
|
||||
Seek(pos);
|
||||
else
|
||||
Seek(0, .FromEnd);
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
|
||||
class BufferedFileStream : BufferedStream
|
||||
|
@ -253,6 +279,22 @@ namespace System.IO
|
|||
}
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFileAccess.HasFlag(FileAccess.Read);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFileAccess.HasFlag(FileAccess.Write);
|
||||
}
|
||||
}
|
||||
|
||||
public this()
|
||||
{
|
||||
|
||||
|
@ -274,22 +316,6 @@ namespace System.IO
|
|||
mFileAccess = access;
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFileAccess.HasFlag(FileAccess.Read);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFileAccess.HasFlag(FileAccess.Write);
|
||||
}
|
||||
}
|
||||
|
||||
public Result<void, FileOpenError> Create(StringView path, FileAccess access = .ReadWrite, FileShare share = .None, int bufferSize = 4096, FileOptions options = .None, SecurityAttributes* secAttrs = null)
|
||||
{
|
||||
return Open(path, FileMode.Create, access, share, bufferSize, options, secAttrs);
|
||||
|
@ -337,7 +363,7 @@ namespace System.IO
|
|||
case .Open:
|
||||
createKind = .OpenExisting;
|
||||
case .OpenOrCreate:
|
||||
createKind = .CreateAlways;
|
||||
createKind = .OpenAlways;
|
||||
case .Truncate:
|
||||
createKind = .CreateAlways;
|
||||
createFlags |= .Truncate;
|
||||
|
@ -406,15 +432,20 @@ namespace System.IO
|
|||
mUnderlyingLength = Platform.BfpFile_GetFileSize(mBfpFile);
|
||||
}
|
||||
|
||||
protected Result<void> SeekUnderlying(int64 offset, Platform.BfpFileSeekKind seekKind = .Absolute)
|
||||
{
|
||||
int64 newPos = Platform.BfpFile_Seek(mBfpFile, offset, seekKind);
|
||||
Result<void> result = ((seekKind == .Absolute) && (newPos != offset)) ? .Err : .Ok;
|
||||
if (result case .Ok)
|
||||
mBfpFilePos = newPos;
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override Result<int> TryReadUnderlying(int64 pos, Span<uint8> data)
|
||||
{
|
||||
if (mBfpFilePos != pos)
|
||||
{
|
||||
int64 newPos = Platform.BfpFile_Seek(mBfpFile, pos, .Absolute);
|
||||
if (newPos != pos)
|
||||
return .Err;
|
||||
mBfpFilePos = pos;
|
||||
}
|
||||
Try!(SeekUnderlying(pos));
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, -1, &result);
|
||||
if ((result != .Ok) && (result != .PartialData))
|
||||
|
@ -426,12 +457,8 @@ namespace System.IO
|
|||
protected override Result<int> TryWriteUnderlying(int64 pos, Span<uint8> data)
|
||||
{
|
||||
if (mBfpFilePos != pos)
|
||||
{
|
||||
int64 newPos = Platform.BfpFile_Seek(mBfpFile, pos, .Absolute);
|
||||
if (newPos != pos)
|
||||
return .Err;
|
||||
mBfpFilePos = pos;
|
||||
}
|
||||
Try!(SeekUnderlying(pos));
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
int numBytesRead = Platform.BfpFile_Write(mBfpFile, data.Ptr, data.Length, -1, &result);
|
||||
if ((result != .Ok) && (result != .PartialData))
|
||||
|
@ -443,12 +470,7 @@ namespace System.IO
|
|||
public Result<int> TryRead(Span<uint8> data, int timeoutMS)
|
||||
{
|
||||
if (mBfpFilePos != mPos)
|
||||
{
|
||||
int64 newPos = Platform.BfpFile_Seek(mBfpFile, mPos, .Absolute);
|
||||
if (newPos != mPos)
|
||||
return .Err;
|
||||
mBfpFilePos = mPos;
|
||||
}
|
||||
Try!(SeekUnderlying(mPos));
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
int numBytesRead = Platform.BfpFile_Read(mBfpFile, data.Ptr, data.Length, timeoutMS, &result);
|
||||
|
@ -456,6 +478,40 @@ namespace System.IO
|
|||
return .Err;
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
public override Result<void> SetLength(int64 length)
|
||||
{
|
||||
Try!(Flush());
|
||||
|
||||
int64 pos = Position;
|
||||
|
||||
if (pos != length || pos != mBfpFilePos)
|
||||
{
|
||||
Try!(SeekUnderlying(length));
|
||||
mPos = length;
|
||||
}
|
||||
|
||||
Platform.BfpFileResult result = .Ok;
|
||||
Platform.BfpFile_Truncate(mBfpFile, &result);
|
||||
if (result != .Ok)
|
||||
{
|
||||
Try!(SeekUnderlying(pos));
|
||||
return .Err;
|
||||
}
|
||||
|
||||
mUnderlyingLength = length;
|
||||
mPos = Math.Min(pos, Length);
|
||||
|
||||
if (pos != length)
|
||||
{
|
||||
if (pos < length)
|
||||
Try!(SeekUnderlying(pos));
|
||||
else
|
||||
Try!(SeekUnderlying(0, .FromEnd));
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
|
||||
class FileStream : BufferedFileStream
|
||||
|
|
|
@ -203,6 +203,11 @@ namespace System.IO
|
|||
return .Ok;
|
||||
}
|
||||
|
||||
public virtual Result<void> SetLength(int64 length)
|
||||
{
|
||||
return .Err;
|
||||
}
|
||||
|
||||
public void Align(int alignSize)
|
||||
{
|
||||
int64 pos = Length;
|
||||
|
|
|
@ -271,6 +271,7 @@ namespace System
|
|||
CreateAlways,
|
||||
CreateIfNotExists,
|
||||
OpenExisting,
|
||||
OpenAlways,
|
||||
};
|
||||
|
||||
public enum BfpFileCreateFlags : int32
|
||||
|
@ -351,7 +352,7 @@ namespace System
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern int64 BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern void BfpFile_Truncate(BfpFile* file);
|
||||
public static extern void BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern BfpTimeStamp BfpFile_GetTime_LastWrite(char8* path);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
|
|
|
@ -219,7 +219,8 @@ void SysFileStream::SetSizeFast(int size)
|
|||
|
||||
int curPos = GetPos();
|
||||
SetPos(size);
|
||||
BfpFile_Truncate(mFile);
|
||||
BfpFileResult result = BfpFileResult_Ok;
|
||||
BfpFile_Truncate(mFile, &result);
|
||||
SetPos(curPos);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -344,6 +344,7 @@ enum BfpFileCreateKind
|
|||
BfpFileCreateKind_CreateAlways,
|
||||
BfpFileCreateKind_CreateIfNotExists,
|
||||
BfpFileCreateKind_OpenExisting,
|
||||
BfpFileCreateKind_OpenAlways
|
||||
};
|
||||
|
||||
enum BfpFileCreateFlags
|
||||
|
@ -421,7 +422,7 @@ BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Read(BfpFile* file, void* buffer, intptr
|
|||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Flush(BfpFile* file);
|
||||
BFP_EXPORT int64 BFP_CALLTYPE BfpFile_GetFileSize(BfpFile* file);
|
||||
BFP_EXPORT int64 BFP_CALLTYPE BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Truncate(BfpFile* file);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult);
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFile_GetTime_LastWrite(const char* path);
|
||||
BFP_EXPORT BfpFileAttributes BFP_CALLTYPE BfpFile_GetAttributes(const char* path, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_SetAttributes(const char* path, BfpFileAttributes attribs, BfpFileResult* outResult);
|
||||
|
|
|
@ -1858,6 +1858,10 @@ BFP_EXPORT BfpFile* BFP_CALLTYPE BfpFile_Create(const char* inName, BfpFileCreat
|
|||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// POSIX doesn't need the OpenAlways kind.
|
||||
if (createKind == BfpFileCreateKind_OpenAlways)
|
||||
createKind = BfpFileCreateKind_CreateAlways;
|
||||
|
||||
BfpFile* bfpFile = NULL;
|
||||
|
||||
|
@ -2079,13 +2083,15 @@ BFP_EXPORT int64 BFP_CALLTYPE BfpFile_Seek(BfpFile* file, int64 offset, BfpFileS
|
|||
return lseek64(file->mHandle, offset, whence);
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Truncate(BfpFile* file)
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult)
|
||||
{
|
||||
int64 curPos = (int64)lseek64(file->mHandle, 0, SEEK_CUR);
|
||||
if (ftruncate64(file->mHandle, curPos) != 0)
|
||||
{
|
||||
//TODO: Report error?
|
||||
}
|
||||
{
|
||||
OUTRESULT(BfpFileResult_UnknownError);
|
||||
return;
|
||||
}
|
||||
OUTRESULT(BfpFileResult_Ok);
|
||||
}
|
||||
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFile_GetTime_LastWrite(const char* path)
|
||||
|
|
|
@ -2741,9 +2741,13 @@ BFP_EXPORT BfpFile* BFP_CALLTYPE BfpFile_Create(const char* path, BfpFileCreateK
|
|||
creationDisposition = CREATE_ALWAYS;
|
||||
}
|
||||
else if (createKind == BfpFileCreateKind_CreateIfNotExists)
|
||||
{
|
||||
{
|
||||
creationDisposition = CREATE_NEW;
|
||||
}
|
||||
else if (createKind == BfpFileCreateKind_OpenAlways)
|
||||
{
|
||||
creationDisposition = OPEN_ALWAYS;
|
||||
}
|
||||
else
|
||||
{
|
||||
creationDisposition = OPEN_EXISTING;
|
||||
|
@ -3019,9 +3023,14 @@ BFP_EXPORT int64 BFP_CALLTYPE BfpFile_Seek(BfpFile* file, int64 offset, BfpFileS
|
|||
return newPos.QuadPart;
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Truncate(BfpFile* file)
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult)
|
||||
{
|
||||
SetEndOfFile(file->mHandle);
|
||||
if (!SetEndOfFile(file->mHandle))
|
||||
{
|
||||
OUTRESULT(BfpFileResult_UnknownError);
|
||||
return;
|
||||
}
|
||||
OUTRESULT(BfpFileResult_Ok);
|
||||
}
|
||||
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFile_GetTime_LastWrite(const char* path)
|
||||
|
|
|
@ -234,6 +234,7 @@ namespace System
|
|||
CreateAlways,
|
||||
CreateIfNotExists,
|
||||
OpenExisting,
|
||||
OpenAlways,
|
||||
};
|
||||
|
||||
public enum BfpFileCreateFlags : int32
|
||||
|
@ -303,7 +304,7 @@ namespace System
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern int64 BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern void BfpFile_Truncate(BfpFile* file);
|
||||
public static extern void BfpFile_Truncate(BfpFile* file, BfpFileResult* outResult);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
public static extern BfpTimeStamp BfpFile_GetTime_LastWrite(char8* path);
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue