go3270

package module
v0.9.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 2, 2026 License: MIT Imports: 10 Imported by: 3

README

Go 3270 Server Library

PkgGoDev

This library allows you to write Go servers for tn3270 clients by building 3270 data streams from fields and processing the client's response to receive the attention keys and field values entered by users.

Project status: This library has been used by a small number of projects, and I believe the overall functionality is sound and relatively bug-free. Feedback is appreciated. At this point, I will try not to make breaking changes to the API, but I have not yet declared the library to be at v1.0, so I make no promises.

Usage

See the example folders for quick demonstrations of using the library:

  • example1 uses the lower-level function ShowScreenOpts().
  • example2 uses a higher-level convenience function HandleScreen().
  • example3 demonstrates updating the client's 3270 display while waiting for a response by using an update thread and a waiting response thread.
  • example4 demonstrates the RunTransactions() approach to handing control from one screen to the next. This is the recommended way to build applications using go3270.
  • example5 demonstrates support for larger-than-default (24x80) terminal sizes.

For larger applications, I recommend using the RunTransactions() function to serve as the driver for your application. You can implement transaction functions which pass control from one transaction to another. example4 demonstrates a "larger" application that uses this approach.

For an example of a complete application that handles multiple user sessions, adapts to different screen sizes, and with a nice written explanation of how the application is built, Moshix has created a Minesweeper game using go3270 to serve as a resource for the community to learn from.

Here's a video introducing the library as well.

Code page support

When clients connect, the NegotiateTelnet() function returns an implementation of the DevInfo interface. That interface has a DevInfo.Codepage() method, which returns an implementation of the Codepage interface for the detected client code page if known and supported (nil otherwise). The ScreenOpts structure you provide to the ShowScreenOpts() function has a Codepage field, which is where you provide DevInfo.Codepage() to ensure the UTF-8–EBCDIC translation is correct for the particular client. If ScreenOpts.Codepage is nil (either because you don't set it, or if DevInfo.Codepage() returns nil), then go3270 will use its global default code page for that interaction with the client. The global default is the CP1047 code page.

All of the examples under this repository demonstrate the correct handling of code pages -- the DevInfo is remembered from the telnet negotiation, and DevInfo.Codepage() is passed to all screen send and receive calls.

You may change the global code page default by calling the SetCodepage() function during your application initialization (this should be set before you use the library for handling any client connections; this is a global setting, not a per-connection setting). SetCodepage() accepts a Codepage interface, which provides methods to encode Go UTF-8 strings to EBCDIC, and decode EBCDIC byte slices to Go UTF-8 strings.

go3270 currently provides the following codepage functions, covering all single-byte code pages supported by x3270 v4.3ga10:

  • Codepage037()
  • Codepage273()
  • Codepage275()
  • Codepage277()
  • Codepage278()
  • Codepage280()
  • Codepage284()
  • Codepage285()
  • Codepage297()
  • Codepage424()
  • Codepage500()
  • Codepage803()
  • Codepage870()
  • Codepage871()
  • Codepage875()
  • Codepage880()
  • Codepage924()
  • Codepage1026()
  • Codepage1047()
  • Codepage1140()
  • Codepage1141()
  • Codepage1142()
  • Codepage1143()
  • Codepage1144()
  • Codepage1145()
  • Codepage1146()
  • Codepage1147()
  • Codepage1148()
  • Codepage1149()
  • Codepage1160()

Additionally, the default x3270 family code page (closest to CP 1047, with with ^ and ¬ swapped back to where they are in CP 37), CodepageBracket(). (Note that x3270 does not report a different code page ID between CP37 and "bracket". Since "bracket" is the default code page for x3270, go3270 will assume that if the client is in the x3270 family and the codepage is 37, "bracket" is the correct code page to use.)

If there are other standard EBCDIC code pages that you would like support for, let me know.

To configure go3270 to use one of the codepages by default, you may do something like:

import (
    "github.com/racingmars/go3270"
)

func init() {
    go3270.SetCodepage(go3270.Codepage1047())
}

With the new codepage detection support, you shouldn't typically rely on the default codepage: you should always pass the DevInfo.Codepage() value to the ShowScreenOpts() function or as the last optional argument to the HandleScreen() or HandleScreenAlt() functions. The global default should only be a fallback if the client code page isn't detected correctly.

Additionally, most characters from the "graphic escape" code page 310 are supported in all of the go3270-provided codepage implementations. Correct display on the client will depend on its support of graphic escape and correct characters being available in its font. The DevInfo.SupportsGE() function returns a boolean indicating that the client supports the graphic escape alternate code page. Use the corresponding Unicode characters in your Go UTF-8 strings and they will be sent as the EBCDIC two-byte sequence of 0x08 followed by the position in code page 310. GE sequences are also processed on incoming field values.

3270 information

I started learning about 3270 data streams from Tommy Sprinkle's tutorial. The tn3270 telnet negotiation is gleaned from RFC 1576: TN3270 Current Practices, RFC 1041: Telnet 3270 Regime Option, and RFC 854: Telnet Protocol Specification. The IANA maintains a useful reference of telnet option numbers. The reference I use for 3270 data streams is the 1981 version from IBM.

License

This library is licensed under the MIT license; see the file LICENSE for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Debug io.Writer

Enable go3270 library debugging by setting Debug to an io.Writer. Disable debugging by setting it to nil (the default value).

View Source
var ErrNo3270 = errors.New("couldn't negotiate telnet options for tn3270")

ErrNo3270 indicates that the telnet client did not respond properly to the options negotiation that are expected for a tn3270 client.

View Source
var ErrTelnetError = errors.New("telnet or 3270 protocol error")

ErrTelnetError indicates an unexpected response was encountered in the telnet protocol.

View Source
var ErrUnknownTerminal = errors.New("unknown terminal type")

ErrUnknownTerminal indicates the client did not identify itself as an IBM-3277, 3278, 3279, or IBM-DYNAMIC model. All modern tn3270 clients should report as IBM-3278 models or IBM-DYNAMIC.

Functions

func AIDtoString

func AIDtoString(aid AID) string

AIDtoString returns a string representation of an AID key name.

func RunTransactions

func RunTransactions(conn net.Conn, dev DevInfo, initial Tx,
	data any) error

RunTransactions begins running transaction functions, starting with the initial transaction, until a transaction eventually returns nil for the next transaction, or until a transaction function returns a non-nil error value. data (which may be nil, if the initial transaction does not require data) is passed in as the data to the initial transaction.

dev is the DevInfo of the connected client, as obtained from NegotiateTelnet(). It is safe to pass a nil DevInfo, in which case all transactions will only be able to operate with the default 24x80 screen size.

func SetCodepage added in v0.9.8

func SetCodepage(cs Codepage)

SetCodepage sets the codepage/character set that go3270 uses. This is a global setting, so if you're expecting clients to be configured to use a character set other than go3270's default, cp1047, you should probably set this during your application initialization and then leave it unchanged after. This is _not_ a per-connection setting.

For per-client codepage, set the ScreenOpts.Codepage field in the calls to ShowScreenOpts() or the codepage argument to HandleScreen() and HandleScreenAlt().

func ShowScreenNoResponse deprecated

func ShowScreenNoResponse(screen Screen, values map[string]string,
	crow, ccol int, conn net.Conn) error

Deprecated: use ShowScreenOpts with ScreenOpts.NoResponse = true.

NOTE: this deprecated function is NOT codepage-aware. The global code page set by SetCodepage will always be used.

func UnNegotiateTelnet

func UnNegotiateTelnet(conn net.Conn, timeout time.Duration) error

UnNegotiateTelnet will naively (e.g. not checking client responses) attempt to restore the telnet options state to what it was before NegotiateTelnet() was called.

Types

type AID

type AID byte

AID is an Action ID character.

const (
	AIDNone  AID = 0x60
	AIDEnter AID = 0x7D
	AIDPF1   AID = 0xF1
	AIDPF2   AID = 0xF2
	AIDPF3   AID = 0xF3
	AIDPF4   AID = 0xF4
	AIDPF5   AID = 0xF5
	AIDPF6   AID = 0xF6
	AIDPF7   AID = 0xF7
	AIDPF8   AID = 0xF8
	AIDPF9   AID = 0xF9
	AIDPF10  AID = 0x7A
	AIDPF11  AID = 0x7B
	AIDPF12  AID = 0x7C
	AIDPF13  AID = 0xC1
	AIDPF14  AID = 0xC2
	AIDPF15  AID = 0xC3
	AIDPF16  AID = 0xC4
	AIDPF17  AID = 0xC5
	AIDPF18  AID = 0xC6
	AIDPF19  AID = 0xC7
	AIDPF20  AID = 0xC8
	AIDPF21  AID = 0xC9
	AIDPF22  AID = 0x4A
	AIDPF23  AID = 0x4B
	AIDPF24  AID = 0x4C
	AIDPA1   AID = 0x6C
	AIDPA2   AID = 0x6E
	AIDPA3   AID = 0x6B
	AIDClear AID = 0x6D
)

type Codepage added in v0.9.8

type Codepage interface {
	// Decode converts a slice of EBCDIC bytes into a UTF-8 string.
	Decode(e []byte) string

	// Encode converts a UTF-8 string into a slice of EBCDIC bytes.
	Encode(s string) []byte

	// ID returns the name of this codepage. Usually a numeric string like
	// "037" or "1047", but could also be a name such as "bracket" if IBM has
	// not assigned a number to the particular codepage.
	ID() string
}

Implementations of Codepage provide EBCDIC<->UTF-8 translation. By default, go3270 is configured to use CP 1047. You may alternatively set a different codepage using the SetCodepage() function during your application initialization.

func Codepage037 added in v0.9.8

func Codepage037() Codepage

func Codepage1026 added in v0.9.10

func Codepage1026() Codepage

func Codepage1047 added in v0.9.8

func Codepage1047() Codepage

func Codepage1140 added in v0.9.8

func Codepage1140() Codepage

func Codepage1141 added in v0.9.10

func Codepage1141() Codepage

func Codepage1142 added in v0.9.10

func Codepage1142() Codepage

func Codepage1143 added in v0.9.10

func Codepage1143() Codepage

func Codepage1144 added in v0.9.10

func Codepage1144() Codepage

func Codepage1145 added in v0.9.10

func Codepage1145() Codepage

func Codepage1146 added in v0.9.10

func Codepage1146() Codepage

func Codepage1147 added in v0.9.10

func Codepage1147() Codepage

func Codepage1148 added in v0.9.10

func Codepage1148() Codepage

func Codepage1149 added in v0.9.10

func Codepage1149() Codepage

func Codepage1160 added in v0.9.10

func Codepage1160() Codepage

func Codepage273 added in v0.9.10

func Codepage273() Codepage

func Codepage275 added in v0.9.10

func Codepage275() Codepage

func Codepage277 added in v0.9.10

func Codepage277() Codepage

func Codepage278 added in v0.9.10

func Codepage278() Codepage

func Codepage280 added in v0.9.10

func Codepage280() Codepage

func Codepage284 added in v0.9.10

func Codepage284() Codepage

func Codepage285 added in v0.9.10

func Codepage285() Codepage

func Codepage297 added in v0.9.10

func Codepage297() Codepage

func Codepage424 added in v0.9.10

func Codepage424() Codepage

func Codepage500 added in v0.9.10

func Codepage500() Codepage

func Codepage803 added in v0.9.10

func Codepage803() Codepage

func Codepage870 added in v0.9.10

func Codepage870() Codepage

func Codepage871 added in v0.9.10

func Codepage871() Codepage

func Codepage875 added in v0.9.10

func Codepage875() Codepage

func Codepage880 added in v0.9.10

func Codepage880() Codepage

func Codepage924 added in v0.9.8

func Codepage924() Codepage

func CodepageBracket added in v0.9.9

func CodepageBracket() Codepage

type Color

type Color byte

Color is a 3270 extended field attribute color value

const (
	DefaultColor Color = 0
	Blue         Color = 0xf1
	Red          Color = 0xf2
	Pink         Color = 0xf3
	Green        Color = 0xf4
	Turquoise    Color = 0xf5
	Yellow       Color = 0xf6
	White        Color = 0xf7
)

The valid 3270 colors

type DevInfo

type DevInfo interface {
	// AltDimensions returns the number or rows and columns on the alternate
	// screen size.
	AltDimensions() (rows, cols int)

	// TerminalType reports the terminal-provided identification string. All
	// modern tn3270 clients will report one of the IBM-3278 models (-2, -3,
	// -4, or -5), or IBM-DYNAMIC if the alternate screen size isn't one of
	// the fixed sizes of the 3278 models. This string is purely
	// informational; the actual size of the alternate screen is available
	// from AltDimensions().
	TerminalType() string

	// Codepage is the Codepage interface that implements the EBCDIC
	// translation for the detected code page for the terminal, if supported.
	// This may be nil if the client code page is unknown. Whenever calling
	// the screen functions, always pass the value returned by this Codepage()
	// function in the ScreenOpts (nil is allowed to default to the global
	// default codepage).
	Codepage() Codepage

	// SupportsGE returns true if the client indicated it supports graphic
	// escape to code page 310.
	SupportsGE() bool
	// contains filtered or unexported methods
}

DevInfo provides information about the terminal that is connected.

3270 terminals operate at a default screen size of 24 rows that are 80 columns wide. The normal "Write/Erase" datastream command always writes to the default 24x80 buffer. But some terminals support more rows and/or columns, and the alternate sized buffer may be written to with the "Write/Erase Alternate" command.

func NegotiateTelnet

func NegotiateTelnet(conn net.Conn) (DevInfo, error)

NegotiateTelnet will negotiate the options necessary for tn3270 on a new telnet connection, conn.

type Field

type Field struct {
	// Row is the row, 0-based, that the field attribute character should
	// begin at. When using the standard screen of 24 rows, Row must be 0-23.
	// When writing to the alternate screen, Row may be up to 1 less than the
	// number of rows on the screen.
	Row int

	// Col is the column, 0-based, that the field attribute character should
	// begin at. When using the standard screen of 80 columns, Col must be
	// 0-79. When writing to the alternate screen, Col may be up to 1 less
	// than the number of columns on the screen.
	Col int

	// Text is the content of the field to display.
	Content string

	// PositionOnly will use a Set Buffer Address (SBA) command to move the
	// cursor to the position, but not insert a new attribute byte. The only
	// properties of the Field that will apply if PositionOnly is true are:
	// Row, Col, Content, Name. Others will be silently ignored.
	PositionOnly bool

	// Write allows the user to edit the value of the field.
	Write bool

	// Autoskip causes protected (Write = false) fields to automatically be
	// skipped and the cursor should move to the next field upon encountering
	// this field. Autoskip is ignored on fields with Write = true.
	Autoskip bool

	// Intense indicates this field should be displayed with high intensity.
	Intense bool

	// Hidden indicates the field content should not be displayed (e.g. a
	// password input field).
	Hidden bool

	// NumericOnly indicates that only numbers may be entered into the field.
	// Very fiew 3270 clients support this, so you must always still validate
	// the input on the server side.
	NumericOnly bool

	// Color is the field color. The default value is the default color.
	Color Color

	// Highlighting is the highlight attribute for the field. The default value
	// is the default (i.e. no) highlighting.
	Highlighting Highlight

	// AttributeOnly will cause this "field" (which won't really be a new
	// field) to use the SA (Set Attribute) 3270 command to change the color
	// and highlighting of the text WITHOUT starting a new field. You can
	// create a field at Row 5, Column 10, with AttributeOnly true, and the
	// text will start in Roe 5, Column 10 and not skip a space to column 11
	// like a new field would when AttributeOnly is false.
	//
	// If AttributeOnly is true, the Write, Autoskip, Intense, Hidden, and
	// NumericOnly properties will have no effect. Only Highlighting and Color
	// will affect the output, and will both default to Default (e.g. default
	// highlighting and default color) if not specificed in this field.
	//
	// After using AttributeOnly to change color and highlighting, you may
	// need to explicitly use another AttributeOnly "field" to reset to
	// defaults, a regular (AttributeOnly = false) field may not end the
	// attributes. (See example1.)
	AttributeOnly bool

	// Name is the name of this field, which is used to get the user-entered
	// data. All writeable fields on a screen must have a unique name.
	// Protected fields may also have a name to populate them dynamically when
	// the screen is sent.
	Name string

	// KeepSpaces will prevent the strings.TrimSpace() function from being
	// called on the field value. Generally you want leading and trailing
	// spaces trimmed from fields in 3270 before processing, but if you are
	// building a whitespace-sensitive application, you can ask for the
	// original, un-trimmed value for a field by setting this to true.
	KeepSpaces bool
}

Field is a field on the 3270 screen.

type FieldRules

type FieldRules struct {
	// MustChange, when true, indicates that the value of the field MUST be
	// altered by the user -- if applied to a field with no starting value,
	// this makes the field a required field. If true on a field with a
	// starting value (either in the field's Content attribute, or with an
	// override in the initial values map), then the user must change
	// the value from the default.
	MustChange bool

	// ErrorText is the text displayed with the MustChange validation fails.
	// If ErrorText is the empty string, but MustValidation fails, an error
	// string will be constructed from the field name: "Please enter a valid
	// value for <fieldName>."
	ErrorText string

	// Validator is a function to validate the value the user input into the
	// field. It may be nil if no validation is required. The Validator
	// function is called *after* the MustChange logic, so if you wish to
	// fully handle validation, ensure MustChange is set to false.
	Validator Validator

	// Reset indicates that if the screen fails validation, this field should
	// always be reset to its original/default value, regardless of what the
	// user entered.
	Reset bool
}

FieldRules provides the validation rules for a particular field.

type Highlight

type Highlight byte

Highlight is a 3270 extended field attribute highlighting method

const (
	DefaultHighlight Highlight = 0
	Blink            Highlight = 0xf1
	ReverseVideo     Highlight = 0xf2
	Underscore       Highlight = 0xf4
)

The valid 3270 highlights

type Response

type Response struct {
	// Which Action ID key did the user press?
	AID AID

	// Row the cursor was on (0-based).
	Row int

	// Column the cursor was on (0-based).
	Col int

	// Field values.
	Values map[string]string
}

Response encapsulates data received from a 3270 client in response to the previously sent screen.

func HandleScreen

func HandleScreen(screen Screen, rules Rules, values map[string]string,
	pfkeys, exitkeys []AID, errorField string, crow, ccol int,
	conn net.Conn, codepage ...Codepage) (Response, error)

HandleScreen is a higher-level interface to the ShowScreen() function. HandleScreen will loop until all validation rules are satisfied, and only return when an expected AID (i.e. PF) key is pressed.

  • screen is the Screen to display (see ShowScreen()).
  • rules are the Rules to enforce: each key in the Rules map corresponds to a Field.Name in the screen array.
  • values are field values you wish to override (see ShowScreen()).
  • pfkeys and exitkeys are the AID keys that you wish to accept (that is, perform validation and return if successful) and treat as exit keys (unconditionally return).
  • errorField is the name of a field in the screen array that you wish error messages to be written in when HandleScreen loops waiting for a valid user submission.
  • crow and ccol are the initial cursor position.
  • conn is the network connection to the 3270 client.
  • codepage is an optional argument (implemented this way as a varargs argument as a hack to add this feature without breaking API backward compatability) for the codepage to use. Typically you should pass in the return value from DevInfo.Codepage() each time to get the correct codepage that was detected when the client connected. If nil, the global default code page (default 1047, but changed with the SetCodepage() function) will be used.

HandleScreen will return when the user: 1) presses a key in pfkeys AND all fields pass validation, OR 2) the user presses a key in exitkeys. In all other cases, HandleScreen will re-present the screen to the user again, possibly with an error message set in the errorField field.

