static HeapTuple TupleParserRead(TupleParser *self, Checker *checker) { uint32 len; BULKLOAD_PROFILE(&prof_reader_parser); if (QueueRead(self->queue, &len, sizeof(uint32), false) == sizeof(uint32) && len > 0) { if (self->buflen < len) { self->buffer = repalloc(self->buffer, len); self->buflen = len; } if (QueueRead(self->queue, self->buffer, len, false) == len) { BULKLOAD_PROFILE(&prof_reader_source); self->tuple.t_len = len; self->tuple.t_data = (HeapTupleHeader) self->buffer; return &self->tuple; } } return NULL; }
// Handle a completed read on a controller void WirelessGamingReceiver::ReadComplete(void *parameter, IOReturn status, UInt32 bufferSizeRemaining) { WGRREAD *data = (WGRREAD*)parameter; bool reread = true; switch (status) { case kIOReturnOverrun: // IOLog("read - kIOReturnOverrun, clearing stall\n"); connections[data->index].controllerIn->ClearStall(); // fall through case kIOReturnSuccess: ProcessMessage(data->index, (unsigned char*)data->buffer->getBytesNoCopy(), data->buffer->getLength() - bufferSizeRemaining); break; case kIOReturnNotResponding: // IOLog("read - kIOReturnNotResponding\n"); // fall through default: reread = false; break; } int newIndex = data->index; data->buffer->release(); IOFree(data, sizeof(WGRREAD)); if (reread) QueueRead(newIndex); }
uint8 UpGetStart(uint8 dev, uint32 OutTime) { uint8 err = 0x00; int8 XMLHead[] = "<?xml version"; //=\"1.0\" encoding=\"utf-8\" ?>"; uint8 DataTemp = 0x00; uint8 Flag = 0x01; uint8 i; FILE *fp; while (Flag) { for (i = 0; i < strlen(XMLHead); i++) { while (QueueRead(&DataTemp, (void*) pQueues[dev]) != QUEUE_OK) { OSSemPend(dev, OutTime, &err); if (err != OS_ERR_NONE) { printf("[%s][%s][%d]OSSemPend err=%d\n", FILE_LINE, err); return err; } } //printf("get start string is %s\n", DataTemp); if (DataTemp == XMLHead[i]) { } else { i = 0; continue; } } Flag = 0; } printf("start fopen %s \n", gXML_Rcv_File.XMLFile[gXML_Rcv_File.writepos]); fp = fopen(gXML_Rcv_File.XMLFile[gXML_Rcv_File.writepos], "w+"); fwrite(XMLHead, 1, strlen(XMLHead), fp); //printf("gGprsRec = %s\n",XMLHead); fclose(fp); return 0; }
// --------------------------------------------------------- // CReceiver::RunL() // --------------------------------------------------------- // void CReceiver::RunL() { DEBUG("CReceiver::RunL()" ); TUint rxCount( 0 ); const TUint KMaxRxCount( 4 ); while( ( rxCount < KMaxRxCount ) && ( iDataBuffer = iParent->iCard.GetRxFrame( iFrameToFree ) ) != NULL ) { TUint8* buf = iDataBuffer->GetBuffer(); TUint32 len = iDataBuffer->GetLength(); //Save the original buf value which points //to the beginning of the Ethernet header TUint8* bufOrig = buf; DEBUG1("CReceiver::RunL() - packet length: %u", len ); if( buf && len > 0 && len <= KMaxEthernetFrameLength ) { //Now set buf point to the beginning of the Payload buf = buf + KEtherHeaderSize; len = len - KEtherHeaderSize; TPtrC8 pkt(buf, len); RMBufPacket pFrame; //Payload TRAPD( ret, pFrame.CreateL( pkt ) ); if( ret == KErrNone ) { pFrame.Pack(); iParent->iParent->Process( pFrame, bufOrig, iDataBuffer->UserPriority() ); } } iFrameToFree = iDataBuffer; ++rxCount; DEBUG1("CReceiver::RunL() - %u packet(s) processed", rxCount ); } if ( rxCount == KMaxRxCount ) { DEBUG("CReceiver::RunL() - yield"); SetActive(); TRequestStatus* status = &iStatus; User::RequestComplete( status, KErrNone ); } else { iFrameToFree = NULL; if( iParent->CardOpen() ) { QueueRead(); } } }
uint8 UpGetEnd(uint8 dev, uint32 OutTime) { uint8 err = 0x00; int8 XMLEnd[] = "</root>"; /*</test>*/ uint8 DataTemp = 0x00; uint8 Flag = 0x01; uint8 i; int j = 0; FILE *fp; while (Flag) { for (i = 0; i < strlen(XMLEnd); i++) { while (QueueRead(&DataTemp, (void*) pQueues[dev]) != QUEUE_OK) { OSSemPend(dev, OutTime, &err); if (err != OS_ERR_NONE) { printf("[%s][%s][%d]OSSemPend err=%d\n", FILE_LINE, err); return err; } } gGprsRec[j++] = DataTemp; if (j == (sizeof(gGprsRec) - 1)) { fp = fopen(gXML_Rcv_File.XMLFile[gXML_Rcv_File.writepos], "a+"); debug_info(gDebugModule[GPRS_MODULE], "xml name is %s\n", gXML_Rcv_File.XMLFile[gXML_Rcv_File.writepos]); fwrite(gGprsRec, 1, strlen(gGprsRec), fp); debug_err(gDebugModule[GPRS_MODULE], "[%s][%s][%d] strlen(gGprsRec)=%d\n", FILE_LINE, strlen(gGprsRec)); memset(gGprsRec, 0, sizeof(gGprsRec)); j = 0; fclose(fp); } if (DataTemp == XMLEnd[i]) { ; } else { i = 0; continue; } } Flag = 0; } if (j != 0) { fp = fopen(gXML_Rcv_File.XMLFile[gXML_Rcv_File.writepos], "a+"); debug_info(gDebugModule[GPRS_MODULE], "xml name is %s\n", gXML_Rcv_File.XMLFile[gXML_Rcv_File.writepos]); fwrite(gGprsRec, 1, strlen(gGprsRec), fp); debug_err(gDebugModule[GPRS_MODULE], "[%s][%s][%d] strlen(gGprsRec)=%d\n", FILE_LINE, strlen(gGprsRec)); memset(gGprsRec, 0, sizeof(gGprsRec)); j = 0; fclose(fp); } return 0; }
uint8 UpGetch(uint8 dev, uint8* data, uint16 OutTime) { uint8 err = 0x00; uint8 ret; while ((ret = QueueRead(data, (void*) pQueues[dev])) != QUEUE_OK) { OSSemPend(dev, (uint32) OutTime, &err); if (err != OS_ERR_NONE) { return err; } else { } } return 0; }
/********************************************************************************************************* ** 函数名称: UART0Putch ** 功能描述: 发送一个字节数据 ** 输 入: Data:发送的数据数据 ** 输 出:无 ** 全局变量: 无 ** 调用模块: 无 ** ** 作 者: 陈明计 ** 日 期: 2003年7月4日 **------------------------------------------------------------------------------------------------------- ** 修改人: 陈明计 ** 日 期: 2003年7月8日 **------------------------------------------------------------------------------------------------------- ** 修改人: 陈明计 ** 日 期: 2003年7月21日 **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/ void UART1Putch(uint8 Data) { uint8 temp; OS_ENTER_CRITICAL(); QueueWrite((void *)UART1SendBuf, Data); /* 数据入队 */ if ((U1LSR & 0x00000020) != 0) { /* UART0发送保持寄存器空 */ QueueRead(&temp, UART1SendBuf); /* 发送最初入队的数据 */ U1THR = temp; U1IER = U1IER | 0x02; /* 允许发送中断 */ } OS_EXIT_CRITICAL(); }
/********************************************************************************************************* ** 函数名称: UART0_Exception ** 功能描述: UART0中断服务程序 ** 输 入: 无 ** ** 输 出: 无 ** ** 全局变量: 无 ** 调用模块: QueueRead,OSSemPost ** ** 作 者: 陈明计 ** 日 期: 2003年7月4日 **------------------------------------------------------------------------------------------------------- ** 修改人: 陈明计 ** 日 期: 2003年7月21日 **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/ void UART1_Exception(void) { uint8 IIR, temp, i; OS_ENTER_CRITICAL(); while(((IIR = U1IIR) & 0x01) == 0) { /* 有中断未处理完 */ switch (IIR & 0x0e) { case 0x02: /* THRE中断 */ for (i = 0; i < UART1_FIFO_LENGTH; i++) /* 向发送FIFO填充数据 */ { if (QueueRead(&temp, UART1SendBuf) == QUEUE_OK) { U1THR = temp; } else { U1IER = U1IER & (~0x02); /* 队列空,则禁止发送中断 */ } } break; case 0x04: /* 接收数据可用 */ OSSemPost(Uart1Sem); /* 通知接收任务 */ U1IER = U1IER & (~0x01); /* 禁止接收及字符超时中断 */ break; case 0x06: /* 接收线状态 */ temp = U1LSR; break; case 0x0c: /* 字符超时指示 */ OSSemPost(Uart1Sem); /* 通知接收任务 */ U1IER = U1IER & (~0x01); /* 禁止接收及字符超时中断 */ break; default : break; } } VICVectAddr = 0; // 通知中断控制器中断结束 OS_EXIT_CRITICAL(); }
// This handles a completed asynchronous read void Xbox360Peripheral::ReadComplete(void *parameter,IOReturn status,UInt32 bufferSizeRemaining) { if (padHandler != NULL) // avoid deadlock with release { LockRequired locker(mainLock); IOReturn err; bool reread=!isInactive(); switch(status) { case kIOReturnOverrun: IOLog("read - kIOReturnOverrun, clearing stall\n"); if (inPipe != NULL) inPipe->ClearStall(); // Fall through case kIOReturnSuccess: if (inBuffer != NULL) { const XBOX360_IN_REPORT *report=(const XBOX360_IN_REPORT*)inBuffer->getBytesNoCopy(); if(((report->header.command==inReport)&&(report->header.size==sizeof(XBOX360_IN_REPORT))) || (report->header.command==0x20) || (report->header.command==0x07)) /* Xbox One */ { err = padHandler->handleReport(inBuffer, kIOHIDReportTypeInput); if(err!=kIOReturnSuccess) { IOLog("read - failed to handle report: 0x%.8x\n",err); } } } break; case kIOReturnNotResponding: IOLog("read - kIOReturnNotResponding\n"); reread=false; break; default: reread=false; break; } if(reread) QueueRead(); } }
// Start device bool WirelessGamingReceiver::start(IOService *provider) { const IOUSBConfigurationDescriptor *cd; IOUSBFindInterfaceRequest interfaceRequest; IOUSBFindEndpointRequest pipeRequest; IOUSBInterface *interface; int iConnection, iOther, i; if (!IOService::start(provider)) { // IOLog("start - superclass failed\n"); return false; } device = OSDynamicCast(IOUSBDevice, provider); if (device == NULL) { // IOLog("start - invalid provider\n"); goto fail; } // Check for configurations if (device->GetNumConfigurations() < 1) { device = NULL; // IOLog("start - device has no configurations!\n"); goto fail; } // Set configuration cd = device->GetFullConfigurationDescriptor(0); if (cd == NULL) { device = NULL; // IOLog("start - couldn't get configuration descriptor\n"); goto fail; } if (!device->open(this)) { device = NULL; // IOLog("start - failed to open device\n"); goto fail; } if (device->SetConfiguration(this, cd->bConfigurationValue, true) != kIOReturnSuccess) { // IOLog("start - unable to set configuration\n"); goto fail; } for (i = 0; i < WIRELESS_CONNECTIONS; i++) { connections[i].controller = NULL; connections[i].controllerIn = NULL; connections[i].controllerOut = NULL; connections[i].other = NULL; connections[i].otherIn = NULL; connections[i].otherOut = NULL; connections[i].inputArray = NULL; connections[i].service = NULL; connections[i].controllerStarted = false; } pipeRequest.interval = 0; pipeRequest.maxPacketSize = 0; pipeRequest.type = kUSBInterrupt; interfaceRequest.bInterfaceClass = kIOUSBFindInterfaceDontCare; interfaceRequest.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; interfaceRequest.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; interfaceRequest.bAlternateSetting = 0; interface = NULL; iConnection = 0; iOther = 0; while ((interface = device->FindNextInterface(interface, &interfaceRequest)) != NULL) { switch(interface->GetInterfaceProtocol()) { case 129: // Controller if (!interface->open(this)) { // IOLog("start: Failed to open control interface\n"); goto fail; } connections[iConnection].controller = interface; pipeRequest.direction = kUSBIn; connections[iConnection].controllerIn = interface->FindNextPipe(NULL, &pipeRequest); if (connections[iConnection].controllerIn == NULL) { // IOLog("start: Failed to open control input pipe\n"); goto fail; } else connections[iConnection].controllerIn->retain(); pipeRequest.direction = kUSBOut; connections[iConnection].controllerOut = interface->FindNextPipe(NULL, &pipeRequest); if (connections[iConnection].controllerOut == NULL) { // IOLog("start: Failed to open control output pipe\n"); goto fail; } else connections[iConnection].controllerOut->retain(); iConnection++; break; case 130: // It is a mystery if (!interface->open(this)) { // IOLog("start: Failed to open mystery interface\n"); goto fail; } connections[iOther].other = interface; pipeRequest.direction = kUSBIn; connections[iOther].otherIn = interface->FindNextPipe(NULL, &pipeRequest); if (connections[iOther].otherIn == NULL) { // IOLog("start: Failed to open mystery input pipe\n"); goto fail; } else connections[iOther].otherIn->retain(); pipeRequest.direction = kUSBOut; connections[iOther].otherOut = interface->FindNextPipe(NULL, &pipeRequest); if (connections[iOther].otherOut == NULL) { // IOLog("start: Failed to open mystery output pipe\n"); goto fail; } else connections[iOther].otherOut->retain(); iOther++; break; default: // IOLog("start: Ignoring interface (protocol %d)\n", interface->GetInterfaceProtocol()); break; } } if (iConnection != iOther) IOLog("start - interface mismatch?\n"); connectionCount = iConnection; for (i = 0; i < connectionCount; i++) { connections[i].inputArray = OSArray::withCapacity(5); if (connections[i].inputArray == NULL) { // IOLog("start: Failed to allocate packet buffer %d\n", i); goto fail; } if (!QueueRead(i)) { // IOLog("start: Failed to start read %d\n", i); goto fail; } } // IOLog("start: Transform and roll out (%d interfaces)\n", connectionCount); return true; fail: ReleaseAll(); return false; }
bool Xbox360Peripheral::start(IOService *provider) { const IOUSBConfigurationDescriptor *cd; IOUSBFindInterfaceRequest intf; IOUSBFindEndpointRequest pipe; XBOX360_OUT_LED led; IOWorkLoop *workloop = NULL; /* * Xbox One controller init packets. * The Rock Candy Xbox One controller requires more than just 0x05 * Minimum required packets unknown. */ UInt8 xoneInitFirst[] = { 0x02, 0x20, 0x01, 0x1C, 0x7E, 0xED, 0x8B, 0x11, 0x0F, 0xA8, 0x00, 0x00, 0x5E, 0x04, 0xD1, 0x02, 0x01, 0x00, 0x01, 0x00, 0x17, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; UInt8 xoneInitSecond[] = { 0x05, 0x20, 0x00, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x53 }; UInt8 xoneInitThird[] = { 0x05, 0x20, 0x01, 0x01, 0x00 }; UInt8 xoneInitFourth[] = { 0x0A, 0x20, 0x02, 0x03, 0x00, 0x01, 0x14 }; if (!super::start(provider)) return false; // Get device device=OSDynamicCast(IOUSBDevice,provider); if(device==NULL) { IOLog("start - invalid provider\n"); goto fail; } // Check for configurations if(device->GetNumConfigurations()<1) { device=NULL; IOLog("start - device has no configurations!\n"); goto fail; } // Set configuration cd=device->GetFullConfigurationDescriptor(0); if(cd==NULL) { device=NULL; IOLog("start - couldn't get configuration descriptor\n"); goto fail; } // Open if(!device->open(this)) { device=NULL; IOLog("start - unable to open device\n"); goto fail; } if(device->SetConfiguration(this,cd->bConfigurationValue,true)!=kIOReturnSuccess) { IOLog("start - unable to set configuration\n"); goto fail; } // Get release { UInt16 release = device->GetDeviceRelease(); switch (release) { default: IOLog("Unknown device release %.4x\n", release); // fall through case 0x0110: chatpadInit[0] = 0x01; chatpadInit[1] = 0x02; break; case 0x0114: chatpadInit[0] = 0x09; chatpadInit[1] = 0x00; break; } } // Find correct interface controllerType = Xbox360; intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=93; intf.bInterfaceProtocol=1; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { // Find correct interface, Xbox original intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=66; intf.bInterfaceProtocol=0; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { // Find correct interface, Xbox One intf.bInterfaceClass=255; intf.bInterfaceSubClass=71; intf.bInterfaceProtocol=208; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL, &intf); if(interface==NULL) { IOLog("start - unable to find the interface\n"); goto fail; } controllerType = XboxOne; goto interfacefound; } controllerType = XboxOriginal; goto interfacefound; } interfacefound: interface->open(this); // Find pipes pipe.direction=kUSBIn; pipe.interval=0; pipe.type=kUSBInterrupt; pipe.maxPacketSize=0; inPipe=interface->FindNextPipe(NULL,&pipe); if(inPipe==NULL) { IOLog("start - unable to find in pipe\n"); goto fail; } inPipe->retain(); pipe.direction=kUSBOut; outPipe=interface->FindNextPipe(NULL,&pipe); if(outPipe==NULL) { IOLog("start - unable to find out pipe\n"); goto fail; } outPipe->retain(); // Get a buffer inBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,GetMaxPacketSize(inPipe)); if(inBuffer==NULL) { IOLog("start - failed to allocate input buffer\n"); goto fail; } // Find chatpad interface intf.bInterfaceClass = kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass = 93; intf.bInterfaceProtocol = 2; intf.bAlternateSetting = kIOUSBFindInterfaceDontCare; serialIn = device->FindNextInterface(NULL, &intf); if (serialIn == NULL) { IOLog("start - unable to find chatpad interface\n"); goto nochat; } serialIn->open(this); // Find chatpad pipe pipe.direction = kUSBIn; pipe.interval = 0; pipe.type = kUSBInterrupt; pipe.maxPacketSize = 0; serialInPipe = serialIn->FindNextPipe(NULL, &pipe); if (serialInPipe == NULL) { IOLog("start - unable to find chatpad in pipe\n"); goto fail; } serialInPipe->retain(); // Get a buffer for the chatpad serialInBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(serialInPipe)); if (serialInBuffer == NULL) { IOLog("start - failed to allocate input buffer for chatpad\n"); goto fail; } // Create timer for chatpad serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); if (serialTimer == NULL) { IOLog("start - failed to create timer for chatpad\n"); goto fail; } workloop = getWorkLoop(); if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess)) { IOLog("start - failed to connect timer for chatpad\n"); goto fail; } // Configure ChatPad // Send 'configuration' SendInit(0xa30c, 0x4423); SendInit(0x2344, 0x7f03); SendInit(0x5839, 0x6832); // Set 'switch' if ((!SendSwitch(false)) || (!SendSwitch(true)) || (!SendSwitch(false))) { // Commenting goto fail fixes the driver for the Hori Real Arcade Pro EX //goto fail; } // Begin toggle serialHeard = false; serialActive = false; serialToggle = false; serialResetCount = 0; serialTimerState = tsToggle; serialTimer->setTimeoutMS(1000); // Begin reading if (!QueueSerialRead()) goto fail; nochat: if (!QueueRead()) goto fail; if (controllerType == XboxOne) { QueueWrite(&xoneInitFirst, sizeof(xoneInitFirst)); QueueWrite(&xoneInitSecond, sizeof(xoneInitSecond)); QueueWrite(&xoneInitThird, sizeof(xoneInitThird)); QueueWrite(&xoneInitFourth, sizeof(xoneInitFourth)); } else { // Disable LED Xbox360_Prepare(led,outLed); led.pattern=ledOff; QueueWrite(&led,sizeof(led)); } // Done PadConnect(); registerService(); return true; fail: ReleaseAll(); return false; }
// Process the received buffer, creating atoms as we go void CImapIO::ProcessBufferL() { // Process the buffer TChar byte; DBG((LogText(_L8("CImapIO::ProcessBuffer(iParserState=%d, Length=%d)"),iParserState,iReceive.Length()))); for(TInt pos=0;pos<iReceive.Length();pos++) { // Note that we've processed stuff iBytesRead++; // Byte to process byte=iReceive[pos]; switch(iParserState) { case EIOStateAtomWait: switch(byte) { case '(': case '[': case '<': { // Make a new current atom CImapAtom *newAtom=new (ELeave) CImapAtom(); iAtomArray.AppendL(newAtom); // Add it as a sibling to the current atom if (iNextIsChild) iAtom->AddChild(newAtom); else iAtom->AddNext(newAtom); // The next item should be a child iNextIsChild=ETrue; // Push current atom onto atom stack, make new current iAtom=newAtom; PushL(iAtom); // Store the open bracket in the buffer, so we can tell what it is TPtrC8 bufptr(iBuffer->Ptr()+iBuffer->Length(),1); BufferAppendL(byte); iAtom->Set(bufptr); break; } case ')': case ']': // End of this nesting level: pop last atom off stack and // make it the new current one iAtom=PopL(); // Any new atoms will be siblings, not children iNextIsChild=EFalse; break; case '{': // Start of a literal length iLiteralLength=0; iParserState=EIOStateLiteralLength; break; case ' ': // Whitespace. Ignore! This state only happens with whitespace // after a close )] or a endquote " break; case '\r': // Newline after a close )] or endquote " iParserState=EIOStateWaitLF; break; case '\"': // Quotes: we don't keep them, so the atom starts at the next // character. iAtomStart=iBuffer->Length(); iParserState=EIOStateInAtom; iParserQuoted=ETrue; iGotEscape=EFalse; break; default: // Start new atom in buffer iAtomStart=iBuffer->Length(); BufferAppendL(byte); iParserState=EIOStateInAtom; iParserQuoted=EFalse; break; } break; case EIOStateInAtom: if (iParserQuoted) { // Look for another quote if (byte=='\"') { // Just had an escape character? if (iGotEscape) { // Add the character BufferAppendL(byte); iGotEscape=EFalse; } else { // It's the terminator: Add the atom, minus the quotes AddAtomL(); iParserState=EIOStateAtomWait; } } // fix for INC51597 and DEF053082:if a " has been missed out by the server, this will end the atom at a \r else if(!iGotEscape && byte == '\r') { AddAtomL(); iParserState = EIOStateWaitLF; } else { // Escape character? if (!iGotEscape && byte=='\\') { // Got one iGotEscape=ETrue; } else { // Add to buffer BufferAppendL(byte); iGotEscape=EFalse; } } } else { if (byte==' ' || byte=='\r') { AddAtomL(); // Either go back to looking for an atom, or a LF iParserState=(byte=='\r')?EIOStateWaitLF:EIOStateAtomWait; } else if (byte=='(' || byte=='[') { // Add this atom AddAtomL(); // Make a new current atom CImapAtom *newAtom=new (ELeave) CImapAtom(); iAtomArray.AppendL(newAtom); // Add it as a sibling to the current atom if (iNextIsChild) iAtom->AddChild(newAtom); else iAtom->AddNext(newAtom); // The next item should be a child iNextIsChild=ETrue; // Push current atom onto atom stack, make new current iAtom=newAtom; PushL(iAtom); // Store the open bracket in the buffer, so we can tell what it is TPtrC8 bufptr(iBuffer->Ptr()+iBuffer->Length(),1); BufferAppendL(byte); iAtom->Set(bufptr); iParserState=EIOStateAtomWait; } else if (byte==')' || byte==']' || byte == '>') { // Although these bytes usually indicate the end of an atom, // they can also legitimately appear in a text field. // If this is the end of an atom, then it must be a child or // sibling atom in which case there will be an entry on the atom // stack. If there is no entry on the atom stack, then this must // be a text field so just add the byte to the buffer. if (iAtomStack.Count() > 0) { // Add this atom AddAtomL(); // End of this nesting level: pop last atom off stack and // make it the new current one iAtom=PopL(); // Any new atoms will be siblings, not children iNextIsChild=EFalse; iParserState=EIOStateAtomWait; } else { BufferAppendL(byte); } } else { // Add to buffer BufferAppendL(byte); } } break; case EIOStateWaitLF: // After LF, this is end of line, finish! if (byte=='\n') { // Remove everything from the buffer, we've finished iReceive.Delete(0,pos+1); // Reset bytes read count & complete iBytesRead=0; // Complete with KErrFoundEOL DBG((LogText(_L8("CImapIO::ProcessBuffer: Complete in EIOStateWaitLF")))); Complete(KErrFoundEOL); return; } break; case EIOStateLiteralLength: // Digit? if (byte.IsDigit()) { // Add it to the total iLiteralLength=(iLiteralLength*10)+(byte-(TChar)'0'); if (iLiteralLength <0) User::Leave(KErrCorrupt); } else if (byte=='}') { // Need to skip CR, LF iLiteralSkip=2; iParserState=EIOStateLiteralSkip; // Add the atom (with the length we know, but no data) to the // structure now, so that the partial structure can be parsed. iAtomStart=iBuffer->Length(); AddAtomL(iLiteralLength); } break; case EIOStateLiteralSkip: // Skipping... if (--iLiteralSkip==0) { // Is literal 0 bytes long? if (iLiteralLength==0) { // Nothing to follow iParserState=EIOStateAtomWait; } else { // Non-empty literal: go into fetch state iParserState=EIOStateLiteralFetch; } } break; case EIOStateLiteralFetch: // Fetching TInt fetchLength(0); if(KReceiveBuffer<iLiteralLength) { fetchLength = KReceiveBuffer; } else { fetchLength = iLiteralLength; } if(fetchLength > iReceive.Length()-pos) { fetchLength = iReceive.Length()-pos; } // need to extend buffer ? DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(1):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength))); if (iBuffer->Length() + iLiteralLength > iBufferSize) { HBufC8 *oldbuffer=iBuffer; const TText8 *oldbufptr=iBuffer->Ptr(); // Extend by extra amount + round up by KIOBufferGranularity iBufferSize += iLiteralLength; iBufferSize += (KIOBufferGranularity - (iBufferSize % KIOBufferGranularity)); iBuffer=iBuffer->ReAllocL(iBufferSize); // Buffer moved? if (iBuffer!=oldbuffer) { // Fixup buffer tree pointers iRootAtom->FixupL(iBuffer,oldbufptr); } DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(2):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength))); } iBuffer->Des().Append(iReceive.Mid(pos,fetchLength)); // adjust loop to account for data copy pos+=fetchLength-1; iLiteralLength-=fetchLength; DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(3):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength))); if (iLiteralLength==0) { // Atom is already saved (we add literal atoms before they // are stored) iParserState=EIOStateAtomWait; } break; } } iReceive.Zero(); // At start of line, or if we're not doing a partial return, we need to // queue another read here if (iBytesRead==0 || !iReturnPartialLine) { // We've processed this buffer: queue a read. We only complete (above) // when we've had a whole reply, including terminating CRLF. DBG((LogText(_L8("CImapIO::ProcessBufferL(): queuing read, iBytesRead=%d, iReturnPartialLine is %d"), iBytesRead, iReturnPartialLine))); QueueRead(); } else { // Have we got 'enough' of the partial line? if (iBytesRead<iBytesToRead) { // Not enough yet: queue another partial read, for the remainder iBytesToRead-=iBytesRead; QueueRead(); } else { // Partial line parsed: return success (client will requeue) DBG((LogText(_L8("CImapIO::ProcessBuffer: Complete on partial line")))); Complete(KErrNone); } } }
int main(int argc, const char ** argv) { struct IntuiMessage *winmsg; ULONG signals, conreadsig, windowsig; LONG lch; WORD InControl = 0; BOOL Done = FALSE; UBYTE ch, ibuf; UBYTE obuf[200]; BYTE error; FromWb = (argc==0L) ? TRUE : FALSE; if(!(IntuitionBase=OpenLibrary("intuition.library",0))) cleanexit("Can't open intuition\n",RETURN_FAIL); /* Create reply port and io block for writing to console */ if(!(writePort = CreatePort("RKM.console.write",0))) cleanexit("Can't create write port\n",RETURN_FAIL); if(!(writeReq = (struct IOStdReq *) CreateExtIO(writePort,(LONG)sizeof(struct IOStdReq)))) cleanexit("Can't create write request\n",RETURN_FAIL); /* Create reply port and io block for reading from console */ if(!(readPort = CreatePort("RKM.console.read",0))) cleanexit("Can't create read port\n",RETURN_FAIL); if(!(readReq = (struct IOStdReq *) CreateExtIO(readPort,(LONG)sizeof(struct IOStdReq)))) cleanexit("Can't create read request\n",RETURN_FAIL); /* Open a window */ if(!(win = OpenWindow(&nw))) cleanexit("Can't open window\n",RETURN_FAIL); /* Now, attach a console to the window */ if(error = OpenConsole(writeReq,readReq,win)) cleanexit("Can't open console.device\n",RETURN_FAIL); else OpenedConsole = TRUE; /* Demonstrate some console escape sequences */ ConPuts(writeReq,"Here's some normal text\n"); sprintf(obuf,"%s%sHere's text in color 3 & italics\n",COLOR03,ITALICS); ConPuts(writeReq,obuf); ConPuts(writeReq,NORMAL); Delay(50); /* Delay for dramatic demo effect */ ConPuts(writeReq,"We will now delete this asterisk =*="); Delay(50); ConPuts(writeReq,"\b\b"); /* backspace twice */ Delay(50); ConPuts(writeReq,DELCHAR); /* delete the character */ Delay(50); QueueRead(readReq,&ibuf); /* send the first console read request */ ConPuts(writeReq,"\n\nNow reading console\n"); ConPuts(writeReq,"Type some keys. Close window when done.\n\n"); conreadsig = 1 << readPort->mp_SigBit; windowsig = 1 << win->UserPort->mp_SigBit; while(!Done) { /* A character, or an IDCMP msg, or both could wake us up */ signals = Wait(conreadsig|windowsig); /* If a console signal was received, get the character */ if (signals & conreadsig) { if((lch = ConMayGetChar(readPort,&ibuf)) != -1) { ch = lch; /* Show hex and ascii (if printable) for char we got. * If you want to parse received control sequences, such as * function or Help keys,you would buffer control sequences * as you receive them, starting to buffer whenever you * receive 0x9B (or 0x1B[ for user-typed sequences) and * ending when you receive a valid terminating character * for the type of control sequence you are receiving. * For CSI sequences, valid terminating characters * are generally 0x40 through 0x7E. * In our example, InControl has the following values: * 0 = no, 1 = have 0x1B, 2 = have 0x9B OR 0x1B and [, * 3 = now inside control sequence, -1 = normal end esc, * -2 = non-CSI(no [) 0x1B end esc * NOTE - a more complex parser is required to recognize * other types of control sequences. */ /* 0x1B ESC not followed by '[', is not CSI seq */ if (InControl==1) { if(ch=='[') InControl = 2; else InControl = -2; } if ((ch==0x9B)||(ch==0x1B)) /* Control seq starting */ { InControl = (ch==0x1B) ? 1 : 2; ConPuts(writeReq,"=== Control Seq ===\n"); } /* We'll show value of this char we received */ if (((ch >= 0x1F)&&(ch <= 0x7E))||(ch >= 0xA0)) sprintf(obuf,"Received: hex %02x = %c\n",ch,ch); else sprintf(obuf,"Received: hex %02x\n",ch); ConPuts(writeReq,obuf); /* Valid ESC sequence terminator ends an ESC seq */ if ((InControl==3)&&((ch >= 0x40) && (ch <= 0x7E))) { InControl = -1; } if (InControl==2) InControl = 3; /* ESC sequence finished (-1 if OK, -2 if bogus) */ if (InControl < 0) { InControl = 0; ConPuts(writeReq,"=== End Control ===\n"); } } } /* If IDCMP messages received, handle them */ if (signals & windowsig) { /* We have to ReplyMsg these when done with them */ while (winmsg = (struct IntuiMessage *)GetMsg(win->UserPort)) { switch(winmsg->Class) { case IDCMP_CLOSEWINDOW: Done = TRUE; break; default: break; } ReplyMsg((struct Message *)winmsg); } } } /* We always have an outstanding queued read request * so we must abort it if it hasn't completed, * and we must remove it. */ if(!(CheckIO(readReq))) AbortIO(readReq); WaitIO(readReq); /* clear it from our replyport */ cleanup(); exit(RETURN_OK); }