/** @file
Implements filebuffer interface functions.
Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "TextEditor.h"
#include <Guid/FileSystemInfo.h>
#include <Library/FileHandleLib.h>
//
// for basic initialization of FileBuffer
//
NULL,
NULL,
NULL,
0,
{
0,
0
},
{
0,
0
},
{
0,
0
},
{
0,
0
},
TRUE,
};
//
// the whole edit area needs to be refreshed
//
//
// only the current line in edit area needs to be refresh
//
extern BOOLEAN EditorMouseAction;
/**
Initialization function for FileBuffer.
@param EFI_SUCCESS The initialization was successful.
@param EFI_LOAD_ERROR A default name could not be created.
@param EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
)
{
//
// basically initialize the FileBuffer
//
//
// set default FileName
//
return EFI_LOAD_ERROR;
}
return EFI_OUT_OF_RESOURCES;
}
return EFI_SUCCESS;
}
/**
Backup function for FileBuffer. Only backup the following items:
File Name, Type, ReadOnly, Modified
Insert Mode
This is for making the file buffer refresh as few as possible.
@retval EFI_SUCCESS The backup operation was successful.
**/
)
{
FileBufferBackupVar.FileName = StrnCatGrow (&FileBufferBackupVar.FileName, NULL, FileBuffer.FileName, 0);
return EFI_SUCCESS;
}
/**
Advance to the next Count lines
@param[in] Count The line number to advance by.
@param[in] CurrentLine The pointer to the current line structure.
@param[in] LineList The pointer to the linked list of lines.
@retval NULL There was an error.
@return The line structure after the advance.
**/
)
{
return NULL;
}
//
// if already last line
//
return NULL;
}
}
return ((EFI_EDITOR_LINE *)Line);
}
/**
Retreat to the previous Count lines.
@param[in] Count The line number to retreat by.
@param[in] CurrentLine The pointer to the current line structure.
@param[in] LineList The pointer to the linked list of lines.
@retval NULL There was an error.
@return The line structure after the retreat.
**/
)
{
return NULL;
}
//
// already the first line
//
return NULL;
}
}
return ((EFI_EDITOR_LINE *)Line);
}
/**
>0 : advance
<0 : retreat
@retval NULL An error occured.
**/
MoveLine (
)
{
//
// if < 0, then retreat
// if > 0, the advance
//
if (Count <= 0) {
Line = InternalEditorMiscLineRetreat (AbsCount,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead);
} else {
Line = InternalEditorMiscLineAdvance ((UINTN)Count,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead);
}
return Line;
}
/**
Function to update the 'screen' to display the mouse position.
@retval EFI_SUCCESS The backup operation was successful.
**/
)
{
//
// variable initialization
//
if (MainEditor.MouseSupported) {
if (FileBufferMouseNeedRefresh) {
//
// if mouse position not moved and only mouse action
// so do not need to refresh mouse position
//
&& EditorMouseAction) {
return EFI_SUCCESS;
}
//
// backup the old screen attributes
//
//
// clear the old mouse position
//
HasCharacter = TRUE;
} else {
}
}
L" "
);
if (HasCharacter) {
L"%c",
);
}
//
// set the new mouse position
//
//
// clear the old mouse position
//
HasCharacter = TRUE;
} else {
}
}
L" "
);
if (HasCharacter) {
L"%c",
);
}
//
// end of HasCharacter
//
}
//
// end of MouseNeedRefresh
//
}
//
// end of MouseSupported
//
return EFI_SUCCESS;
}
/**
Free all the lines in FileBuffer
Fields affected:
Lines
CurrentLine
NumLines
ListHead
@retval EFI_SUCCESS The operation was successful.
**/
)
{
//
// free all the lines
//
do {
//
// free line's buffer and line itself
//
}
//
// clean the line list related structure
//
FileBuffer.NumLines = 0;
return EFI_SUCCESS;
}
/**
Cleanup function for FileBuffer.
@retval EFI_SUCCESS The cleanup was successful.
**/
)
{
//
// free all the lines
//
Status = FileBufferFreeLines ();
return Status;
}
/**
Print a line specified by Line on a row specified by Row of the screen.
@param[in] Line The line to print.
@param[in] Row The row on the screen to print onto (begin from 1).
@retval EFI_SUCCESS The printing was successful.
**/
)
{
//
// print start from correct character
//
Limit = 0;
}
}
0,
L"%s",
);
return EFI_SUCCESS;
}
/**
Set the cursor position according to FileBuffer.DisplayPosition.
@retval EFI_SUCCESS The operation was successful.
**/
)
{
//
// set cursor position
//
));
}
/**
Refresh the screen with whats in the buffer.
@retval EFI_SUCCESS The refresh was successful.
@retval EFI_LOAD_ERROR There was an error finding what to write.
**/
)
{
//
// if it's the first time after editor launch, so should refresh
//
if (!EditorFirst) {
//
// no definite required refresh
// and file position displayed on screen has not been changed
//
if (!FileBufferNeedRefresh &&
) {
return EFI_SUCCESS;
}
}
//
// only need to refresh current line
//
) {
EditorClearLine (FileBuffer.DisplayPosition.Row, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row);
);
} else {
//
// the whole edit area need refresh
//
//
// no line
//
return EFI_SUCCESS;
}
//
// get the first line that will be displayed
//
return EFI_LOAD_ERROR;
}
Row = 2;
do {
//
// print line at row
//
Row++;
//
// while not file end and not screen full
//
Row++;
}
}
return EFI_SUCCESS;
}
/**
Create a new line and append it to the line list.
Fields affected:
NumLines
Lines
@retval NULL The create line failed.
@return The line created.
**/
)
{
//
// allocate a line structure
//
return NULL;
}
//
// initialize the structure
//
//
// initial buffer of the line is "\0"
//
return NULL;
}
//
// insert the line into line list
//
FileBuffer.Lines = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
}
return Line;
}
/**
Set FileName field in FileBuffer.
@param Str The file name to set.
@retval EFI_SUCCESS The filename was successfully set.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
@retval EFI_INVALID_PARAMETER Str is not a valid filename.
**/
)
{
//
// Verify the parameters
//
if (!IsValidFileName(Str)) {
return (EFI_INVALID_PARAMETER);
}
//
// free the old file name
//
//
// Allocate and set the new name
//
return EFI_OUT_OF_RESOURCES;
}
return EFI_SUCCESS;
}
/**
Free the existing file lines and reset the modified flag.
@retval EFI_SUCCESS The operation was successful.
**/
)
{
//
// free all the lines
//
return EFI_SUCCESS;
}
/**
Read a file from disk into the FileBuffer.
@param[in] FileName The filename to read.
@param[in] Recover TRUE if is for recover mode, no information printouts.
@retval EFI_SUCCESS The load was successful.
@retval EFI_LOAD_ERROR The load failed.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
@retval EFI_INVALID_PARAMETER FileName is a directory.
**/
)
{
LoopVar1 = 0;
FileSize = 0;
FileHandle = NULL;
CreateFile = FALSE;
//
// in this function, when you return error ( except EFI_OUT_OF_RESOURCES )
// you should set status string via StatusBarSetStatusString(L"blah")
// since this function maybe called before the editorhandleinput loop
// so any error will cause editor return
// so if you want to print the error status
// you should set the status string
//
//
// try to open the file
//
CreateFile = FALSE;
if (FileHandle == NULL) {
StatusBarSetStatusString (L"Disk Error");
return EFI_LOAD_ERROR;
}
StatusBarSetStatusString (L"Directory Can Not Be Edited");
return EFI_INVALID_PARAMETER;
}
} else {
}
//
// get file size
//
} else if (Status == EFI_NOT_FOUND) {
//
// file not exists. add create and try again
//
Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
if (Status == EFI_WRITE_PROTECTED ||
Status == EFI_ACCESS_DENIED ||
Status == EFI_NO_MEDIA ||
) {
StatusBarSetStatusString (L"Access Denied");
} else if (Status == EFI_DEVICE_ERROR || Status == EFI_VOLUME_CORRUPTED || Status == EFI_VOLUME_FULL) {
StatusBarSetStatusString (L"Disk Error");
} else {
StatusBarSetStatusString (L"Invalid File Name or Current-working-directory");
}
return Status;
} else {
//
// it worked. now delete it and move on with the name (now validated)
//
if (Status == EFI_WARN_DELETE_FAILURE) {
}
FileHandle = NULL;
StatusBarSetStatusString (L"Access Denied");
return Status;
}
}
//
// file doesn't exist, so set CreateFile to TRUE
//
CreateFile = TRUE;
//
// all the check ends
// so now begin to set file name, free lines
//
}
//
// free the old lines
//
FileBufferFree ();
}
//
// the file exists
//
if (!CreateFile) {
//
// allocate buffer to read file
//
return EFI_OUT_OF_RESOURCES;
}
//
// read file into Buffer
//
FileHandle = NULL;
StatusBarSetStatusString (L"Read File Failed");
return EFI_LOAD_ERROR;
}
//
// nothing in this file
//
if (FileSize == 0) {
//
// since has no head, so only can be an ASCII file
//
goto Done;
}
if (FileSize < 2) {
//
// size < Unicode file header, so only can be ASCII file
//
} else {
//
// Unicode file
//
//
// Unicode file's size should be even
//
if ((FileSize % 2) != 0) {
StatusBarSetStatusString (L"File Format Wrong");
return EFI_LOAD_ERROR;
}
FileSize /= 2;
//
// pass this 0xff and 0xfe
//
FileSize--;
} else {
}
//
// end of AsciiBuffer ==
//
}
//
// end of FileSize < 2
// all the check ends
// so now begin to set file name, free lines
//
}
//
// free the old lines
//
FileBufferFree ();
//
// parse file content line by line
//
//
// has LF following
//
}
}
break;
//
// has CR following
//
}
}
break;
}
} else {
//
// has LF following
//
}
}
break;
//
// has CR following
//
}
}
break;
}
}
//
// endif == ASCII
//
}
//
// end of for LineSize
//
// if the type is wrong, then exit
//
if (Type == NewLineTypeUnknown) {
//
// Now if Type is NewLineTypeUnknown, it should be file end
//
}
//
// create a new line
//
Line = FileBufferCreateLine ();
return EFI_OUT_OF_RESOURCES;
}
//
// calculate file length
//
//
// Unicode and one CHAR_NULL
//
return EFI_OUT_OF_RESOURCES;
}
//
// copy this line to Line->Buffer
//
} else {
}
LoopVar1++;
}
//
// LoopVar1 now points to where CHAR_CARRIAGE_RETURN or CHAR_LINEFEED;
//
LoopVar1++;
}
//
// last character is a return, SO create a new line
//
if (((Type == NewLineTypeCarriageReturnLineFeed || Type == NewLineTypeLineFeedCarriageReturn) && LineSizeBackup == FileSize - 2) ||
((Type == NewLineTypeLineFeed || Type == NewLineTypeCarriageReturn) && LineSizeBackup == FileSize - 1)
) {
Line = FileBufferCreateLine ();
return EFI_OUT_OF_RESOURCES;
}
}
//
// end of if
//
}
//
// end of LoopVar1
//
}
//
// end of if CreateFile
//
Done:
if (!Recover) {
if (UnicodeBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
}
/*
//
// check whether we have fs?: in filename
//
LoopVar1 = 0;
FSMappingPtr = NULL;
while (FileName[LoopVar1] != 0) {
if (FileName[LoopVar1] == L':') {
FSMappingPtr = &FileName[LoopVar1];
break;
}
LoopVar1++;
}
if (FSMappingPtr == NULL) {
CurDir = ShellGetCurrentDir (NULL);
} else {
LoopVar1 = 0;
LoopVar2 = 0;
while (FileName[LoopVar1] != 0) {
if (FileName[LoopVar1] == L':') {
break;
}
FSMapping[LoopVar2++] = FileName[LoopVar1];
LoopVar1++;
}
FSMapping[LoopVar2] = 0;
CurDir = ShellGetCurrentDir (FSMapping);
}
if (CurDir != NULL) {
for (LoopVar1 = 0; LoopVar1 < StrLen (CurDir) && CurDir[LoopVar1] != ':'; LoopVar1++);
CurDir[LoopVar1] = 0;
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ShellGetMap (CurDir);
FreePool (CurDir);
} else {
return EFI_LOAD_ERROR;
}
Status = LibDevicePathToInterface (
&gEfiSimpleFileSystemProtocolGuid,
DevicePath,
(VOID **) &Vol
);
if (EFI_ERROR (Status)) {
return EFI_LOAD_ERROR;
}
Status = Vol->OpenVolume (Vol, &RootFs);
if (EFI_ERROR (Status)) {
return EFI_LOAD_ERROR;
}
//
// Get volume information of file system
//
Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + 100;
VolumeInfo = (EFI_FILE_SYSTEM_INFO *) AllocateZeroPool (Size);
Status = RootFs->GetInfo (RootFs, &gEfiFileSystemInfoGuid, &Size, VolumeInfo);
if (EFI_ERROR (Status)) {
RootFs->Close (RootFs);
return EFI_LOAD_ERROR;
}
if (VolumeInfo->ReadOnly) {
StatusBarSetStatusString (L"WARNING: Volume Read Only");
}
FreePool (VolumeInfo);
RootFs->Close (RootFs);
}
//
*/
//
// has line
//
if (FileBuffer.Lines != 0) {
FileBuffer.CurrentLine = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
} else {
//
// create a dummy line
//
Line = FileBufferCreateLine ();
return EFI_OUT_OF_RESOURCES;
}
}
return EFI_SUCCESS;
}
/**
According to FileBuffer.NewLineType & FileBuffer.FileType,
get the return buffer and size.
@param[in] Type The type of line.
@param[out] Buffer The buffer to fill.
@param[out] Size The amount of the buffer used on return.
**/
)
{
//
// give new line buffer,
// and will judge unicode or ascii
//
NewLineSize = 0;
//
// not legal new line type
//
if (Type != NewLineTypeLineFeed && Type != NewLineTypeCarriageReturn && Type != NewLineTypeCarriageReturnLineFeed && Type != NewLineTypeLineFeedCarriageReturn) {
*Size = 0;
return ;
}
//
// use_cr: give 0x0d
//
if (Type == NewLineTypeCarriageReturn) {
Buffer[0] = 0x0d;
Buffer[1] = 0;
NewLineSize = 2;
} else {
Buffer[0] = 0x0d;
NewLineSize = 1;
}
*Size = NewLineSize;
return ;
}
//
// use_lf: give 0x0a
//
if (Type == NewLineTypeLineFeed) {
Buffer[0] = 0x0a;
Buffer[1] = 0;
NewLineSize = 2;
} else {
Buffer[0] = 0x0a;
NewLineSize = 1;
}
*Size = NewLineSize;
return ;
}
//
// use_crlf: give 0x0d 0x0a
//
if (Type == NewLineTypeCarriageReturnLineFeed) {
Buffer[0] = 0x0d;
Buffer[1] = 0;
Buffer[3] = 0;
NewLineSize = 4;
} else {
Buffer[0] = 0x0d;
NewLineSize = 2;
}
*Size = NewLineSize;
return ;
}
//
// use_lfcr: give 0x0a 0x0d
//
if (Type == NewLineTypeLineFeedCarriageReturn) {
Buffer[0] = 0x0a;
Buffer[1] = 0;
Buffer[3] = 0;
NewLineSize = 4;
} else {
Buffer[0] = 0x0a;
NewLineSize = 2;
}
*Size = NewLineSize;
return ;
}
}
/**
Change a Unicode string to an ASCII string.
@param[in] UStr The Unicode string.
@param[in] Length The maximum size of AStr.
@param[out] AStr ASCII string to pass out.
@return The actuall length.
**/
)
{
//
// just buffer copy, not character copy
//
}
return Index;
}
/**
Save lines in FileBuffer to disk
@param[in] FileName The file name for writing.
@retval EFI_SUCCESS Data was written.
@retval EFI_LOAD_ERROR
@retval EFI_OUT_OF_RESOURCES There were not enough resources to write the file.
**/
)
{
//
// 2M
//
Length = 0;
//
// 2M
//
TotalSize = 0x200000;
Attribute = 0;
//
// if is the old file
//
//
// file has not been modified
//
if (!FileBuffer.FileModified) {
return EFI_SUCCESS;
}
//
// if file is read-only, set error
//
if (FileBuffer.ReadOnly) {
StatusBarSetStatusString (L"Read Only File Can Not Be Saved");
return EFI_SUCCESS;
}
}
StatusBarSetStatusString (L"Directory Can Not Be Saved");
return EFI_LOAD_ERROR;
}
}
//
// if file exits, so delete it
//
StatusBarSetStatusString (L"Write File Failed");
return EFI_LOAD_ERROR;
}
}
Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, Attribute);
StatusBarSetStatusString (L"Create File Failed");
return EFI_LOAD_ERROR;
}
//
// if file is Unicode file, write Unicode header to it.
//
Length = 2;
return EFI_LOAD_ERROR;
}
}
return EFI_OUT_OF_RESOURCES;
}
//
// write all the lines back to disk
//
NumLines = 0;
for (Link = FileBuffer.ListHead->ForwardLink; Link != FileBuffer.ListHead; Link = Link->ForwardLink) {
}
//
// newline character is at most 4 bytes ( two Unicode characters )
//
Length = 4;
} else {
}
//
// end if FileTypeAscii
//
}
//
// no cache room left, so write cache to disk
//
return EFI_LOAD_ERROR;
}
}
} else {
}
//
// end if FileTypeAscii
//
}
//
// end of if Line -> Buffer != NULL && Line -> Size != 0
//
// if not the last line , write return buffer to disk
//
Ptr += NewLineSize;
LeftSize -= NewLineSize;
}
NumLines++;
}
return EFI_LOAD_ERROR;
}
}
//
// set status string
//
return EFI_OUT_OF_RESOURCES;
}
//
// now everything is ready , you can set the new file name to filebuffer
//
if (FileName != NULL && FileBuffer.FileName != NULL && StrCmp (FileName, FileBuffer.FileName) != 0) {
//
// not the same
//
return EFI_OUT_OF_RESOURCES;
}
}
return EFI_SUCCESS;
}
/**
Scroll cursor to left 1 character position.
@retval EFI_SUCCESS The operation was successful.
**/
)
{
//
// if already at start of this line, so move to the end of previous line
//
if (FCol <= 1) {
//
// has previous line
//
FRow--;
} else {
return EFI_SUCCESS;
}
} else {
//
// if not at start of this line, just move to previous column
//
FCol--;
}
return EFI_SUCCESS;
}
/**
Delete a char in line
@param[in, out] Line The line to delete in.
@param[in] Pos Position to delete the char at ( start from 0 ).
**/
)
{
//
// move the latter characters front
//
}
}
/**
Concatenate Src into Dest.
@param[in, out] Dest Destination string
@param[in] Src Src String.
**/
LineCat (
)
{
//
// concatenate the two strings
//
return ;
}
//
// put str to dest->buffer
//
}
/**
Delete the previous character.
@retval EFI_SUCCESS The delete was successful.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
)
{
//
// the first column
//
if (FileColumn == 1) {
//
// the first row
//
return EFI_SUCCESS;
}
//
// concatenate this line with previous line
//
return EFI_OUT_OF_RESOURCES;
}
//
// remove End from line list
//
} else {
//
// just delete the previous character
//
}
if (!FileBuffer.FileModified) {
}
return EFI_SUCCESS;
}
/**
Add a return into line at current position.
@retval EFI_SUCCESS The insetrion of the character was successful.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
)
{
return EFI_OUT_OF_RESOURCES;
}
return EFI_OUT_OF_RESOURCES;
}
//
// UNICODE + CHAR_NULL
//
return EFI_OUT_OF_RESOURCES;
}
}
}
//
// increase NumLines
//
//
// insert it into the correct position of line list
//
//
// move cursor to the start of next line
//
Col = 1;
//
// set file is modified
//
if (!FileBuffer.FileModified) {
}
return EFI_SUCCESS;
}
/**
Delete current character from current line. This is the effect caused
by the 'del' key.
@retval EFI_SUCCESS
**/
)
{
//
// the last column
//
//
// the last line
//
return EFI_SUCCESS;
}
//
// since last character,
// so will add the next line to this line
//
return EFI_OUT_OF_RESOURCES;
}
} else {
//
// just delete current character
//
}
if (!FileBuffer.FileModified) {
}
return EFI_SUCCESS;
}
/**
Scroll cursor to right 1 character.
@retval EFI_SUCCESS The operation was successful.
**/
)
{
return EFI_SUCCESS;
}
//
// if already at end of this line, scroll it to the start of next line
//
//
// has next line
//
FRow++;
FCol = 1;
} else {
return EFI_SUCCESS;
}
} else {
//
// if not at end of this line, just move to next column
//
FCol++;
}
return EFI_SUCCESS;
}
/**
Insert a char into line
@param[in] Line The line to insert into.
@param[in] Char The char to insert.
@param[in] Pos The position to insert the char at ( start from 0 ).
@param[in] StrSize The current string size ( include CHAR_NULL ),unit is Unicode character.
@return The new string size ( include CHAR_NULL ) ( unit is Unicode character ).
**/
)
{
//
// do not have free space
//
return 0;
}
}
//
// move the later part of the string one character right
//
TempStringPtr = Str;
}
//
// insert char into it.
//
return StrSize + 1;
}
/**
Add a character to the current line.
@param[in] Char The Character to input.
@retval EFI_SUCCESS The input was succesful.
**/
)
{
//
// only needs to refresh current line
//
//
// when is insert mode, or cursor is at end of this line,
// so insert this character
// or replace the character.
//
} else {
}
//
// move cursor to right
//
if (!FileBuffer.FileModified) {
}
return EFI_SUCCESS;
}
/**
Handles inputs from characters (ASCII key + Backspace + return)
@param[in] Char The input character.
@retval EFI_SUCCESS The operation was successful.
@retval EFI_LOAD_ERROR There was an error.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
)
{
switch (Char) {
case CHAR_NULL:
break;
case CHAR_BACKSPACE:
Status = FileBufferDoBackspace ();
break;
case CHAR_TAB:
//
// Tabs are ignored
//
break;
case CHAR_LINEFEED:
case CHAR_CARRIAGE_RETURN:
Status = FileBufferDoReturn ();
break;
default:
//
// DEAL WITH ASCII CHAR, filter out thing like ctrl+f
//
} else {
}
break;
}
return Status;
}
/**
Scroll cursor to the next line.
@retval EFI_SUCCESS The operation was successful.
**/
)
{
return EFI_SUCCESS;
}
//
// has next line
//
FRow++;
//
// if the next line is not that long, so move to end of next line
//
}
} else {
return EFI_SUCCESS;
}
return EFI_SUCCESS;
}
/**
Scroll the cursor to previous line.
@retval EFI_SUCCESS The operation was successful.
**/
)
{
//
// has previous line
//
FRow--;
//
// if previous line is not that long, so move to the end of previous line
//
}
} else {
return EFI_SUCCESS;
}
return EFI_SUCCESS;
}
/**
Scroll cursor to next page.
@retval EFI_SUCCESS The operation wa successful.
**/
)
{
//
// has next page
//
} else {
//
// MOVE CURSOR TO LAST LINE
//
}
//
// get correct line
//
//
// if that line, is not that long, so move to the end of that line
//
}
return EFI_SUCCESS;
}
/**
Scroll cursor to previous screen.
@retval EFI_SUCCESS The operation was successful.
**/
)
{
//
// has previous page
//
} else {
//
// the first line of file will displayed on the first line of screen
//
}
//
// get correct line
//
//
// if that line is not that long, so move to the end of that line
//
}
return EFI_SUCCESS;
}
/**
Scroll cursor to end of the current line.
@retval EFI_SUCCESS The operation was successful.
**/
)
{
//
// goto the last column of the line
//
return EFI_SUCCESS;
}
/**
Dispatch input to different handler
@param[in] Key The input key. One of:
ASCII KEY
Return
INS
@retval EFI_SUCCESS The dispatch was done successfully.
@retval EFI_LOAD_ERROR The dispatch was not successful.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
)
{
//
// ordinary key input
//
case SCAN_NULL:
if (!FileBuffer.ReadOnly) {
} else {
}
break;
//
// up arrow
//
case SCAN_UP:
Status = FileBufferScrollUp ();
break;
//
// down arrow
//
case SCAN_DOWN:
Status = FileBufferScrollDown ();
break;
//
// right arrow
//
case SCAN_RIGHT:
Status = FileBufferScrollRight ();
break;
//
// left arrow
//
case SCAN_LEFT:
Status = FileBufferScrollLeft ();
break;
//
// page up
//
case SCAN_PAGE_UP:
Status = FileBufferPageUp ();
break;
//
// page down
//
case SCAN_PAGE_DOWN:
Status = FileBufferPageDown ();
break;
//
// delete
//
case SCAN_DELETE:
if (!FileBuffer.ReadOnly) {
Status = FileBufferDoDelete ();
} else {
}
break;
//
// home
//
case SCAN_HOME:
break;
//
// end
//
case SCAN_END:
Status = FileBufferEnd ();
break;
//
// insert
//
case SCAN_INSERT:
break;
default:
break;
}
return Status;
}
/**
Check user specified FileRow is above current screen.
@param[in] FileRow The row of file position ( start from 1 ).
@retval TRUE It is above the current screen.
@retval FALSE It is not above the current screen.
**/
)
{
//
// if is to the above of the screen
//
return TRUE;
}
return FALSE;
}
/**
Check user specified FileRow is under current screen.
@param[in] FileRow The row of file position ( start from 1 ).
@retval TRUE It is under the current screen.
@retval FALSE It is not under the current screen.
**/
)
{
//
// if is to the under of the screen
//
return TRUE;
}
return FALSE;
}
/**
Check user specified FileCol is left to current screen.
@param[in] FileCol The column of file position ( start from 1 ).
@retval TRUE It is to the left.
@retval FALSE It is not to the left.
**/
)
{
//
// if is to the left of the screen
//
return TRUE;
}
return FALSE;
}
/**
Check user specified FileCol is right to current screen.
@param[in] FileCol The column of file position ( start from 1 ).
@retval TRUE It is to the right.
@retval FALSE It is not to the right.
**/
)
{
//
// if is to the right of the screen
//
return TRUE;
}
return FALSE;
}
/**
>0 : advance
<0: retreat
@retval NULL An error occured.
**/
)
{
if (Count <= 0) {
Line = InternalEditorMiscLineRetreat (AbsCount,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead);
} else {
Line = InternalEditorMiscLineAdvance ((UINTN)Count,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead);
}
return NULL;
}
return Line;
}
/**
According to cursor's file position, adjust screen display
@param[in] NewFilePosRow The row of file position ( start from 1 ).
@param[in] NewFilePosCol The column of file position ( start from 1 ).
**/
)
{
//
// CALCULATE gap between current file position and new file position
//
//
// if is below current screen
//
if (Under) {
//
// display row will be unchanged
//
} else {
if (Above) {
//
// has enough above line, so display row unchanged
// not has enough above lines, so the first line is at the
// first display line
//
}
} else {
//
// in current screen
//
if (RowGap < 0) {
} else {
}
}
}
FileBuffer.LowVisibleRange.Row = FileBuffer.FilePosition.Row - (FileBuffer.DisplayPosition.Row - 2);
//
// if right to current screen
//
if (Right) {
//
// display column will be changed to end
//
} else {
if (Left) {
//
// has enough left characters , so display row unchanged
// not has enough left characters,
// so the first character is at the first display column
//
}
} else {
//
// in current screen
//
if (ColGap < 0) {
} else {
}
}
}
FileBuffer.LowVisibleRange.Column = FileBuffer.FilePosition.Column - (FileBuffer.DisplayPosition.Column - 1);
//
// let CurrentLine point to correct line;
//
}
/**
Cut current line out and return a pointer to it.
@param[out] CutLine Upon a successful return pointer to the pointer to
the allocated cut line.
@retval EFI_SUCCESS The cut was successful.
@retval EFI_NOT_FOUND There was no selection to cut.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
)
{
if (FileBuffer.ReadOnly) {
StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
return EFI_SUCCESS;
}
//
// if is the last dummy line, SO CAN not cut
//
//
// last line
//
) {
//
// LAST LINE AND NOTHING ON THIS LINE, SO CUT NOTHING
//
StatusBarSetStatusString (L"Nothing to Cut");
return EFI_NOT_FOUND;
}
//
// if is the last line, so create a dummy line
//
//
// last line
// create a new line
//
NewLine = FileBufferCreateLine ();
return EFI_OUT_OF_RESOURCES;
}
}
Col = 1;
//
// move home
//
Link,
);
FileBuffer.Lines = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
return EFI_SUCCESS;
}
/**
Paste a line into line list.
@retval EFI_SUCCESS The paste was successful.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
)
{
//
// if nothing is on clip board
// then do nothing
//
return EFI_SUCCESS;
}
//
// read only file can not be pasted on
//
if (FileBuffer.ReadOnly) {
StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
return EFI_SUCCESS;
}
return EFI_OUT_OF_RESOURCES;
}
//
// insert it above current line
//
FileBuffer.Lines = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
Col = 1;
//
// move home
//
//
// after paste, set some value so that refresh knows to do something
//
return EFI_SUCCESS;
}
/**
Search string from current position on in file
@param[in] Str The search string.
@param[in] Offset The offset from current position.
@retval EFI_SUCCESS The operation was successful.
@retval EFI_NOT_FOUND The string Str was not found.
**/
)
{
Column = 0;
Position = 0;
//
// search if in current line
//
//
// the end
//
}
}
//
// found
//
if (Found) {
} else {
//
// not found so find through next lines
//
// Position = StrStr (Line->Buffer, Str);
}
if (Found) {
//
// found
//
break;
}
Row++;
}
} else {
}
}
if (!Found) {
return EFI_NOT_FOUND;
}
//
// call refresh to fresh edit area,
// because the outer may loop to find multiply occurrence of this string
//
return EFI_SUCCESS;
}
/**
Replace SearchLen characters from current position on with Replace.
This will modify the current buffer at the current position.
@param[in] Replace The string to replace.
@param[in] SearchLen Search string's length.
@retval EFI_SUCCESS The operation was successful.
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
)
{
//
// include CHAR_NULL
//
if (ReplaceLen > SearchLen) {
//
// do not have the enough space
//
2 * OldSize,
2 * NewSize,
);
}
return EFI_OUT_OF_RESOURCES;
}
//
// the end CHAR_NULL character;
//
//
// keep the latter part
//
for (Index = 0; Index < (FileBuffer.CurrentLine->Size - FileBuffer.FilePosition.Column - SearchLen + 2); Index++) {
Buffer--;
}
//
// set replace into it
//
}
}
if (ReplaceLen < SearchLen) {
}
Buffer += ReplaceLen;
//
// set replace into it
//
for (Index = 0; Index < (FileBuffer.CurrentLine->Size - FileBuffer.FilePosition.Column - ReplaceLen + 2); Index++) {
Buffer++;
}
}
if (ReplaceLen == SearchLen) {
}
}
MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);
return EFI_SUCCESS;
}
/**
Move the mouse cursor position.
@param[in] TextX The new x-coordinate.
@param[in] TextY The new y-coordinate.
**/
)
{
//
// TextX and TextY is mouse movement data returned by mouse driver
// This function will change it to MousePosition
//
//
// get absolute value
//
if (TextX >= 0) {
CoordinateX += TextX;
} else {
if (CoordinateX >= AbsX) {
CoordinateX -= AbsX;
} else {
CoordinateX = 0;
}
}
if (TextY >= 0) {
CoordinateY += TextY;
} else {
if (CoordinateY >= AbsY) {
CoordinateY -= AbsY;
} else {
CoordinateY = 0;
}
}
//
// check whether new mouse column position is beyond screen
// if not, adjust it
//
} else if (CoordinateX < 1) {
}
//
// check whether new mouse row position is beyond screen
// if not, adjust it
//
} else if (CoordinateY < 2) {
}
}
/**
Search and replace operation.
@param[in] SearchStr The string to search for.
@param[in] ReplaceStr The string to replace with.
@param[in] Offset The column to start at.
**/
)
{
}
//
// found
//
if (ReplaceLen > SearchLen) {
//
// include CHAR_NULL
//
//
// do not have the enough space
//
2 * OldSize,
2 * NewSize,
);
}
return EFI_OUT_OF_RESOURCES;
}
//
// the end CHAR_NULL character;
//
//
// keep the latter part
//
Buffer--;
}
} else if (ReplaceLen < SearchLen){
Buffer++;
}
} else {
}
//
// set replace into it
//
}
Column += ReplaceLen;
} else {
//
// not found
//
Column = 0;
}
}
//
// call refresh to fresh edit area
//
return EFI_SUCCESS;
}
/**
Set the modified state to TRUE.
**/
)
{
}