For alternate screen support (larger than 24x80), use HandleScreenAlt().

func HandleScreenAlt

func HandleScreenAlt(screen Screen, rules Rules, values map[string]string,
	pfkeys, exitkeys []AID, errorField string, crow, ccol int,
	conn net.Conn, dev DevInfo, codepage ...Codepage) (Response, error)

HandleScreenAlt is identical to HandleScreen, but writes to the "alternate" screen size provided by dev. To write a non-24-by-80 screen, use this HandleScreenAlt function with a non-nil dev. If dev is nil, the behavior is identical to HandleScreen, which is limited to 24x80 and will set larger terminals to the default 24x80 mode.

func ShowScreen deprecated

func ShowScreen(screen Screen, values map[string]string, crow, ccol int,
	conn net.Conn) (Response, error)

Deprecated: use ShowScreenOpts with default/empty ScreenOpts.

NOTE: this deprecated function is NOT codepage-aware. The global code page set by SetCodepage will always be used.

func ShowScreenOpts

func ShowScreenOpts(screen Screen,
	values map[string]string, conn net.Conn,
	opts ScreenOpts) (Response, error)

ShowScreenOpts writes the 3270 datastream for the screen, with the provided ScreenOpts, to a connection.

Fields that aren't valid (e.g. outside of the screen size) are silently ignored. If a named field has an entry in the values map, the content of the field from the values map is used INSTEAD OF the Field struct's Content field. The values map may be nil if no overrides are needed.

If opts.NoClear is false, the client screen will be cleared before writing the new screen, and the cursor will be repositioned to the values in opts.CursorRow and opts.CursorCol. If opts.NoClear is true, the screen will NOT be cleared, the cursor will NOT be repositioned, and the new screen will be overlayed over the current state of the client screen.

If opts.NoResponse is false, ShowScreenOpts will block before returning, waiting for data from the client and returning the Response. If opts.NoResponse is true, ShowScreenOpts will immediately return after sending the datastream and the Response will be empty.

If using from multiple threads -- one to block and wait for a response, and another to send screens with NoResponse and/or NoClear, be aware that if you change the input fields on screen after the initial blocking call is made, the response fields will not line up correctly and end up being invalid. That is to say, while waiting for a response, don't perform other actions from another thread that could layout the user input fields differently.

type Rules

type Rules map[string]FieldRules

Rules is a map of field names (strings) to FieldRules structs. Each field for which you wish validation to occur must appear in the map. Fields not in the map will not have any input validation performed.

type Screen

type Screen []Field

Screen is an array of Fields which compose a complete 3270 screen. No checking is performed for lack of overlapping fields, unique field names, fields out of bounds of the screen size (these will simply be omitted from the datastream), etc.

type ScreenOpts

type ScreenOpts struct {
	// If AltScreen is non-nil, the screen will be written to the "alternate"
	// screen size, which is the non-default (24x80) screen dimensions that
	// the terminal supports (although for many terminals, the alternate
	// screen is still just 24x80). If AltScreen is nil, the default (24x80)
	// mode will be used. Never switch between AltScreen and normal screen
	// (e.g. AltScreen = nil) unless NoClear is false. (That is, switching
	// between default and alternate screen size or back requires a screen
	// clear at the same time.) When AltScreen is nil, field positions in the
	// screen must be within the 24x80 screen (so rows 0-23 and cols 0-79),
	// when AltScreen is present, the field positions must be within the
	// dimensions of the DevInfo.AltDimensions() values.
	AltScreen DevInfo

	// Codepage is the Codepage implementation to use when sending text to the
	// client and translating incoming field text from the client. Typically
	// you should pass in the return value from DevInfo.Codepage() each time
	// to get the correct codepage that was detected when the client
	// connected. If nil, the global default code page (default 1047, but
	// changed with the SetCodepage() function) will be used. NOTE: providing
	// a DevInfo to ScreenOpts.AltScreen does _not_ automatically set this
	// value, you must set it explicitly on every call that accepts
	// ScreenOpts.
	Codepage Codepage

	// NoResponse will draw the screen and immediately return, without
	// waiting for any input data from the remote client.
	NoResponse bool

	// NoClear will send the data stream to the remote client without
	// clearing the screen first. Existing data will be overlayed with
	// the current screen.
	NoClear bool

	// CursorRow sets the row (0-indexed) to position the cursor after sending
	// the screen, when NoClear is false. When AltScreen is nil, maximum value
	// is 23; otherwise, maximum is 1 less than the number of rows in
	// AltScreen.
	CursorRow int

	// CursorCol sets the column (0-indexed) to position the cursor after
	// sending the screen, when NoClear is false. When AltScreen is nil,
	// maximum value is 79; otherwise, maximum is 1 less than the number of
	// columns in AltScreen.
	CursorCol int

	// PostSendCallback is a function that, if non-nil, will be called after
	// go3270 sends the datastream to the client, but before it blocks to
	// read the response (if NoResponse is true, the callback will still be
	// called before returning). If the function returns an error, then
	// the ShowScreenOpts() function will return the error instead of a
	// response. The value of CallbackData will be passed as the argument to
	// the function.
	PostSendCallback func(any) error

	// CallbackData is passed as the argument to the PostSendCallback
	// function.
	CallbackData any
}

