📄 httpform.cxx
字号:
/* * httpform.cxx * * Forms using HTTP user interface. * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: httpform.cxx,v $ * Revision 1.31 2000/06/19 11:35:01 robertj * Fixed bug in setting current value of options in select form fields. * * Revision 1.30 1999/02/10 13:19:45 robertj * Fixed PConfig update problem when POSTing to the form. Especiall with arrays. * * Revision 1.29 1998/11/30 04:51:57 robertj * New directory structure * * Revision 1.28 1998/11/14 11:11:06 robertj * PPC GNU compiler compatibility. * * Revision 1.27 1998/10/01 09:05:11 robertj * Fixed bug in nested composite field names, array indexes not being set correctly. * * Revision 1.26 1998/09/23 06:22:11 robertj * Added open source copyright license. * * Revision 1.25 1998/08/20 05:51:06 robertj * Fixed bug where substitutions did not always occur if near end of macro block. * Improved internationalisation. Allow HTML override of strings in macros. * * Revision 1.24 1998/08/09 11:25:51 robertj * GNU C++ warning removal. * * Revision 1.23 1998/08/09 10:35:11 robertj * Changed array control so can have language override. * * Revision 1.22 1998/07/24 06:56:05 robertj * Fixed case significance problem in HTTP forms. * Improved detection of VALUE= fields with and without quotes. * * Revision 1.21 1998/03/20 03:16:43 robertj * Fixed bug in beaing able to reset a check box field. * * Revision 1.20 1998/02/03 06:26:09 robertj * Fixed propagation of inital values in arrays subfields. * Fixed problem where hidden fields were being relaced with default values from PHTTPForm. * * Revision 1.19 1998/01/26 02:49:17 robertj * GNU support. * * Revision 1.18 1998/01/26 01:51:37 robertj * Fixed uninitialised variable. * * Revision 1.17 1998/01/26 00:25:25 robertj * Major rewrite of HTTP forms management. * * Revision 1.16 1997/12/18 05:06:51 robertj * Added missing braces to kill GNU compiler warning. * * Revision 1.15 1997/10/10 10:43:43 robertj * Fixed bug in password encryption, missing string terminator. * * Revision 1.14 1997/08/28 12:48:29 robertj * Changed array fields to allow for reordering. * * Revision 1.13 1997/08/21 12:44:10 robertj * Fixed bug in HTTP form array size field. * Fixed bug where section list was only replacing first instance of macro. * * Revision 1.12 1997/08/09 07:46:52 robertj * Fixed problems with value of SELECT fields in form * * Revision 1.11 1997/08/04 10:41:13 robertj * Fixed bug in new section list page for names with special characters in them. * * Revision 1.10 1997/07/26 11:38:20 robertj * Support for overridable pages in HTTP service applications. * * Revision 1.9 1997/07/14 11:49:51 robertj * Put "Add" and "Keep" on check boxes in array fields. * * Revision 1.8 1997/07/08 13:12:29 robertj * Major HTTP form enhancements for lists and arrays of fields. * * Revision 1.7 1997/06/08 04:47:27 robertj * Adding new llist based form field. * * Revision 1.6 1997/04/12 02:07:26 robertj * Fixed boolean check boxes being more flexible on string values. * * Revision 1.5 1997/04/01 06:00:53 robertj * Changed PHTTPConfig so if section empty string, does not write PConfig parameters. * * Revision 1.4 1996/10/08 13:10:34 robertj * Fixed bug in boolean (checkbox) html forms, cannot be reset. * * Revision 1.3 1996/09/14 13:09:31 robertj * Major upgrade: * rearranged sockets to help support IPX. * added indirect channel class and moved all protocols to descend from it, * separating the protocol from the low level byte transport. * * Revision 1.2 1996/08/08 13:34:10 robertj * Removed redundent call. * * Revision 1.1 1996/06/28 12:56:20 robertj * Initial revision * */#ifdef __GNUC__#pragma implementation "httpform.h"#endif#include <ptlib.h>#include <ptclib/httpform.h>#include <ptclib/cypher.h>//////////////////////////////////////////////////////////////////////////////// PHTTPFieldPHTTPField::PHTTPField(const char * nam, const char * titl, const char * hlp) : baseName(nam), fullName(nam), title(titl != NULL ? titl : nam), help(hlp != NULL ? hlp : ""){ notInHTML = TRUE;}PObject::Comparison PHTTPField::Compare(const PObject & obj) const{ PAssert(obj.IsDescendant(PHTTPField::Class()), PInvalidCast); return fullName.Compare(((const PHTTPField &)obj).fullName);}void PHTTPField::SetName(const PString & newName){ fullName = newName;}const PHTTPField * PHTTPField::LocateName(const PString & name) const{ if (fullName == name) return this; return NULL;}void PHTTPField::SetHelp(const PString & hotLinkURL, const PString & linkText){ help = "<A HREF=\"" + hotLinkURL + "\">" + linkText + "</A>\r\n";}void PHTTPField::SetHelp(const PString & hotLinkURL, const PString & imageURL, const PString & imageText){ help = "<A HREF=\"" + hotLinkURL + "\"><IMG SRC=\"" + imageURL + "\" ALT=\"" + imageText + "\" ALIGN=absmiddle></A>\r\n";}static BOOL FindSpliceBlock(const PRegularExpression & startExpr, const PRegularExpression & endExpr, const PString & text, PINDEX offset, PINDEX & pos, PINDEX & len, PINDEX & start, PINDEX & finish){ start = finish = P_MAX_INDEX; if (!text.FindRegEx(startExpr, pos, len, offset)) return FALSE; PINDEX endpos, endlen; if (!text.FindRegEx(endExpr, endpos, endlen, pos+len)) return TRUE; start = pos + len; finish = endpos - 1; len = endpos - pos + endlen; return TRUE;}static BOOL FindSpliceBlock(const PRegularExpression & startExpr, const PString & text, PINDEX offset, PINDEX & pos, PINDEX & len, PINDEX & start, PINDEX & finish){ static PRegularExpression EndBlock("<?!--#form[ \t\r\n]+end[ \t\r\n]*-->?", PRegularExpression::Extended|PRegularExpression::IgnoreCase); return FindSpliceBlock(startExpr, EndBlock, text, offset, pos, len, start, finish);}static BOOL FindSpliceName(const PCaselessString & text, PINDEX start, PINDEX finish, PINDEX & pos, PINDEX & end){ if (text[start+1] != '!') { static PRegularExpression NameExpr("name[ \t\r\n]*=[ \t\r\n]*\"[^\"]*\"", PRegularExpression::Extended|PRegularExpression::IgnoreCase); if ((pos = text.FindRegEx(NameExpr, start)) == P_MAX_INDEX) return FALSE; if (pos >= finish) return FALSE; pos = text.Find('"', pos) + 1; end = text.Find('"', pos) - 1; } else { pos = start + 9; // Skip over the <!--#form while (isspace(text[pos])) // Skip over blanks pos++; while (pos < finish && !isspace(text[pos])) // Skip over keyword pos++; while (isspace(text[pos])) // Skip over more blanks pos++; end = text.Find("--", pos) - 1; } return end < finish;}static BOOL FindSpliceFieldName(const PString & text, PINDEX offset, PINDEX & pos, PINDEX & len, PString & name){ static PRegularExpression FieldName("<?!--#form[ \t\r\n]+[a-z0-9]+[ \t\r\n]+[^-]+[ \t\r\n]*-->?" "|" "<[a-z]+[ \t\r\n][^>]*name[ \t\r\n]*=[ \t\r\n]*\"[^\"]*\"[^>]*>", PRegularExpression::Extended|PRegularExpression::IgnoreCase); if (!text.FindRegEx(FieldName, pos, len, offset)) return FALSE; PINDEX nameStart, nameEnd; if (!FindSpliceName(text, pos, pos+len-1, nameStart, nameEnd)) return FALSE; name = text(nameStart, nameEnd); pos = nameStart; len = nameEnd - nameStart + 1; return TRUE;}static void SpliceAdjust(const PString & str, PString & text, PINDEX pos, PINDEX & len, PINDEX & finish){ text.Splice(str, pos, len); PINDEX newLen = str.GetLength(); if (finish != P_MAX_INDEX) finish += newLen - len; len = newLen;}void PHTTPField::ExpandFieldNames(PString & text, PINDEX start, PINDEX & finish) const{ PString name; PINDEX pos, len; while (start < finish && FindSpliceFieldName(text, start, pos, len, name)) { if (pos > finish) break; if (baseName == name) SpliceAdjust(fullName, text, pos, len, finish); start = pos + len; }}static BOOL FindInputValue(const PString & text, PINDEX & before, PINDEX & after){ static PRegularExpression Value("value[ \t\r\n]*=[ \t\r\n]*(\"[^\"]*\"|[^> \t\r\n]+)", PRegularExpression::Extended|PRegularExpression::IgnoreCase); PINDEX pos = text.FindRegEx(Value); if (pos == P_MAX_INDEX) return FALSE; before = text.Find('"', pos); if (before != P_MAX_INDEX) after = text.Find('"', before+1); else { before = text.Find('=', pos); while (isspace(text[before+1])) before++; after = before + 1; while (text[after] != '\0' && text[after] != '>' && !isspace(text[after])) after++; } return TRUE;}PString PHTTPField::GetHTMLInput(const PString & input) const{ PINDEX before, after; if (FindInputValue(input, before, after)) return input(0, before) + GetValue(FALSE) + input.Mid(after); return "<input value=\"" + GetValue(FALSE) + "\"" + input.Mid(6);}static void AdjustSelectOptions(PString & text, PINDEX begin, PINDEX end, const PString & myValue, PStringList & validValues, PINDEX & finishAdjust){ PINDEX start, finish; PINDEX pos = begin; PINDEX len = 0; static PRegularExpression StartOption("<[ \t\r\n]*option[^>]*>", PRegularExpression::IgnoreCase); static PRegularExpression EndOption("<[ \t\r\n]*/?option[^>]*>", PRegularExpression::Extended|PRegularExpression::IgnoreCase); while (FindSpliceBlock(StartOption, EndOption, text, pos+len, pos, len, start, finish) && pos < end) { PCaselessString option = text(pos, start-1); PINDEX before, after; if (FindInputValue(option, before, after)) { start = pos + before + 1; finish = pos + after - 1; } PINDEX selpos = option.Find("selected"); PString thisValue = text(start, finish); if (thisValue == myValue) { if (selpos == P_MAX_INDEX) { text.Splice(" selected", pos+7, 0); if (finishAdjust != P_MAX_INDEX) finishAdjust += 9; if (end != P_MAX_INDEX) end += 9; len += 9; } } else { if (validValues.GetSize() > 0) { PINDEX valid; for (valid = 0; valid < validValues.GetSize(); valid++) { if (thisValue == validValues[valid]) break; } if (valid >= validValues.GetSize()) { text.Delete(pos, len); selpos = P_MAX_INDEX; if (finishAdjust != P_MAX_INDEX) finishAdjust -= len; if (end != P_MAX_INDEX) end -= len; len = 0; } } if (selpos != P_MAX_INDEX) { selpos += pos; PINDEX sellen = 8; if (text[selpos-1] == ' ') { selpos--; sellen++; } text.Delete(selpos, sellen); if (finishAdjust != P_MAX_INDEX) finishAdjust -= sellen; if (end != P_MAX_INDEX) end -= sellen; len -= sellen; } } }}PString PHTTPField::GetHTMLSelect(const PString & selection) const{ PString text = selection; PStringList dummy1; PINDEX dummy2 = P_MAX_INDEX; AdjustSelectOptions(text, 0, P_MAX_INDEX, GetValue(FALSE), dummy1, dummy2); return text;}void PHTTPField::GetHTMLHeading(PHTML &) const{}static int SplitConfigKey(const PString & fullName, PString & section, PString & key){ if (fullName.IsEmpty()) return 0; PINDEX slash = fullName.FindLast('\\'); if (slash == 0 || slash >= fullName.GetLength()-1) { key = fullName; return 1; } section = fullName.Left(slash); key = fullName.Mid(slash+1); if (section.IsEmpty() || key.IsEmpty())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -