/** @file Implementation of various string and line routines Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
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 http://opensource.org/licenses/bsd-license.php 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 "HexEditor.h" extern BOOLEAN HEditorMouseAction; VOID HEditorClearLine ( IN UINTN Row ) /*++ Routine Description: Clear line at Row Arguments: Row -- row number to be cleared ( start from 1 ) Returns: EFI_SUCCESS --*/ { CHAR16 Line[200]; UINTN Index; UINTN Limit; UINTN StartCol; if (HEditorMouseAction) { Limit = 3 * 0x10; StartCol = 10; } else { Limit = HMainEditor.ScreenSize.Column; StartCol = 1; } // // prepare a blank line // for (Index = 0; Index < Limit; Index++) { Line[Index] = ' '; } if (Row == HMainEditor.ScreenSize.Row && Limit == HMainEditor.ScreenSize.Column) { // // if '\0' is still at position 80, it will cause first line error // Line[Limit - 1] = '\0'; } else { Line[Limit] = '\0'; } // // print out the blank line // ShellPrintEx ((INT32)StartCol - 1, (INT32)Row - 1, Line); } HEFI_EDITOR_LINE * HLineDup ( IN HEFI_EDITOR_LINE *Src ) /*++ Routine Description: Duplicate a line Arguments: Src -- line to be duplicated Returns: NULL -- wrong Not NULL -- line created --*/ { HEFI_EDITOR_LINE *Dest; // // allocate for the line structure // Dest = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE)); if (Dest == NULL) { return NULL; } Dest->Signature = EFI_EDITOR_LINE_LIST; Dest->Size = Src->Size; CopyMem (Dest->Buffer, Src->Buffer, 0x10); Dest->Link = Src->Link; return Dest; } VOID HLineFree ( IN HEFI_EDITOR_LINE *Src ) /*++ Routine Description: Free a line and it's internal buffer Arguments: Src -- line to be freed Returns: None --*/ { if (Src == NULL) { return ; } SHELL_FREE_NON_NULL (Src); } HEFI_EDITOR_LINE * _HLineAdvance ( IN UINTN Count ) /*++ Routine Description: Advance to the next Count lines Arguments: Count -- line number to advance Returns: NULL -- wrong Not NULL -- line after advance --*/ { UINTN Index; HEFI_EDITOR_LINE *Line; Line = HMainEditor.BufferImage->CurrentLine; if (Line == NULL) { return NULL; } for (Index = 0; Index < Count; Index++) { // // if already last line // if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead) { return NULL; } Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); } return Line; } HEFI_EDITOR_LINE * _HLineRetreat ( IN UINTN Count ) /*++ Routine Description: Retreat to the previous Count lines Arguments: Count -- line number to retreat Returns: NULL -- wrong Not NULL -- line after retreat --*/ { UINTN Index; HEFI_EDITOR_LINE *Line; Line = HMainEditor.BufferImage->CurrentLine; if (Line == NULL) { return NULL; } for (Index = 0; Index < Count; Index++) { // // already the first line // if (Line->Link.BackLink == HMainEditor.BufferImage->ListHead) { return NULL; } Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); } return Line; } HEFI_EDITOR_LINE * HMoveLine ( IN INTN Count ) /*++ Routine Description: Advance/Retreat lines Arguments: Count -- line number to advance/retreat >0 : advance <0: retreat Returns: NULL -- wrong Not NULL -- line after advance --*/ { HEFI_EDITOR_LINE *Line; UINTN AbsCount; // // difference with MoveCurrentLine // just return Line // do not set currentline to Line // if (Count <= 0) { AbsCount = -Count; Line = _HLineRetreat (AbsCount); } else { Line = _HLineAdvance (Count); } return Line; } HEFI_EDITOR_LINE * HMoveCurrentLine ( IN INTN Count ) /*++ Routine Description: Advance/Retreat lines and set CurrentLine in BufferImage to it Arguments: Count -- line number to advance/retreat >0 : advance <0: retreat Returns: NULL -- wrong Not NULL -- line after advance --*/ { HEFI_EDITOR_LINE *Line; UINTN AbsCount; // // <0: retreat // >0: advance // if (Count <= 0) { AbsCount = -Count; Line = _HLineRetreat (AbsCount); } else { Line = _HLineAdvance (Count); } if (Line == NULL) { return NULL; } HMainEditor.BufferImage->CurrentLine = Line; return Line; } EFI_STATUS HFreeLines ( IN LIST_ENTRY *ListHead, IN HEFI_EDITOR_LINE *Lines ) /*++ Routine Description: Free all the lines in HBufferImage Fields affected: Lines CurrentLine NumLines ListHead Arguments: ListHead - The list head Lines - The lines Returns: EFI_SUCCESS --*/ { LIST_ENTRY *Link; HEFI_EDITOR_LINE *Line; // // release all the lines // if (Lines != NULL) { Line = Lines; Link = &(Line->Link); do { Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); Link = Link->ForwardLink; HLineFree (Line); } while (Link != ListHead); } ListHead->ForwardLink = ListHead; ListHead->BackLink = ListHead; return EFI_SUCCESS; } UINTN HStrStr ( IN CHAR16 *Str, IN CHAR16 *Pat ) /*++ Routine Description: Search Pat in Str Arguments: Str -- mother string Pat -- search pattern Returns: 0 : not found >= 1 : found position + 1 --*/ { INTN *Failure; INTN i; INTN j; INTN Lenp; INTN Lens; // // this function copies from some lib // Lenp = StrLen (Pat); Lens = StrLen (Str); Failure = AllocateZeroPool (Lenp * sizeof (INTN)); Failure[0] = -1; for (j = 1; j < Lenp; j++) { i = Failure[j - 1]; while ((Pat[j] != Pat[i + 1]) && (i >= 0)) { i = Failure[i]; } if (Pat[j] == Pat[i + 1]) { Failure[j] = i + 1; } else { Failure[j] = -1; } } i = 0; j = 0; while (i < Lens && j < Lenp) { if (Str[i] == Pat[j]) { i++; j++; } else if (j == 0) { i++; } else { j = Failure[j - 1] + 1; } } FreePool (Failure); // // 0: not found // >=1 : found position + 1 // return ((j == Lenp) ? (i - Lenp) : -1) + 1; } INT32 HGetTextX ( IN INT32 GuidX ) { INT32 Gap; HMainEditor.MouseAccumulatorX += GuidX; Gap = (HMainEditor.MouseAccumulatorX * (INT32) HMainEditor.ScreenSize.Column) / (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionX); HMainEditor.MouseAccumulatorX = (HMainEditor.MouseAccumulatorX * (INT32) HMainEditor.ScreenSize.Column) % (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionX); HMainEditor.MouseAccumulatorX = HMainEditor.MouseAccumulatorX / (INT32) HMainEditor.ScreenSize.Column; return Gap; } INT32 HGetTextY ( IN INT32 GuidY ) { INT32 Gap; HMainEditor.MouseAccumulatorY += GuidY; Gap = (HMainEditor.MouseAccumulatorY * (INT32) HMainEditor.ScreenSize.Row) / (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionY); HMainEditor.MouseAccumulatorY = (HMainEditor.MouseAccumulatorY * (INT32) HMainEditor.ScreenSize.Row) % (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionY); HMainEditor.MouseAccumulatorY = HMainEditor.MouseAccumulatorY / (INT32) HMainEditor.ScreenSize.Row; return Gap; } EFI_STATUS HXtoi ( IN CHAR16 *Str, OUT UINTN *Value ) /*++ Routine Description: convert hex string to uint Arguments: Str - The string Value - The value Returns: --*/ { UINT64 u; CHAR16 c; UINTN Size; Size = sizeof (UINTN); // // skip leading white space // while (*Str && *Str == ' ') { Str += 1; } if (StrLen (Str) > Size * 2) { return EFI_LOAD_ERROR; } // // convert hex digits // u = 0; c = *Str; while (c) { c = *Str; Str++; if (c == 0) { break; } // // not valid char // if (!((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9') || (c == '\0'))) { return EFI_LOAD_ERROR; } if (c >= 'a' && c <= 'f') { c -= 'a' - 'A'; } if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) { u = LShiftU64 (u, 4) + (c - (c >= 'A' ? 'A' - 10 : '0')); } else { // // '\0' // break; } } *Value = (UINTN) u; return EFI_SUCCESS; }