ScreenOpts are the options that callers may set when sending a screen to the 3270 client.

type Tx

type Tx func(conn net.Conn, dev DevInfo, data any) (
	next Tx, newdata any, err error)

Tx is a function that serves as one transaction in a go3270 application. The Tx function is called with the network connection to the client, the DevInfo for use with alternate screen writes, and a "data" value provided by the previous transaction. Tx functions return the next transaction to run (or nil to indicate the RunTransactions() function should terminate), the data to pass into the next transaction, and any error. If the error is non-nil, the RunTransactions() function will terminate and return the err. A non-nil error is _not_ passed between transactions, it terminates transaction processing.

type Validator

type Validator func(input string) bool

Validator is a type that represents a function which can perform field input validation. The function is passed a string, input, and returns true if the input is valid or false if the not.

var IsInteger Validator = func(input string) bool {
	input = strings.TrimSpace(input)
	return isIntegerRegexp.MatchString(input)
}

IsInteger is a Validator that returns true if, after spaces are trimmed from the beginning and end if the string, the value is an integer (including negative numbers and 0).

var NonBlank Validator = func(input string) bool {
	return !(strings.TrimSpace(input) == "")
}

NonBlank is a Validator that returns true if, after spaces are trimmed from the beginning and end of the string, the value is not empty.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL